diff options
author | Caolán McNamara <caolanm@redhat.com> | 2019-11-12 11:23:57 +0000 |
---|---|---|
committer | Caolán McNamara <caolanm@redhat.com> | 2019-11-12 15:52:30 +0100 |
commit | f9e693cbe13a8ff55de112d709d1409c67887f2a (patch) | |
tree | 93475301b430ca05432bb01a44e67015573927f1 /vcl | |
parent | f8641f0106ee45731449966f798957a8dc09cfb6 (diff) |
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@redhat.com>
Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/unx/gtk3/gtk3gtkinst.cxx | 106 |
1 files changed, 103 insertions, 3 deletions
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 |