obs-studio/UI/scene-tree.cpp

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);
}