[gtk/wip/baedert/for-master: 1/2] menubutton: Add a create_popup_func
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/baedert/for-master: 1/2] menubutton: Add a create_popup_func
- Date: Thu, 22 Aug 2019 08:10:53 +0000 (UTC)
commit 96778c6dc7ee3cf4f2164f783d12d36afafbeb2c
Author: Timm Bäder <mail baedert org>
Date: Thu Aug 22 09:06:43 2019 +0200
menubutton: Add a create_popup_func
Some use cases require a menu button to create the popup on demand.
docs/reference/gtk/gtk4-sections.txt | 1 +
gtk/gtkmenubutton.c | 118 ++++++++++++++++++++++-------------
gtk/gtkmenubutton.h | 17 +++++
gtk/gtkmenubuttonprivate.h | 7 ---
gtk/gtkmenutoolbutton.c | 10 +--
5 files changed, 96 insertions(+), 57 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index b72906d7ab..477c0b4b9c 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -1866,6 +1866,7 @@ gtk_menu_button_set_relief
gtk_menu_button_get_relief
gtk_menu_button_popup
gtk_menu_button_popdown
+gtk_menu_button_set_create_popup_func
<SUBSECTION Standard>
GTK_TYPE_MENU_BUTTON
GTK_MENU_BUTTON
diff --git a/gtk/gtkmenubutton.c b/gtk/gtkmenubutton.c
index ba5e66fe9b..33a16903ef 100644
--- a/gtk/gtkmenubutton.c
+++ b/gtk/gtkmenubutton.c
@@ -150,8 +150,9 @@ struct _GtkMenuButtonPrivate
GtkWidget *popover; /* Only one at a time can be set */
GMenuModel *model;
- GtkMenuButtonShowMenuCallback func;
- gpointer user_data;
+ GtkMenuButtonCreatePopupFunc create_popup_func;
+ gpointer create_popup_user_data;
+ GDestroyNotify create_popup_destroy_notify;
GtkWidget *align_widget;
GtkWidget *arrow_widget;
@@ -289,9 +290,6 @@ popup_menu (GtkMenuButton *menu_button,
GdkGravity widget_anchor = GDK_GRAVITY_SOUTH_WEST;
GdkGravity menu_anchor = GDK_GRAVITY_NORTH_WEST;
- if (priv->func)
- priv->func (priv->user_data);
-
if (!priv->menu)
return;
@@ -446,7 +444,13 @@ static void
gtk_menu_button_toggled (GtkMenuButton *menu_button)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
- gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button));
+ const gboolean active = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->button));
+
+ /* Might set a new menu/popover */
+ if (active && priv->create_popup_func)
+ {
+ priv->create_popup_func (menu_button, priv->create_popup_user_data);
+ }
if (priv->menu)
{
@@ -755,26 +759,34 @@ update_sensitivity (GtkMenuButton *menu_button)
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
gtk_widget_set_sensitive (GTK_WIDGET (menu_button),
- priv->menu != NULL || priv->popover != NULL);
+ priv->menu != NULL ||
+ priv->popover != NULL ||
+ priv->create_popup_func != NULL);
}
-/* This function is used in GtkMenuToolButton, the call back will
- * be called when GtkMenuToolButton would have emitted the “show-menu”
- * signal.
+/**
+ * gtk_menu_button_set_popup:
+ * @menu_button: a #GtkMenuButton
+ * @menu: (nullable): a #GtkMenu, or %NULL to unset and disable the button
+ *
+ * Sets the #GtkMenu that will be popped up when the @menu_button is clicked, or
+ * %NULL to dissociate any existing menu and disable the button.
+ *
+ * If #GtkMenuButton:menu-model or #GtkMenuButton:popover are set, those objects
+ * are dissociated from the @menu_button, and those properties are set to %NULL.
*/
void
-_gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button,
- GtkWidget *menu,
- GtkMenuButtonShowMenuCallback func,
- gpointer user_data)
+gtk_menu_button_set_popup (GtkMenuButton *menu_button,
+ GtkWidget *menu)
{
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
- priv->func = func;
- priv->user_data = user_data;
+ g_object_freeze_notify (G_OBJECT (menu_button));
+
+ g_clear_object (&priv->model);
if (priv->menu == GTK_WIDGET (menu))
return;
@@ -803,37 +815,8 @@ _gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button
G_CALLBACK (menu_deactivate_cb), menu_button);
}
- update_sensitivity (menu_button);
-
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_POPUP]);
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_MENU_MODEL]);
-}
-
-/**
- * gtk_menu_button_set_popup:
- * @menu_button: a #GtkMenuButton
- * @menu: (nullable): a #GtkMenu, or %NULL to unset and disable the button
- *
- * Sets the #GtkMenu that will be popped up when the @menu_button is clicked, or
- * %NULL to dissociate any existing menu and disable the button.
- *
- * If #GtkMenuButton:menu-model or #GtkMenuButton:popover are set, those objects
- * are dissociated from the @menu_button, and those properties are set to %NULL.
- */
-void
-gtk_menu_button_set_popup (GtkMenuButton *menu_button,
- GtkWidget *menu)
-{
- GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
-
- g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
- g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
-
- g_object_freeze_notify (G_OBJECT (menu_button));
-
- g_clear_object (&priv->model);
-
- _gtk_menu_button_set_popup_with_func (menu_button, menu, NULL, NULL);
if (menu && priv->popover)
gtk_menu_button_set_popover (menu_button, NULL);
@@ -1129,6 +1112,9 @@ gtk_menu_button_dispose (GObject *object)
g_clear_object (&priv->model);
g_clear_pointer (&priv->button, gtk_widget_unparent);
+ if (priv->create_popup_destroy_notify)
+ priv->create_popup_destroy_notify (priv->create_popup_user_data);
+
G_OBJECT_CLASS (gtk_menu_button_parent_class)->dispose (object);
}
@@ -1447,3 +1433,45 @@ gtk_menu_button_add_child (GtkMenuButton *menu_button,
gtk_container_add (GTK_CONTAINER (priv->button), new_child);
}
+
+/**
+ * gtk_menu_button_set_create_popup_func:
+ * @menu_button: a #GtkMenuButton
+ * @func: (nullable): function to call when a popuop is about to
+ * be shown, but none has been provided via other means, or %NULL
+ * to reset to default behavior.
+ * @user_data: (nullable): user data to pass to @callback
+ * @destroy_notify: (nullable): destroy notify for @user_data
+ *
+ * Sets @func to be called when a popup is about to be shown.
+ * @func should use one of
+ *
+ * - gtk_menu_button_set_popup()
+ * - gtk_menu_button_set_popover()
+ * - gtk_menu_button_set_menu_model()
+ *
+ * to set a popoup for @menu_button.
+ * If @func is non-%NULL, @menu_button will always be sensitive.
+ *
+ * Using this function will NOT reset the menu widget attached to @menu_button.
+ * Instead, this can be done manually in @func.
+ */
+void
+gtk_menu_button_set_create_popup_func (GtkMenuButton *menu_button,
+ GtkMenuButtonCreatePopupFunc func,
+ gpointer user_data,
+ GDestroyNotify destroy_notify)
+{
+ GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
+
+ g_return_if_fail (GTK_IS_MENU_BUTTON (menu_button));
+
+ if (priv->create_popup_destroy_notify)
+ priv->create_popup_destroy_notify (priv->create_popup_user_data);
+
+ priv->create_popup_func = func;
+ priv->create_popup_user_data = user_data;
+ priv->create_popup_destroy_notify = destroy_notify;
+
+ update_sensitivity (menu_button);
+}
diff --git a/gtk/gtkmenubutton.h b/gtk/gtkmenubutton.h
index ad97d2b4fe..4ec73d39ff 100644
--- a/gtk/gtkmenubutton.h
+++ b/gtk/gtkmenubutton.h
@@ -37,6 +37,18 @@ G_BEGIN_DECLS
typedef struct _GtkMenuButton GtkMenuButton;
+/**
+ * GtkMenuButtonCreatePopupFunc:
+ * @menu_button: the #GtkMenuButton
+ *
+ * User-provided callback function to create a popup for @menu_button on demand.
+ * This function is called when the popoup of @menu_button is shown, but none has
+ * been provided via gtk_menu_buton_set_popup(), gtk_menu_button_set_popover()
+ * or gtk_menu_button_set_menu_model().
+ */
+typedef void (*GtkMenuButtonCreatePopupFunc) (GtkMenuButton *menu_button,
+ gpointer user_data);
+
GDK_AVAILABLE_IN_ALL
GType gtk_menu_button_get_type (void) G_GNUC_CONST;
GDK_AVAILABLE_IN_ALL
@@ -102,6 +114,11 @@ void gtk_menu_button_popup (GtkMenuButton *menu_button);
GDK_AVAILABLE_IN_ALL
void gtk_menu_button_popdown (GtkMenuButton *menu_button);
+GDK_AVAILABLE_IN_ALL
+void gtk_menu_button_set_create_popup_func (GtkMenuButton *menu_button,
+ GtkMenuButtonCreatePopupFunc func,
+ gpointer user_data,
+ GDestroyNotify destroy_notify);
G_END_DECLS
diff --git a/gtk/gtkmenubuttonprivate.h b/gtk/gtkmenubuttonprivate.h
index 85114c3318..aaddeea39b 100644
--- a/gtk/gtkmenubuttonprivate.h
+++ b/gtk/gtkmenubuttonprivate.h
@@ -25,13 +25,6 @@
G_BEGIN_DECLS
-typedef void (* GtkMenuButtonShowMenuCallback) (gpointer user_data);
-
-void _gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button,
- GtkWidget *menu,
- GtkMenuButtonShowMenuCallback func,
- gpointer user_data);
-
void gtk_menu_button_add_child (GtkMenuButton *button,
GtkWidget *child);
diff --git a/gtk/gtkmenutoolbutton.c b/gtk/gtkmenutoolbutton.c
index ec8448d86a..cfcb1127cf 100644
--- a/gtk/gtkmenutoolbutton.c
+++ b/gtk/gtkmenutoolbutton.c
@@ -363,7 +363,8 @@ gtk_menu_tool_button_new (GtkWidget *icon_widget,
}
static void
-_show_menu_emit (gpointer user_data)
+_show_menu_emit (GtkMenuButton *menu_button,
+ gpointer user_data)
{
GtkMenuToolButton *button = (GtkMenuToolButton *) user_data;
g_signal_emit (button, signals[SHOW_MENU], 0);
@@ -388,10 +389,9 @@ gtk_menu_tool_button_set_menu (GtkMenuToolButton *button,
priv = button->priv;
- _gtk_menu_button_set_popup_with_func (GTK_MENU_BUTTON (priv->arrow_button),
- menu,
- _show_menu_emit,
- button);
+ gtk_menu_button_set_popup (GTK_MENU_BUTTON (priv->arrow_button), menu);
+ gtk_menu_button_set_create_popup_func (GTK_MENU_BUTTON (priv->arrow_button),
+ _show_menu_emit, NULL, NULL);
g_object_notify (G_OBJECT (button), "menu");
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]