diff --git a/obs/forms/OBSBasic.ui b/obs/forms/OBSBasic.ui index 42fd544ab..5498bd062 100644 --- a/obs/forms/OBSBasic.ui +++ b/obs/forms/OBSBasic.ui @@ -369,6 +369,21 @@ QFrame::NoFrame + + true + + + true + + + QAbstractItemView::InternalMove + + + QAbstractItemView::ExtendedSelection + + + Qt::IgnoreAction + diff --git a/obs/source-list-widget.cpp b/obs/source-list-widget.cpp index 9cef2289e..d537fbc3b 100644 --- a/obs/source-list-widget.cpp +++ b/obs/source-list-widget.cpp @@ -1,8 +1,46 @@ #include + +#include + +#include "qt-wrappers.hpp" #include "source-list-widget.hpp" +Q_DECLARE_METATYPE(OBSSceneItem); + void SourceListWidget::mouseDoubleClickEvent(QMouseEvent *event) { if (event->button() == Qt::LeftButton) QListWidget::mouseDoubleClickEvent(event); } + +void SourceListWidget::dropEvent(QDropEvent *event) +{ + QListWidget::dropEvent(event); + if (!event->isAccepted() || !count()) + return; + + auto GetSceneItem = [&](int i) + { + return item(i)->data(Qt::UserRole).value(); + }; + + std::vector newOrder; + newOrder.reserve(count()); + for (int i = count() - 1; i >= 0; i--) + newOrder.push_back(GetSceneItem(i)); + + auto UpdateOrderAtomically = [&](obs_scene_t *scene) + { + ignoreReorder = true; + obs_scene_reorder_items(scene, newOrder.data(), + newOrder.size()); + ignoreReorder = false; + }; + using UpdateOrderAtomically_t = decltype(UpdateOrderAtomically); + + auto scene = obs_sceneitem_get_scene(GetSceneItem(0)); + obs_scene_atomic_update(scene, [](void *data, obs_scene_t *scene) + { + (*static_cast(data))(scene); + }, static_cast(&UpdateOrderAtomically)); +} diff --git a/obs/source-list-widget.hpp b/obs/source-list-widget.hpp index b571bf5ad..d2215b0c2 100644 --- a/obs/source-list-widget.hpp +++ b/obs/source-list-widget.hpp @@ -6,12 +6,17 @@ class QMouseEvent; class SourceListWidget : public QListWidget { Q_OBJECT + + bool ignoreReorder = false; public: inline SourceListWidget(QWidget *parent = nullptr) : QListWidget(parent) { } + bool IgnoreReorder() const { return ignoreReorder; } + protected: virtual void mouseDoubleClickEvent(QMouseEvent *event) override; + virtual void dropEvent(QDropEvent *event) override; };