forked from AuroraMiddleware/gtk
menubutton: Add a create_popup_func
Some use cases require a menu button to create the popup on demand.
This commit is contained in:
parent
cb6d96d65f
commit
c0214cfcc1
@ -1866,6 +1866,7 @@ gtk_menu_button_set_relief
|
|||||||
gtk_menu_button_get_relief
|
gtk_menu_button_get_relief
|
||||||
gtk_menu_button_popup
|
gtk_menu_button_popup
|
||||||
gtk_menu_button_popdown
|
gtk_menu_button_popdown
|
||||||
|
gtk_menu_button_set_create_popup_func
|
||||||
<SUBSECTION Standard>
|
<SUBSECTION Standard>
|
||||||
GTK_TYPE_MENU_BUTTON
|
GTK_TYPE_MENU_BUTTON
|
||||||
GTK_MENU_BUTTON
|
GTK_MENU_BUTTON
|
||||||
|
@ -150,8 +150,9 @@ struct _GtkMenuButtonPrivate
|
|||||||
GtkWidget *popover; /* Only one at a time can be set */
|
GtkWidget *popover; /* Only one at a time can be set */
|
||||||
GMenuModel *model;
|
GMenuModel *model;
|
||||||
|
|
||||||
GtkMenuButtonShowMenuCallback func;
|
GtkMenuButtonCreatePopupFunc create_popup_func;
|
||||||
gpointer user_data;
|
gpointer create_popup_user_data;
|
||||||
|
GDestroyNotify create_popup_destroy_notify;
|
||||||
|
|
||||||
GtkWidget *align_widget;
|
GtkWidget *align_widget;
|
||||||
GtkWidget *arrow_widget;
|
GtkWidget *arrow_widget;
|
||||||
@ -289,9 +290,6 @@ popup_menu (GtkMenuButton *menu_button,
|
|||||||
GdkGravity widget_anchor = GDK_GRAVITY_SOUTH_WEST;
|
GdkGravity widget_anchor = GDK_GRAVITY_SOUTH_WEST;
|
||||||
GdkGravity menu_anchor = GDK_GRAVITY_NORTH_WEST;
|
GdkGravity menu_anchor = GDK_GRAVITY_NORTH_WEST;
|
||||||
|
|
||||||
if (priv->func)
|
|
||||||
priv->func (priv->user_data);
|
|
||||||
|
|
||||||
if (!priv->menu)
|
if (!priv->menu)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@ -446,7 +444,13 @@ static void
|
|||||||
gtk_menu_button_toggled (GtkMenuButton *menu_button)
|
gtk_menu_button_toggled (GtkMenuButton *menu_button)
|
||||||
{
|
{
|
||||||
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (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)
|
if (priv->menu)
|
||||||
{
|
{
|
||||||
@ -755,26 +759,34 @@ update_sensitivity (GtkMenuButton *menu_button)
|
|||||||
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
|
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
|
||||||
|
|
||||||
gtk_widget_set_sensitive (GTK_WIDGET (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”
|
* gtk_menu_button_set_popup:
|
||||||
* signal.
|
* @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
|
void
|
||||||
_gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button,
|
gtk_menu_button_set_popup (GtkMenuButton *menu_button,
|
||||||
GtkWidget *menu,
|
GtkWidget *menu)
|
||||||
GtkMenuButtonShowMenuCallback func,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
GtkMenuButtonPrivate *priv = gtk_menu_button_get_instance_private (menu_button);
|
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_BUTTON (menu_button));
|
||||||
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
|
g_return_if_fail (GTK_IS_MENU (menu) || menu == NULL);
|
||||||
|
|
||||||
priv->func = func;
|
g_object_freeze_notify (G_OBJECT (menu_button));
|
||||||
priv->user_data = user_data;
|
|
||||||
|
g_clear_object (&priv->model);
|
||||||
|
|
||||||
if (priv->menu == GTK_WIDGET (menu))
|
if (priv->menu == GTK_WIDGET (menu))
|
||||||
return;
|
return;
|
||||||
@ -803,37 +815,8 @@ _gtk_menu_button_set_popup_with_func (GtkMenuButton *menu_button
|
|||||||
G_CALLBACK (menu_deactivate_cb), 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_POPUP]);
|
||||||
g_object_notify_by_pspec (G_OBJECT (menu_button), menu_button_props[PROP_MENU_MODEL]);
|
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)
|
if (menu && priv->popover)
|
||||||
gtk_menu_button_set_popover (menu_button, NULL);
|
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_object (&priv->model);
|
||||||
g_clear_pointer (&priv->button, gtk_widget_unparent);
|
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);
|
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_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);
|
||||||
|
}
|
||||||
|
@ -37,6 +37,18 @@ G_BEGIN_DECLS
|
|||||||
|
|
||||||
typedef struct _GtkMenuButton GtkMenuButton;
|
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
|
GDK_AVAILABLE_IN_ALL
|
||||||
GType gtk_menu_button_get_type (void) G_GNUC_CONST;
|
GType gtk_menu_button_get_type (void) G_GNUC_CONST;
|
||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
@ -102,6 +114,11 @@ void gtk_menu_button_popup (GtkMenuButton *menu_button);
|
|||||||
GDK_AVAILABLE_IN_ALL
|
GDK_AVAILABLE_IN_ALL
|
||||||
void gtk_menu_button_popdown (GtkMenuButton *menu_button);
|
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
|
G_END_DECLS
|
||||||
|
|
||||||
|
@ -25,13 +25,6 @@
|
|||||||
|
|
||||||
G_BEGIN_DECLS
|
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,
|
void gtk_menu_button_add_child (GtkMenuButton *button,
|
||||||
GtkWidget *child);
|
GtkWidget *child);
|
||||||
|
|
||||||
|
@ -363,7 +363,8 @@ gtk_menu_tool_button_new (GtkWidget *icon_widget,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_show_menu_emit (gpointer user_data)
|
_show_menu_emit (GtkMenuButton *menu_button,
|
||||||
|
gpointer user_data)
|
||||||
{
|
{
|
||||||
GtkMenuToolButton *button = (GtkMenuToolButton *) user_data;
|
GtkMenuToolButton *button = (GtkMenuToolButton *) user_data;
|
||||||
g_signal_emit (button, signals[SHOW_MENU], 0);
|
g_signal_emit (button, signals[SHOW_MENU], 0);
|
||||||
@ -388,10 +389,9 @@ gtk_menu_tool_button_set_menu (GtkMenuToolButton *button,
|
|||||||
|
|
||||||
priv = button->priv;
|
priv = button->priv;
|
||||||
|
|
||||||
_gtk_menu_button_set_popup_with_func (GTK_MENU_BUTTON (priv->arrow_button),
|
gtk_menu_button_set_popup (GTK_MENU_BUTTON (priv->arrow_button), menu);
|
||||||
menu,
|
gtk_menu_button_set_create_popup_func (GTK_MENU_BUTTON (priv->arrow_button),
|
||||||
_show_menu_emit,
|
_show_menu_emit, NULL, NULL);
|
||||||
button);
|
|
||||||
|
|
||||||
g_object_notify (G_OBJECT (button), "menu");
|
g_object_notify (G_OBJECT (button), "menu");
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user