Browse Source

UI: Add ability to reorder filters by drag & drop

This adds the ability for filters to be dragged and dropped
to be reordered, similar to scenes and sources.
Clayton Groeneveld 6 years ago
parent
commit
f2f4582141
5 changed files with 72 additions and 0 deletions
  1. 17 0
      UI/focus-list.cpp
  2. 3 0
      UI/focus-list.hpp
  3. 18 0
      UI/forms/OBSBasicFilters.ui
  4. 30 0
      UI/window-basic-filters.cpp
  5. 4 0
      UI/window-basic-filters.hpp

+ 17 - 0
UI/focus-list.cpp

@@ -1,4 +1,5 @@
 #include "focus-list.hpp"
+#include <QDragMoveEvent>
 
 FocusList::FocusList(QWidget *parent) : QListWidget(parent) {}
 
@@ -8,3 +9,19 @@ void FocusList::focusInEvent(QFocusEvent *event)
 
 	emit GotFocus();
 }
+
+void FocusList::dragMoveEvent(QDragMoveEvent *event)
+{
+#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
+	QPoint pos = event->position().toPoint();
+#else
+	QPoint pos = event->pos();
+#endif
+	int itemRow = row(itemAt(pos));
+
+	if ((itemRow == currentRow() + 1) ||
+	    (currentRow() == count() - 1 && itemRow == -1))
+		event->ignore();
+	else
+		QListWidget::dragMoveEvent(event);
+}

+ 3 - 0
UI/focus-list.hpp

@@ -2,6 +2,8 @@
 
 #include <QListWidget>
 
+class QDragMoveEvent;
+
 class FocusList : public QListWidget {
 	Q_OBJECT
 
@@ -10,6 +12,7 @@ public:
 
 protected:
 	void focusInEvent(QFocusEvent *event) override;
+	virtual void dragMoveEvent(QDragMoveEvent *event) override;
 
 signals:
 	void GotFocus();

+ 18 - 0
UI/forms/OBSBasicFilters.ui

@@ -72,6 +72,15 @@
             <property name="spacing">
              <number>1</number>
             </property>
+            <property name="dragEnabled">
+             <bool>true</bool>
+            </property>
+            <property name="dragDropMode">
+             <enum>QAbstractItemView::InternalMove</enum>
+            </property>
+            <property name="defaultDropAction">
+             <enum>Qt::TargetMoveAction</enum>
+            </property>
            </widget>
           </item>
           <item>
@@ -285,6 +294,15 @@
             <property name="spacing">
              <number>1</number>
             </property>
+            <property name="dragEnabled">
+             <bool>true</bool>
+            </property>
+            <property name="dragDropMode">
+             <enum>QAbstractItemView::InternalMove</enum>
+            </property>
+            <property name="defaultDropAction">
+             <enum>Qt::TargetMoveAction</enum>
+            </property>
            </widget>
           </item>
           <item>

+ 30 - 0
UI/window-basic-filters.cpp

@@ -103,6 +103,11 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
 	connect(ui->buttonBox->button(QDialogButtonBox::RestoreDefaults),
 		SIGNAL(clicked()), this, SLOT(ResetFilters()));
 
+	connect(ui->asyncFilters->model(), &QAbstractItemModel::rowsMoved, this,
+		&OBSBasicFilters::FiltersMoved);
+	connect(ui->effectFilters->model(), &QAbstractItemModel::rowsMoved,
+		this, &OBSBasicFilters::FiltersMoved);
+
 	uint32_t caps = obs_source_get_output_flags(source);
 	bool audio = (caps & OBS_SOURCE_AUDIO) != 0;
 	bool audioOnly = (caps & OBS_SOURCE_VIDEO) == 0;
@@ -1276,3 +1281,28 @@ void OBSBasicFilters::delete_filter(OBSSource filter)
 		redo, undo_data, redo_data, false);
 	obs_source_filter_remove(source, filter);
 }
+
+void OBSBasicFilters::FiltersMoved(const QModelIndex &, int srcIdxStart, int,
+				   const QModelIndex &, int)
+{
+	QListWidget *list = isAsync ? ui->asyncFilters : ui->effectFilters;
+	int neighborIdx = 0;
+
+	if (srcIdxStart < list->currentRow())
+		neighborIdx = list->currentRow() - 1;
+	else if (srcIdxStart > list->currentRow())
+		neighborIdx = list->currentRow() + 1;
+	else
+		return;
+
+	if (neighborIdx > list->count() - 1)
+		neighborIdx = list->count() - 1;
+	else if (neighborIdx < 0)
+		neighborIdx = 0;
+
+	OBSSource neighbor = GetFilter(neighborIdx, isAsync);
+	size_t idx = obs_source_filter_get_index(source, neighbor);
+
+	OBSSource filter = GetFilter(list->currentRow(), isAsync);
+	obs_source_filter_set_index(source, filter, idx);
+}

+ 4 - 0
UI/window-basic-filters.hpp

@@ -121,6 +121,10 @@ private slots:
 	void CopyFilter();
 	void PasteFilter();
 
+	void FiltersMoved(const QModelIndex &srcParent, int srcIdxStart,
+			  int srcIdxEnd, const QModelIndex &dstParent,
+			  int dstIdx);
+
 public:
 	OBSBasicFilters(QWidget *parent, OBSSource source_);
 	~OBSBasicFilters();