From 541e7af37452d35a8ccc21199b398528176d97d5 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 11:36:15 +0000 Subject: [PATCH 1/3] Fix wx drag events to actually be keyed off of the Qt dragging state instead of its "drop" events. Add "dropped" state to track whether a drop actually occurred or whether the drag ended unsuccessfully. --- src/qt/treectrl.cpp | 45 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index c3879d0920..30549ed217 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -103,7 +103,8 @@ class wxQTreeWidget : public wxQtEventSignalHandler public: wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : wxQtEventSignalHandler(parent, handler), - m_editorFactory(handler) + m_editorFactory(handler), + m_dropped(false) { connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); @@ -142,7 +143,7 @@ protected: QTreeWidget::drawBranches(painter, rect, index); const int imageIndex = ChooseBestImage(item); - if (imageIndex != -1 ) + if ( imageIndex != -1 ) { wxImageList *imageList = GetHandler()->GetImageList(); wxBitmap bitmap = imageList->GetBitmap(imageIndex); @@ -228,13 +229,14 @@ private: EmitEvent(expandedEvent); } - virtual void dragEnterEvent(QDragEnterEvent* event) wxOVERRIDE + void tryStartDrag(const QMouseEvent *event) { - wxEventType command = (event->mouseButtons() & Qt::RightButton) + m_dropped = false; + + wxEventType command = (event->buttons() & Qt::RightButton) ? wxEVT_TREE_BEGIN_RDRAG : wxEVT_TREE_BEGIN_DRAG; - QTreeWidgetItem *hitItem = itemAt(event->pos()); wxTreeEvent tree_event( @@ -250,13 +252,13 @@ private: EmitEvent(tree_event); - if ( tree_event.IsAllowed() ) + if ( !tree_event.IsAllowed() ) { - event->accept(); + setState(DragSelectingState); } } - virtual void dropEvent(QDropEvent* event) wxOVERRIDE + void endDrag(const QMouseEvent* event) { const wxPoint pos = wxQtConvertPoint(event->pos()); QTreeWidgetItem *hitItem = itemAt(event->pos()); @@ -272,6 +274,32 @@ private: EmitEvent(tree_event); } + virtual void dropEvent(QDropEvent* event) wxOVERRIDE + { + m_dropped = true; + + // We don't want Qt to actually do the drop. + event->ignore(); + } + + virtual void mouseMoveEvent(QMouseEvent *event) wxOVERRIDE + { + const bool wasDragging = state() == DraggingState; + wxQtEventSignalHandler::mouseMoveEvent(event); + const bool nowDragging = state() == DraggingState; + if ( !wasDragging && nowDragging ) + { + tryStartDrag(event); + } + else if ( wasDragging && !nowDragging ) + { + // Only emit "end drag" if we have dropped + // (e.g. not hit escape to cancel). + if ( m_dropped ) + endDrag(event); + } + } + int ChooseBestImage(QTreeWidgetItem *item) const { int imageIndex = -1; @@ -306,6 +334,7 @@ private: typedef std::map ImageStateMap; ImageStateMap m_imageStates; + bool m_dropped; }; wxTreeCtrl::wxTreeCtrl() : From 6dfc243b275e48011655b4747d0db1984fb8bef2 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 11:39:26 +0000 Subject: [PATCH 2/3] Fix up a comment. --- src/qt/treectrl.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 30549ed217..2aeabd62c0 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -167,8 +167,10 @@ private: return; } - //QT doesnt update the selection until this singal has been processed. //Defering this event ensures - //that wxTreeCtrl::GetSelection returns the new selection in the wx event handler. + // QT doesn't update the selection until this signal has been + // processed. Deferring this event ensures that + // wxTreeCtrl::GetSelection returns the new selection in the + // wx event handler. wxTreeEvent changedEvent(wxEVT_TREE_SEL_CHANGED, treeCtrl, wxQtConvertTreeItem(current)); wxPostEvent(treeCtrl, changedEvent); } From 9566143b580d9d0e5f076c6131518e198913a272 Mon Sep 17 00:00:00 2001 From: Jay Nabonne Date: Thu, 7 Feb 2019 12:05:34 +0000 Subject: [PATCH 3/3] Get rid of logic error - no need for state variables and all that, by just doing things at the right time. This fixes the problem of the mouse position being wrong during endDrag. --- src/qt/treectrl.cpp | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) diff --git a/src/qt/treectrl.cpp b/src/qt/treectrl.cpp index 037164aeda..899e63f8c9 100644 --- a/src/qt/treectrl.cpp +++ b/src/qt/treectrl.cpp @@ -103,8 +103,7 @@ class wxQTreeWidget : public wxQtEventSignalHandler public: wxQTreeWidget(wxWindow *parent, wxTreeCtrl *handler) : wxQtEventSignalHandler(parent, handler), - m_editorFactory(handler), - m_dropped(false) + m_editorFactory(handler) { connect(this, &QTreeWidget::currentItemChanged, this, &wxQTreeWidget::OnCurrentItemChanged); connect(this, &QTreeWidget::itemActivated, this, &wxQTreeWidget::OnItemActivated); @@ -233,8 +232,6 @@ private: void tryStartDrag(const QMouseEvent *event) { - m_dropped = false; - wxEventType command = (event->buttons() & Qt::RightButton) ? wxEVT_TREE_BEGIN_RDRAG : wxEVT_TREE_BEGIN_DRAG; @@ -260,10 +257,11 @@ private: } } - void endDrag(const QMouseEvent* event) + void endDrag(QPoint position) { - const wxPoint pos = wxQtConvertPoint(event->pos()); - QTreeWidgetItem *hitItem = itemAt(event->pos()); + const wxPoint pos = wxQtConvertPoint(position); + QTreeWidgetItem *hitItem = itemAt(position); + OutputDebugStringA(hitItem->text(0).toUtf8().data()); wxTreeEvent tree_event( wxEVT_TREE_END_DRAG, @@ -271,14 +269,14 @@ private: wxQtConvertTreeItem(hitItem) ); - tree_event.SetPoint(wxQtConvertPoint(event->pos())); + tree_event.SetPoint(wxQtConvertPoint(position)); EmitEvent(tree_event); } virtual void dropEvent(QDropEvent* event) wxOVERRIDE { - m_dropped = true; + endDrag(event->pos()); // We don't want Qt to actually do the drop. event->ignore(); @@ -288,18 +286,12 @@ private: { const bool wasDragging = state() == DraggingState; wxQtEventSignalHandler::mouseMoveEvent(event); + const bool nowDragging = state() == DraggingState; if ( !wasDragging && nowDragging ) { tryStartDrag(event); } - else if ( wasDragging && !nowDragging ) - { - // Only emit "end drag" if we have dropped - // (e.g. not hit escape to cancel). - if ( m_dropped ) - endDrag(event); - } } int ChooseBestImage(QTreeWidgetItem *item) const @@ -336,7 +328,6 @@ private: typedef std::map ImageStateMap; ImageStateMap m_imageStates; - bool m_dropped; }; wxTreeCtrl::wxTreeCtrl() :