[Libreoffice-commits] core.git: vcl/unx

Caolán McNamara (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 12 14:53:40 UTC 2019


 vcl/unx/gtk3/gtk3gtkinst.cxx |  106 +++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 103 insertions(+), 3 deletions(-)

New commits:
commit f9e693cbe13a8ff55de112d709d1409c67887f2a
Author:     Caolán McNamara <caolanm at redhat.com>
AuthorDate: Tue Nov 12 11:23:57 2019 +0000
Commit:     Caolán McNamara <caolanm at redhat.com>
CommitDate: Tue Nov 12 15:52:30 2019 +0100

    Resolves: tdf#128716 make gtk assistant steps clickable
    
    Change-Id: I28d7cfd2192f22410eee08c6f4e5ab056789fcfd
    Reviewed-on: https://gerrit.libreoffice.org/82503
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index d9217d412e5e..83c6bbaf9f63 100644
--- a/vcl/unx/gtk3/gtk3gtkinst.cxx
+++ b/vcl/unx/gtk3/gtk3gtkinst.cxx
@@ -1694,6 +1694,9 @@ namespace
 
     GtkWidget* ensureEventWidget(GtkWidget* pWidget)
     {
+        if (!pWidget)
+            return nullptr;
+
         GtkWidget* pMouseEventBox;
         // not every widget has a GdkWindow and can get any event, so if we
         // want an event it doesn't have, insert a GtkEventBox so we can get
@@ -1719,6 +1722,21 @@ namespace
                         nullptr);
             }
 
+            gboolean bExpand(false), bFill(false);
+            GtkPackType ePackType(GTK_PACK_START);
+            guint nPadding(0);
+            gint nPosition(0);
+            if (GTK_IS_BOX(pParent))
+            {
+                gtk_container_child_get(GTK_CONTAINER(pParent), pWidget,
+                        "expand", &bExpand,
+                        "fill", &bFill,
+                        "pack-type", &ePackType,
+                        "padding", &nPadding,
+                        "position", &nPosition,
+                        nullptr);
+            }
+
             gtk_container_remove(GTK_CONTAINER(pParent), pWidget);
 
             pMouseEventBox = gtk_event_box_new();
@@ -1738,6 +1756,17 @@ namespace
                         nullptr);
             }
 
+            if (GTK_IS_BOX(pParent))
+            {
+                gtk_container_child_set(GTK_CONTAINER(pParent), pMouseEventBox,
+                        "expand", bExpand,
+                        "fill", bFill,
+                        "pack-type", ePackType,
+                        "padding", nPadding,
+                        "position", nPosition,
+                        nullptr);
+            }
+
             gtk_container_add(GTK_CONTAINER(pMouseEventBox), pWidget);
             g_object_unref(pWidget);
 
@@ -4442,13 +4471,16 @@ class GtkInstanceAssistant : public GtkInstanceDialog, public virtual weld::Assi
 private:
     GtkAssistant* m_pAssistant;
     GtkWidget* m_pSidebar;
+    GtkWidget* m_pSidebarEventBox;
     GtkButtonBox* m_pButtonBox;
     GtkButton* m_pHelp;
     GtkButton* m_pBack;
     GtkButton* m_pNext;
     GtkButton* m_pFinish;
     GtkButton* m_pCancel;
+    gulong m_nButtonPressSignalId;
     std::vector<std::unique_ptr<GtkInstanceContainer>> m_aPages;
+    std::map<OString, bool> m_aNotClickable;
 
     int find_page(const OString& rIdent) const
     {
@@ -4495,6 +4527,66 @@ private:
         help();
     }
 
+    static gboolean signalButton(GtkWidget*, GdkEventButton* pEvent, gpointer widget)
+    {
+        GtkInstanceAssistant* pThis = static_cast<GtkInstanceAssistant*>(widget);
+        SolarMutexGuard aGuard;
+        return pThis->signal_button(pEvent);
+    }
+
+    bool signal_button(GdkEventButton* pEvent)
+    {
+        int nNewCurrentPage = -1;
+
+        GtkAllocation allocation;
+
+        int nPageIndex = 0;
+        GList* pChildren = gtk_container_get_children(GTK_CONTAINER(m_pSidebar));
+        for (GList* pChild = g_list_first(pChildren); pChild; pChild = g_list_next(pChild))
+        {
+            GtkWidget* pWidget = static_cast<GtkWidget*>(pChild->data);
+            if (!gtk_widget_get_visible(pWidget))
+                continue;
+
+            gtk_widget_get_allocation(pWidget, &allocation);
+
+            gint dest_x1, dest_y1;
+            gtk_widget_translate_coordinates(pWidget,
+                                             m_pSidebarEventBox,
+                                             0,
+                                             0,
+                                             &dest_x1,
+                                             &dest_y1);
+
+            gint dest_x2, dest_y2;
+            gtk_widget_translate_coordinates(pWidget,
+                                             m_pSidebarEventBox,
+                                             allocation.width,
+                                             allocation.height,
+                                             &dest_x2,
+                                             &dest_y2);
+
+
+            if (pEvent->x >= dest_x1 && pEvent->x <= dest_x2 && pEvent->y >= dest_y1 && pEvent->y <= dest_y2)
+            {
+                nNewCurrentPage = nPageIndex;
+                break;
+            }
+
+            ++nPageIndex;
+        }
+        g_list_free(pChildren);
+
+        if (nNewCurrentPage != -1 && nNewCurrentPage != get_current_page())
+        {
+            OString sIdent = get_page_ident(nNewCurrentPage);
+            if (!m_aNotClickable[sIdent] && !signal_jump_page(sIdent))
+                set_current_page(nNewCurrentPage);
+        }
+
+        return false;
+    }
+
 public:
     GtkInstanceAssistant(GtkAssistant* pAssistant, GtkInstanceBuilder* pBuilder, bool bTakeOwnership)
         : GtkInstanceDialog(GTK_WINDOW(pAssistant), pBuilder, bTakeOwnership)
@@ -4550,6 +4642,9 @@ public:
         gtk_widget_show_all(GTK_WIDGET(m_pButtonBox));
 
         find_sidebar(GTK_WIDGET(m_pAssistant), &m_pSidebar);
+
+        m_pSidebarEventBox = ::ensureEventWidget(m_pSidebar);
+        m_nButtonPressSignalId = m_pSidebarEventBox ? g_signal_connect(m_pSidebarEventBox, "button-press-event", G_CALLBACK(signalButton), this) : 0;
     }
 
     virtual int get_current_page() const override
@@ -4616,10 +4711,9 @@ public:
         return OUString(pStr, pStr ? strlen(pStr) : 0, RTL_TEXTENCODING_UTF8);
     }
 
-    virtual void set_page_sensitive(const OString& /*rIdent*/, bool /*bSensitive*/) override
+    virtual void set_page_sensitive(const OString& rIdent, bool bSensitive) override
     {
-        // seeing as the GtkAssistant doesn't have clickable roadmap entries
-        // sensitive vs insensitive is moot
+        m_aNotClickable[rIdent] = !bSensitive;
     }
 
     virtual void set_page_index(const OString& rIdent, int nNewIndex) override
@@ -4682,6 +4776,12 @@ public:
             pButton = m_pHelp;
         return pButton;
     }
+
+    virtual ~GtkInstanceAssistant() override
+    {
+        if (m_nButtonPressSignalId)
+            g_signal_handler_disconnect(m_pSidebarEventBox, m_nButtonPressSignalId);
+    }
 };
 
 class GtkInstanceFrame : public GtkInstanceContainer, public virtual weld::Frame


More information about the Libreoffice-commits mailing list