summaryrefslogtreecommitdiff
path: root/vcl/unx
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-11-12 11:23:57 +0000
committerCaolán McNamara <caolanm@redhat.com>2019-11-12 15:52:30 +0100
commitf9e693cbe13a8ff55de112d709d1409c67887f2a (patch)
tree93475301b430ca05432bb01a44e67015573927f1 /vcl/unx
parentf8641f0106ee45731449966f798957a8dc09cfb6 (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/unx')
-rw-r--r--vcl/unx/gtk3/gtk3gtkinst.cxx106
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