Skip to content

Commit

Permalink
Add DnD filter reorder
Browse files Browse the repository at this point in the history
  • Loading branch information
bmatherly committed Oct 25, 2014
1 parent 475cd0c commit 87d8150
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 37 deletions.
39 changes: 39 additions & 0 deletions src/models/attachedfiltersmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,29 @@ bool AttachedFiltersModel::removeRows(int row, int count, const QModelIndex &par
}
}

bool AttachedFiltersModel::moveRows(const QModelIndex & sourceParent, int sourceRow, int count, const QModelIndex & destinationParent, int destinationRow)
{
if (!m_producer || !m_producer->is_valid() || sourceParent != destinationParent || count != 1) {
return false;
}

QModelIndex fromIndex = createIndex(sourceRow, 0);
QModelIndex toIndex = createIndex(destinationRow, 0);

if (fromIndex.isValid() && toIndex.isValid()) {
if (beginMoveRows(sourceParent, sourceRow, sourceRow, destinationParent, destinationRow)) {
if (destinationRow > sourceRow) {
// Moving down: Convert to MLT Service indexing
destinationRow--;
}
m_producer->move_filter(indexForRow(sourceRow), indexForRow(destinationRow));
endMoveRows();
return true;
}
}
return false;
}

Mlt::Filter *AttachedFiltersModel::add(const QString& mlt_service, const QString& shotcutName)
{
Mlt::Filter* filter = new Mlt::Filter(MLT.profile(), mlt_service.toUtf8().constData());
Expand Down Expand Up @@ -222,6 +245,22 @@ void AttachedFiltersModel::remove(int row)
delete filter;
}

bool AttachedFiltersModel::move(int fromRow, int toRow)
{
QModelIndex parent = QModelIndex();

if (fromRow < 0 || toRow < 0) {
return false;
}

if (toRow > fromRow) {
// Moving down: put it under the destination index
toRow++;
}

return moveRows(parent, fromRow, 1, parent, toRow);
}

