From e0959181286810c855d4a0c239a57281267d120a Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Thu, 23 Oct 2014 23:38:46 -0400 Subject: [PATCH] GtkModelButton: Add a menu-name property Add a menu-name property and use it in a default implementation of ::clicked to switch menus if we are inside a stack. This means GtkModelButton is no longer entirely generic, but rather expects to be used inside a GtkPopoverMenu. It still works in other contexts too, of course. --- gtk/gtkmodelbutton.c | 50 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c index a45169c25b..9569fd1a8e 100644 --- a/gtk/gtkmodelbutton.c +++ b/gtk/gtkmodelbutton.c @@ -31,6 +31,8 @@ #include "gtkrender.h" #include "gtkstylecontext.h" #include "gtktypebuiltins.h" +#include "gtkstack.h" +#include "gtkpopover.h" struct _GtkModelButton { @@ -43,6 +45,7 @@ struct _GtkModelButton gboolean centered; gboolean inverted; gboolean iconic; + gchar *menu_name; GtkMenuTrackerItemRole role; }; @@ -59,6 +62,7 @@ enum PROP_ACTIVE, PROP_ACCEL, PROP_HAS_SUBMENU, + PROP_MENU_NAME, PROP_INVERTED, PROP_CENTERED, PROP_ICONIC @@ -172,6 +176,16 @@ gtk_model_button_set_has_submenu (GtkModelButton *button, gtk_widget_queue_resize (GTK_WIDGET (button)); } +static void +gtk_model_button_set_menu_name (GtkModelButton *button, + const gchar *menu_name) +{ + g_free (button->menu_name); + button->menu_name = g_strdup (menu_name); + gtk_model_button_update_state (button); + gtk_widget_queue_resize (GTK_WIDGET (button)); +} + static void gtk_model_button_set_inverted (GtkModelButton *button, gboolean inverted) @@ -229,6 +243,10 @@ gtk_model_button_get_property (GObject *object, g_value_set_boolean (value, button->active); break; + case PROP_MENU_NAME: + g_value_set_string (value, button->menu_name); + break; + default: g_assert_not_reached (); } @@ -268,6 +286,10 @@ gtk_model_button_set_property (GObject *object, gtk_model_button_set_has_submenu (button, g_value_get_boolean (value)); break; + case PROP_MENU_NAME: + gtk_model_button_set_menu_name (button, g_value_get_string (value)); + break; + case PROP_INVERTED: gtk_model_button_set_inverted (button, g_value_get_boolean (value)); break; @@ -677,11 +699,34 @@ gtk_model_button_draw (GtkWidget *widget, return FALSE; } +static void +gtk_model_button_clicked (GtkButton *button) +{ + GtkModelButton *model_button = GTK_MODEL_BUTTON (button); + if (model_button->menu_name != NULL) + { + GtkWidget *stack; + + stack = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_STACK); + if (stack != NULL) + gtk_stack_set_visible_child_name (GTK_STACK (stack), model_button->menu_name); + } + else if (model_button->role == GTK_MENU_TRACKER_ITEM_ROLE_NORMAL) + { + GtkWidget *popover; + + popover = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_POPOVER); + if (popover != NULL) + gtk_widget_hide (popover); + } +} + static void gtk_model_button_class_init (GtkModelButtonClass *class) { GObjectClass *object_class = G_OBJECT_CLASS (class); GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class); + GtkButtonClass *button_class = GTK_BUTTON_CLASS (class); object_class->get_property = gtk_model_button_get_property; object_class->set_property = gtk_model_button_set_property; @@ -694,6 +739,8 @@ gtk_model_button_class_init (GtkModelButtonClass *class) widget_class->size_allocate = gtk_model_button_size_allocate; widget_class->draw = gtk_model_button_draw; + button_class->clicked = gtk_model_button_clicked; + g_object_class_install_property (object_class, PROP_ACTION_ROLE, g_param_spec_enum ("action-role", "", "", GTK_TYPE_MENU_TRACKER_ITEM_ROLE, @@ -714,6 +761,9 @@ gtk_model_button_class_init (GtkModelButtonClass *class) g_object_class_install_property (object_class, PROP_HAS_SUBMENU, g_param_spec_boolean ("has-submenu", "", "", FALSE, G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS)); + g_object_class_install_property (object_class, PROP_MENU_NAME, + g_param_spec_string ("menu-name", "", "", NULL, + G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); g_object_class_install_property (object_class, PROP_INVERTED, g_param_spec_boolean ("inverted", "", "", FALSE,