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>
diff --git a/vcl/unx/gtk3/gtk3gtkinst.cxx b/vcl/unx/gtk3/gtk3gtkinst.cxx
index d9217d4..83c6bba 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