diff options
author | Caolán McNamara <caolanm@redhat.com> | 2020-01-16 16:38:15 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2020-01-21 09:57:58 +0100 |
commit | fa8c85fa90e9565a357b247a69f930098d11ff84 (patch) | |
tree | d14cb6db4faa840ae23b435bbdcd3ff5987c3f44 /vcl/unx/gtk3/gtk3gtkinst.cxx | |
parent | 9394ad31fb9c325001c97702feda317d61f1cbbb (diff) |
weld gallery panel
Change-Id: I4aebb3f90e9943044d106a507972c39434988f03
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87003
Tested-by: Jenkins
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl/unx/gtk3/gtk3gtkinst.cxx')
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 290 |
1 files changed, 187 insertions, 103 deletions
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx index 024b71c782e6..486b522dfe71 100644 --- a/vcl/unx/gtk3/gtk3gtkinst.cxx +++ b/vcl/unx/gtk3/gtk3gtkinst.cxx @@ -1792,6 +1792,18 @@ namespace namespace { +GdkDragAction VclToGdk(sal_Int8 dragOperation) +{ + GdkDragAction eRet(static_cast<GdkDragAction>(0)); + if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_COPY) + eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_COPY); + if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_MOVE) + eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_MOVE); + if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_LINK) + eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_LINK); + return eRet; +} + class GtkInstanceWidget : public virtual weld::Widget { protected: @@ -1894,6 +1906,25 @@ protected: return AllSettings::GetLayoutRTL(); } + void do_enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) + { + css::uno::Reference<css::datatransfer::XTransferable> xTrans(rHelper.get()); + css::uno::Reference<css::datatransfer::dnd::XDragSourceListener> xListener(rHelper.get()); + + ensure_drag_source(); + + auto aFormats = xTrans->getTransferDataFlavors(); + std::vector<GtkTargetEntry> aGtkTargets(m_xDragSource->FormatsToGtk(aFormats)); + + m_eDragAction = VclToGdk(eDNDConstants); + drag_source_set(aGtkTargets, m_eDragAction); + + for (auto &a : aGtkTargets) + g_free(a.target); + + m_xDragSource->set_datatransfer(xTrans, xListener); + } + void localizeDecimalSeparator() { // tdf#128867 if localize decimal separator is active we will always @@ -1908,9 +1939,13 @@ private: bool m_bDraggedOver; sal_uInt16 m_nLastMouseButton; sal_uInt16 m_nLastMouseClicks; + int m_nPressedButton; + int m_nPressStartX; + int m_nPressStartY; ImplSVEvent* m_pFocusInEvent; ImplSVEvent* m_pFocusOutEvent; GtkCssProvider* m_pBgCssProvider; + GdkDragAction m_eDragAction; gulong m_nFocusInSignalId; gulong m_nMnemonicActivateSignalId; gulong m_nFocusOutSignalId; @@ -1926,8 +1961,14 @@ private: gulong m_nDragDropSignalId; gulong m_nDragDropReceivedSignalId; gulong m_nDragLeaveSignalId; + gulong m_nDragBeginSignalId; + gulong m_nDragEndSignalId; + gulong m_nDragFailedSignalId; + gulong m_nDragDataDeleteignalId; + gulong m_nDragGetSignalId; rtl::Reference<GtkDropTarget> m_xDropTarget; + rtl::Reference<GtkDragSource> m_xDragSource; std::vector<AtkRelation*> m_aExtraAtkRelations; static void signalSizeAllocate(GtkWidget*, GdkRectangle* allocation, gpointer widget) @@ -1964,6 +2005,8 @@ private: bool signal_button(GdkEventButton* pEvent) { + m_nPressedButton = -1; + Point aPos(pEvent->x, pEvent->y); if (SwapForRTL()) aPos.setX(gtk_widget_get_allocated_width(m_pWidget) - 1 - aPos.X()); @@ -2026,6 +2069,14 @@ private: return false; } + /* Save press to possibly begin a drag */ + if (pEvent->type != GDK_BUTTON_RELEASE) + { + m_nPressedButton = pEvent->button; + m_nPressStartX = pEvent->x; + m_nPressStartY = pEvent->y; + } + sal_uInt32 nModCode = GtkSalFrame::GetMouseModCode(pEvent->state); sal_uInt16 nCode = m_nLastMouseButton | (nModCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)); MouseEvent aMEvt(aPos, m_nLastMouseClicks, ImplGetMouseButtonMode(m_nLastMouseButton, nModCode), nCode, nCode); @@ -2051,6 +2102,19 @@ private: bool signal_motion(const GdkEventMotion* pEvent) { + GtkTargetList* pDragData = (m_eDragAction != 0 && m_nPressedButton != -1 && m_xDragSource.is()) ? gtk_drag_source_get_target_list(m_pWidget) : nullptr; + if (pDragData && gtk_drag_check_threshold(m_pWidget, m_nPressStartX, m_nPressStartY, pEvent->x, pEvent->y) && !do_signal_drag_begin()) + { + gtk_drag_begin_with_coordinates(m_pWidget, + pDragData, + m_eDragAction, + m_nPressedButton, + const_cast<GdkEvent*>(reinterpret_cast<const GdkEvent*>(pEvent)), + m_nPressStartX, m_nPressStartY); + m_nPressedButton = -1; + return false; + } + if (!m_aMouseMotionHdl.IsSet()) return false; @@ -2132,6 +2196,80 @@ private: } } + static void signalDragBegin(GtkWidget*, GdkDragContext* context, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + pThis->signal_drag_begin(context); + } + + void ensure_drag_source() + { + if (!m_xDragSource) + { + m_xDragSource.set(new GtkDragSource); + + m_nDragFailedSignalId = g_signal_connect(m_pWidget, "drag-failed", G_CALLBACK(signalDragFailed), this); + m_nDragDataDeleteignalId = g_signal_connect(m_pWidget, "drag-data-delete", G_CALLBACK(signalDragDelete), this); + m_nDragGetSignalId = g_signal_connect(m_pWidget, "drag-data-get", G_CALLBACK(signalDragDataGet), this); + m_nDragBeginSignalId = g_signal_connect(m_pWidget, "drag-begin", G_CALLBACK(signalDragBegin), this); + m_nDragEndSignalId = g_signal_connect(m_pWidget, "drag-end", G_CALLBACK(signalDragEnd), this); + } + } + + virtual bool do_signal_drag_begin() + { + return false; + } + + void signal_drag_begin(GdkDragContext* context) + { + if (do_signal_drag_begin()) + { + gtk_drag_cancel(context); + return; + } + if (!m_xDragSource) + return; + m_xDragSource->setActiveDragSource(); + } + + virtual void do_signal_drag_end() + { + } + + static void signalDragEnd(GtkWidget* /*widget*/, GdkDragContext* context, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + pThis->do_signal_drag_end(); + if (pThis->m_xDragSource.is()) + pThis->m_xDragSource->dragEnd(context); + } + + static gboolean signalDragFailed(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkDragResult /*result*/, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + pThis->m_xDragSource->dragFailed(); + return false; + } + + static void signalDragDelete(GtkWidget* /*widget*/, GdkDragContext* /*context*/, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + pThis->m_xDragSource->dragDelete(); + } + + static void signalDragDataGet(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkSelectionData *data, guint info, + guint /*time*/, gpointer widget) + { + GtkInstanceWidget* pThis = static_cast<GtkInstanceWidget*>(widget); + pThis->m_xDragSource->dragDataGet(data, info); + } + + virtual void drag_source_set(const std::vector<GtkTargetEntry>& rGtkTargets, GdkDragAction eDragAction) + { + gtk_drag_source_set(m_pWidget, GDK_BUTTON1_MASK, rGtkTargets.data(), rGtkTargets.size(), eDragAction); + } + void set_background(const OUString* pColor) { if (!pColor && !m_pBgCssProvider) @@ -2162,9 +2300,13 @@ public: , m_bDraggedOver(false) , m_nLastMouseButton(0) , m_nLastMouseClicks(0) + , m_nPressedButton(-1) + , m_nPressStartX(-1) + , m_nPressStartY(-1) , m_pFocusInEvent(nullptr) , m_pFocusOutEvent(nullptr) , m_pBgCssProvider(nullptr) + , m_eDragAction(GdkDragAction(0)) , m_nFocusInSignalId(0) , m_nMnemonicActivateSignalId(0) , m_nFocusOutSignalId(0) @@ -2180,6 +2322,11 @@ public: , m_nDragDropSignalId(0) , m_nDragDropReceivedSignalId(0) , m_nDragLeaveSignalId(0) + , m_nDragBeginSignalId(0) + , m_nDragEndSignalId(0) + , m_nDragFailedSignalId(0) + , m_nDragDataDeleteignalId(0) + , m_nDragGetSignalId(0) { if (!bTakeOwnership) g_object_ref(m_pWidget); @@ -2733,6 +2880,16 @@ public: g_signal_handler_disconnect(m_pWidget, m_nDragDropReceivedSignalId); if (m_nDragLeaveSignalId) g_signal_handler_disconnect(m_pWidget, m_nDragLeaveSignalId); + if (m_nDragEndSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragEndSignalId); + if (m_nDragBeginSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragBeginSignalId); + if (m_nDragFailedSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragFailedSignalId); + if (m_nDragDataDeleteignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragDataDeleteignalId); + if (m_nDragGetSignalId) + g_signal_handler_disconnect(m_pWidget, m_nDragGetSignalId); if (m_nKeyPressSignalId) g_signal_handler_disconnect(m_pWidget, m_nKeyPressSignalId); if (m_nKeyReleaseSignalId) @@ -8227,18 +8384,6 @@ namespace return -1; } - GdkDragAction VclToGdk(sal_Int8 dragOperation) - { - GdkDragAction eRet(static_cast<GdkDragAction>(0)); - if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_COPY) - eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_COPY); - if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_MOVE) - eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_MOVE); - if (dragOperation & css::datatransfer::dnd::DNDConstants::ACTION_LINK) - eRet = static_cast<GdkDragAction>(eRet | GDK_ACTION_LINK); - return eRet; - } - struct GtkInstanceTreeIter : public weld::TreeIter { GtkInstanceTreeIter(const GtkInstanceTreeIter* pOrig) @@ -8287,7 +8432,6 @@ private: std::vector<int> m_aSavedSortColumns; std::vector<int> m_aViewColToModelCol; std::vector<int> m_aModelColToViewCol; - rtl::Reference<GtkDragSource> m_xDragSource; bool m_bWorkAroundBadDragRegion; bool m_bInDrag; gint m_nTextCol; @@ -8301,11 +8445,6 @@ private: gulong m_nRowDeletedSignalId; gulong m_nRowInsertedSignalId; gulong m_nPopupMenuSignalId; - gulong m_nDragBeginSignalId; - gulong m_nDragEndSignalId; - gulong m_nDragFailedSignalId; - gulong m_nDragDataDeleteignalId; - gulong m_nDragGetSignalId; gulong m_nKeyPressSignalId; gulong m_nQueryTooltipSignalId; ImplSVEvent* m_pChangeEvent; @@ -8691,65 +8830,6 @@ private: return default_sort_func(pModel, a, b, m_xSorter.get()); } - static void signalDragBegin(GtkWidget*, GdkDragContext* context, gpointer widget) - { - GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); - pThis->signal_drag_begin(context); - } - - void ensure_drag_source() - { - if (!m_xDragSource) - { - m_xDragSource.set(new GtkDragSource); - - m_nDragFailedSignalId = g_signal_connect(m_pWidget, "drag-failed", G_CALLBACK(signalDragFailed), this); - m_nDragDataDeleteignalId = g_signal_connect(m_pWidget, "drag-data-delete", G_CALLBACK(signalDragDelete), this); - m_nDragGetSignalId = g_signal_connect(m_pWidget, "drag-data-get", G_CALLBACK(signalDragDataGet), this); - } - } - - void signal_drag_begin(GdkDragContext* context) - { - if (m_aDragBeginHdl.Call(*this)) - { - gtk_drag_cancel(context); - return; - } - g_DragSource = this; - if (!m_xDragSource) - return; - m_xDragSource->setActiveDragSource(); - } - - static void signalDragEnd(GtkWidget* /*widget*/, GdkDragContext* context, gpointer widget) - { - g_DragSource = nullptr; - GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); - if (pThis->m_xDragSource.is()) - pThis->m_xDragSource->dragEnd(context); - } - - static gboolean signalDragFailed(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkDragResult /*result*/, gpointer widget) - { - GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); - pThis->m_xDragSource->dragFailed(); - return false; - } - - static void signalDragDelete(GtkWidget* /*widget*/, GdkDragContext* /*context*/, gpointer widget) - { - GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); - pThis->m_xDragSource->dragDelete(); - } - - static void signalDragDataGet(GtkWidget* /*widget*/, GdkDragContext* /*context*/, GtkSelectionData *data, guint info, - guint /*time*/, gpointer widget) - { - GtkInstanceTreeView* pThis = static_cast<GtkInstanceTreeView*>(widget); - pThis->m_xDragSource->dragDataGet(data, info); - } - bool signal_key_press(GdkEventKey* pEvent) { if (pEvent->keyval != GDK_KEY_Left && pEvent->keyval != GDK_KEY_Right) @@ -8828,11 +8908,6 @@ public: , m_nTestExpandRowSignalId(g_signal_connect(pTreeView, "test-expand-row", G_CALLBACK(signalTestExpandRow), this)) , m_nVAdjustmentChangedSignalId(0) , m_nPopupMenuSignalId(g_signal_connect(pTreeView, "popup-menu", G_CALLBACK(signalPopupMenu), this)) - , m_nDragBeginSignalId(g_signal_connect(pTreeView, "drag-begin", G_CALLBACK(signalDragBegin), this)) - , m_nDragEndSignalId(g_signal_connect(pTreeView, "drag-end", G_CALLBACK(signalDragEnd), this)) - , m_nDragFailedSignalId(0) - , m_nDragDataDeleteignalId(0) - , m_nDragGetSignalId(0) , m_nKeyPressSignalId(g_signal_connect(pTreeView, "key-press-event", G_CALLBACK(signalKeyPress), this)) , m_nQueryTooltipSignalId(0) , m_pChangeEvent(nullptr) @@ -10034,20 +10109,12 @@ public: virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) override { - css::uno::Reference<css::datatransfer::XTransferable> xTrans(rHelper.get()); - css::uno::Reference<css::datatransfer::dnd::XDragSourceListener> xListener(rHelper.get()); - - ensure_drag_source(); - - auto aFormats = xTrans->getTransferDataFlavors(); - std::vector<GtkTargetEntry> aGtkTargets(m_xDragSource->FormatsToGtk(aFormats)); - - gtk_tree_view_enable_model_drag_source(m_pTreeView, GDK_BUTTON1_MASK, aGtkTargets.data(), aGtkTargets.size(), VclToGdk(eDNDConstants)); - - for (auto &a : aGtkTargets) - g_free(a.target); + do_enable_drag_source(rHelper, eDNDConstants); + } - m_xDragSource->set_datatransfer(xTrans, xListener); + virtual void drag_source_set(const std::vector<GtkTargetEntry>& rGtkTargets, GdkDragAction eDragAction) override + { + gtk_tree_view_enable_model_drag_source(m_pTreeView, GDK_BUTTON1_MASK, rGtkTargets.data(), rGtkTargets.size(), eDragAction); } virtual void set_selection_mode(SelectionMode eMode) override @@ -10259,6 +10326,19 @@ public: return g_DragSource; } + virtual bool do_signal_drag_begin() override + { + if (m_aDragBeginHdl.Call(*this)) + return true; + g_DragSource = this; + return false; + } + + virtual void do_signal_drag_end() override + { + g_DragSource = nullptr; + } + // Under gtk 3.24.8 dragging into the TreeView is not highlighting // entire TreeView widget, just the rectangle which has no entries // in it, so as a workaround highlight the parent container @@ -10298,14 +10378,6 @@ public: if (m_nQueryTooltipSignalId) g_signal_handler_disconnect(m_pTreeView, m_nQueryTooltipSignalId); g_signal_handler_disconnect(m_pTreeView, m_nKeyPressSignalId); - g_signal_handler_disconnect(m_pTreeView, m_nDragEndSignalId); - g_signal_handler_disconnect(m_pTreeView, m_nDragBeginSignalId); - if (m_nDragFailedSignalId) - g_signal_handler_disconnect(m_pTreeView, m_nDragFailedSignalId); - if (m_nDragDataDeleteignalId) - g_signal_handler_disconnect(m_pTreeView, m_nDragDataDeleteignalId); - if (m_nDragGetSignalId) - g_signal_handler_disconnect(m_pTreeView, m_nDragGetSignalId); g_signal_handler_disconnect(m_pTreeView, m_nPopupMenuSignalId); GtkTreeModel *pModel = GTK_TREE_MODEL(m_pTreeStore); g_signal_handler_disconnect(pModel, m_nRowDeletedSignalId); @@ -11557,6 +11629,18 @@ public: return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8); } + virtual void enable_drag_source(rtl::Reference<TransferDataContainer>& rHelper, sal_uInt8 eDNDConstants) override + { + do_enable_drag_source(rHelper, eDNDConstants); + } + + virtual bool do_signal_drag_begin() override + { + if (m_aDragBeginHdl.Call(*this)) + return true; + return false; + } + virtual ~GtkInstanceDrawingArea() override { g_object_steal_data(G_OBJECT(m_pDrawingArea), "g-lo-GtkInstanceDrawingArea"); |