obs-studio/UI/scene-tree.cpp
VodBox c0e2e7f12e UI: Add Grid Mode to Scenes Widget
Adds an option to the right click menu in the scenes widget to switch
modes. When in regular list mode, it'll let you select grid mode, and in
grid mode, it'll let you select list mode. Grid mode changes the scenes
widget to have a grid of buttons for scenes rather than a list, much
like XSplit.
2019-12-02 08:42:10 +13:00

189 lines
4.2 KiB
C++

#include "obs.hpp"
#include "scene-tree.hpp"
#include "obs-app.hpp"
#include <QSizePolicy>
#include <QScrollBar>
#include <QDropEvent>
#include <QPushButton>
SceneTree::SceneTree(QWidget *parent_) : QListWidget(parent_)
{
installEventFilter(this);
setDragDropMode(InternalMove);
setMovement(QListView::Snap);
}
void SceneTree::SetGridMode(bool grid)
{
config_set_bool(App()->GlobalConfig(), "BasicWindow", "gridMode", grid);
parent()->setProperty("gridMode", grid);
gridMode = grid;
if (gridMode) {
setResizeMode(QListView::Adjust);
setViewMode(QListView::IconMode);
setUniformItemSizes(true);
setStyleSheet("*{padding: 0; margin: 0;}");
} else {
setViewMode(QListView::ListMode);
setResizeMode(QListView::Fixed);
setStyleSheet("");
}
resizeEvent(new QResizeEvent(size(), size()));
}
bool SceneTree::GetGridMode()
{
return gridMode;
}
void SceneTree::SetGridItemWidth(int width)
{
maxWidth = width;
}
void SceneTree::SetGridItemHeight(int height)
{
itemHeight = height;
}
int SceneTree::GetGridItemWidth()
{
return maxWidth;
}
int SceneTree::GetGridItemHeight()
{
return itemHeight;
}
bool SceneTree::eventFilter(QObject *obj, QEvent *event)
{
return QObject::eventFilter(obj, event);
}
void SceneTree::resizeEvent(QResizeEvent *event)
{
QListWidget::resizeEvent(event);
if (gridMode) {
int scrollWid = verticalScrollBar()->sizeHint().width();
int h = visualItemRect(item(count() - 1)).bottom();
if (h < height()) {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollWid = 0;
} else {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
}
int wid = contentsRect().width() - scrollWid - 1;
int items = (int)ceil((float)wid / maxWidth);
int itemWidth = wid / items;
setGridSize(QSize(itemWidth, itemHeight));
for (int i = 0; i < count(); i++) {
item(i)->setSizeHint(QSize(itemWidth, itemHeight));
}
} else {
setGridSize(QSize());
setSpacing(0);
for (int i = 0; i < count(); i++) {
item(i)->setData(Qt::SizeHintRole, QVariant());
}
}
}
void SceneTree::startDrag(Qt::DropActions supportedActions)
{
QListWidget::startDrag(supportedActions);
}
void SceneTree::dropEvent(QDropEvent *event)
{
QListWidget::dropEvent(event);
if (event->source() == this && gridMode) {
int scrollWid = verticalScrollBar()->sizeHint().width();
int h = visualItemRect(item(count() - 1)).bottom();
if (h < height()) {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollWid = 0;
} else {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
}
float wid = contentsRect().width() - scrollWid - 1;
QPoint point = event->pos();
int x = (float)point.x() / wid * ceil(wid / maxWidth);
int y = point.y() / itemHeight;
int r = x + y * ceil(wid / maxWidth);
QListWidgetItem *item = takeItem(selectedIndexes()[0].row());
insertItem(r, item);
setCurrentItem(item);
resize(size());
}
}
void SceneTree::dragMoveEvent(QDragMoveEvent *event)
{
if (gridMode) {
int scrollWid = verticalScrollBar()->sizeHint().width();
int h = visualItemRect(item(count() - 1)).bottom();
if (h < height()) {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollWid = 0;
} else {
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
}
float wid = contentsRect().width() - scrollWid - 1;
QPoint point = event->pos();
int x = (float)point.x() / wid * ceil(wid / maxWidth);
int y = point.y() / itemHeight;
int r = x + y * ceil(wid / maxWidth);
int orig = selectedIndexes()[0].row();
for (int i = 0; i < count(); i++) {
auto *wItem = item(i);
if (wItem->isSelected())
continue;
QModelIndex index = indexFromItem(wItem);
int off = (i >= r ? 1 : 0) -
(i > orig && i > r ? 1 : 0) -
(i > orig && i == r ? 2 : 0);
int xPos = (i + off) % (int)ceil(wid / maxWidth);
int yPos = (i + off) / (int)ceil(wid / maxWidth);
QSize g = gridSize();
QPoint position(xPos * g.width(), yPos * g.height());
setPositionForIndex(position, index);
}
} else {
QListWidget::dragMoveEvent(event);
}
}
void SceneTree::rowsInserted(const QModelIndex &parent, int start, int end)
{
QListWidget::rowsInserted(parent, start, end);
QResizeEvent *event = new QResizeEvent(size(), size());
SceneTree::resizeEvent(event);
}