فهرست منبع

UI: Add drag&drop reordering for the sources list

Palana 10 سال پیش
والد
کامیت
b53d6e9e58
3فایلهای تغییر یافته به همراه58 افزوده شده و 0 حذف شده
  1. 15 0
      obs/forms/OBSBasic.ui
  2. 38 0
      obs/source-list-widget.cpp
  3. 5 0
      obs/source-list-widget.hpp

+ 15 - 0
obs/forms/OBSBasic.ui

@@ -369,6 +369,21 @@
               <property name="frameShape">
                <enum>QFrame::NoFrame</enum>
               </property>
+               <property name="showDropIndicator" stdset="0">
+                <bool>true</bool>
+               </property>
+               <property name="dragEnabled">
+                <bool>true</bool>
+               </property>
+               <property name="dragDropMode">
+                <enum>QAbstractItemView::InternalMove</enum>
+               </property>
+               <property name="selectionMode">
+                <enum>QAbstractItemView::ExtendedSelection</enum>
+               </property>
+               <property name="defaultDropAction">
+                <enum>Qt::IgnoreAction</enum>
+               </property>
               <addaction name="actionRemoveSource"/>
              </widget>
             </item>

+ 38 - 0
obs/source-list-widget.cpp

@@ -1,8 +1,46 @@
 #include <QMouseEvent>
+
+#include <vector>
+
+#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<OBSSceneItem>();
+	};
+
+	std::vector<obs_sceneitem_t*> 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<UpdateOrderAtomically_t*>(data))(scene);
+	}, static_cast<void*>(&UpdateOrderAtomically));
+}

+ 5 - 0
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;
 };