void AttachedFiltersModel::reset(Mlt::Producer* producer)
{
beginResetModel();
Expand Down
2 changes: 2 additions & 0 deletions src/models/attachedfiltersmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,15 @@ class AttachedFiltersModel : public QAbstractListModel
Qt::DropActions supportedDropActions() const;
bool insertRows(int row, int count, const QModelIndex &parent);
bool removeRows(int row, int count, const QModelIndex &parent);
bool moveRows(const QModelIndex & sourceParent, int sourceRow, int count, const QModelIndex & destinationParent, int destinationRow);

signals:
void changed(bool modified = true);

public slots:
Mlt::Filter* add(const QString& mlt_service, const QString& shotcutName = QString());
void remove(int row);
bool move(int fromRow, int toRow);
void reset(Mlt::Producer *producer = 0);

private:
Expand Down
175 changes: 138 additions & 37 deletions src/qml/views/filter/AttachedFilters.qml
Original file line number Diff line number Diff line change
Expand Up @@ -31,48 +31,59 @@ Rectangle {
Component {
id: filterDelegate

Row {
height: filterDelegateText.implicitHeight
ListView.onAdd: { attachedFiltersView.currentIndex = attachedFiltersView.count - 1 }
Rectangle {
id: background

Item {
width: 4
height: parent.height
}
// Trick to make the model item available to the dragItem
property var rowData: model

CheckBox {
id: filterDelegateCheck
width: 15
anchors.verticalCenter: parent.verticalCenter
checkedState: model.checkState
onClicked: {
model.checkState = !model.checkState
}
}

Item {
width: 4
ListView.onAdd: { attachedFiltersView.currentIndex = attachedFiltersView.count - 1 }

height: filterDelegateText.implicitHeight
width: parent ? parent.width : undefined
color: "transparent"
border.width: 2
border.color: attachedFiltersView.dragTarget == index ? activePalette.highlight : "transparent"

Row {
height: parent.height
}

Text {
id: filterDelegateText
text: model.display
color: attachedFiltersView.currentIndex == index ? activePalette.highlightedText : activePalette.windowText
width: attachedFiltersView.width - 23

MouseArea {
id: mouseArea
anchors.fill: parent
z: 1
hoverEnabled: true

Item {
width: 4
height: parent.height
}

CheckBox {
id: filterDelegateCheck
width: 15
anchors.verticalCenter: parent.verticalCenter
checkedState: model.checkState
onClicked: {
attachedFiltersView.currentIndex = index
attachedFiltersView.forceActiveFocus()
}
onDoubleClicked: {
model.checkState = !model.checkState
filterDelegateCheck.checkedState = model.checkState
}
}

Item {
width: 4
height: parent.height
}

Text {
id: filterDelegateText
text: model.display
color: attachedFiltersView.currentIndex == index ? activePalette.highlightedText : activePalette.windowText
width: attachedFiltersView.width - 23

MouseArea {
id: mouseArea
anchors.fill: parent
onClicked: {
attachedFiltersView.currentIndex = index
}
onDoubleClicked: {
model.checkState = !model.checkState
filterDelegateCheck.checkedState = model.checkState
}
}
}
}
Expand All @@ -84,6 +95,8 @@ Rectangle {
ListView {
id: attachedFiltersView

property var dragTarget: -1

function handleReset () {
currentIndex = -1
}
Expand All @@ -103,6 +116,94 @@ Rectangle {
Component.onCompleted: {
model.modelReset.connect(handleReset)
}

MouseArea {
property int oldIndex: -1
property var grabPos: Qt.point(0,0)

function beginDrag() {
var grabbedItem = attachedFiltersView.itemAt(mouseX, mouseY)
oldIndex = attachedFiltersView.indexAt(mouseX, mouseY)
grabPos = Qt.point(mouseX - grabbedItem.x, mouseY - grabbedItem.y)
dragItem.index = oldIndex
dragItem.model = grabbedItem.rowData
dragItem.sourceComponent = filterDelegate
dragItem.x = mouseX - grabPos.x
dragItem.y = mouseY - grabPos.y
attachedFiltersView.currentIndex = oldIndex
cursorShape = Qt.DragMoveCursor
autoScrollTimer.running = true
}

function endDrag() {
oldIndex = -1
attachedFiltersView.dragTarget = -1
dragItem.sourceComponent = null
cursorShape = Qt.ArrowCursor
autoScrollTimer.running = false
}

propagateComposedEvents: true
anchors.fill: parent
z: 1

onPressAndHold: {
if (oldIndex == -1) {
beginDrag()
}
}
onReleased: {
if(oldIndex != -1
&& attachedFiltersView.dragTarget != -1
&& oldIndex != attachedFiltersView.dragTarget) {
attachedfiltersmodel.move(oldIndex, attachedFiltersView.dragTarget)
}
endDrag()
mouse.accepted = true;
}
onPositionChanged: {
if (oldIndex == -1) {
beginDrag()
}
dragItem.x = mouseX - grabPos.x
dragItem.y = mouseY - grabPos.y
attachedFiltersView.dragTarget = attachedFiltersView.indexAt(mouseX, mouseY + attachedFiltersView.contentY)
}
onCanceled: endDrag()

Timer {
id: autoScrollTimer
interval: 500;
running: false;
repeat: true
onTriggered: {
// Make sure previous and next indices are always visible
var nextIndex = attachedFiltersView.dragTarget + 1
var prevIndex = attachedFiltersView.dragTarget - 1
if( nextIndex < attachedFiltersView.count ) {
attachedFiltersView.positionViewAtIndex(nextIndex, ListView.Contain)
}
if( prevIndex >= 0 ) {
attachedFiltersView.positionViewAtIndex(prevIndex, ListView.Contain)
}
attachedFiltersView.dragTarget = attachedFiltersView.indexAt(parent.mouseX, parent.mouseY + attachedFiltersView.contentY)
}
}
}

Loader {
id: dragItem

// Emulate the delegate properties added by ListView
property var model : Object()
property int index

onLoaded: {
item.color = activePalette.highlight
item.opacity = 0.5
item.width = attachedFiltersView.width
}
}
}
}
}

0 comments on commit 87d8150

Please sign in to comment.