[gtk/nested-popover-menu: 1/2] Add nesting popover menus
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/nested-popover-menu: 1/2] Add nesting popover menus
- Date: Sun, 1 Sep 2019 18:34:10 +0000 (UTC)
commit 818acefd5bbe1803c385eedf8309db3d5485d9bf
Author: Matthias Clasen <mclasen redhat com>
Date: Tue Aug 27 09:28:29 2019 +0100
Add nesting popover menus
Add a variant of popover menus that are nesting
like traditional menus. This is a better fit for
replacing traditional main menus.
gtk/gtkmenusectionbox.c | 83 +++++++++++++++++----------
gtk/gtkmenusectionboxprivate.h | 5 +-
gtk/gtkmodelbutton.c | 127 ++++++++++++++++++++++++++++++++++++-----
gtk/gtkpopovermenu.c | 47 ++++++++++++++-
gtk/gtkpopovermenu.h | 9 +++
gtk/gtkpopovermenuprivate.h | 11 +++-
tests/popover2.ui | 38 +++++-------
tests/testpopover.c | 10 ++++
8 files changed, 257 insertions(+), 73 deletions(-)
---
diff --git a/gtk/gtkmenusectionbox.c b/gtk/gtkmenusectionbox.c
index 0bb33cd68b..7ab6aa772d 100644
--- a/gtk/gtkmenusectionbox.c
+++ b/gtk/gtkmenusectionbox.c
@@ -38,18 +38,19 @@ typedef GtkBoxClass GtkMenuSectionBoxClass;
struct _GtkMenuSectionBox
{
- GtkBox parent_instance;
-
- GtkMenuSectionBox *toplevel;
- GtkMenuTracker *tracker;
- GtkBox *item_box;
- GtkWidget *separator;
- guint separator_sync_idle;
- gboolean iconic;
- gboolean inline_buttons;
- gboolean circular;
- gint depth;
- GtkSizeGroup *indicators;
+ GtkBox parent_instance;
+
+ GtkMenuSectionBox *toplevel;
+ GtkMenuTracker *tracker;
+ GtkBox *item_box;
+ GtkWidget *separator;
+ guint separator_sync_idle;
+ gboolean iconic;
+ gboolean inline_buttons;
+ gboolean circular;
+ gint depth;
+ GtkPopoverMenuFlags flags;
+ GtkSizeGroup *indicators;
};
typedef struct
@@ -295,22 +296,40 @@ gtk_menu_section_box_insert_func (GtkMenuTrackerItem *item,
}
else if (gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU))
{
- GtkWidget *stack = NULL;
- GtkWidget *parent = NULL;
- gchar *name;
-
- widget = g_object_new (GTK_TYPE_MODEL_BUTTON,
- "menu-name", gtk_menu_tracker_item_get_label (item),
- "indicator-size-group", box->indicators,
- NULL);
- g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
- g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
-
- get_ancestors (GTK_WIDGET (box->toplevel), GTK_TYPE_STACK, &stack, &parent);
- g_object_get (gtk_stack_get_page (GTK_STACK (stack), parent), "name", &name, NULL);
- gtk_menu_section_box_new_submenu (item, box->toplevel, widget, name);
- g_free (name);
+ if (box->flags & GTK_POPOVER_MENU_NESTED)
+ {
+ GMenuModel *model;
+ GtkWidget *submenu;
+
+ model = _gtk_menu_tracker_item_get_link (item, G_MENU_LINK_SUBMENU);
+
+ submenu = gtk_popover_menu_new_from_model_full (NULL, model, box->flags);
+ widget = g_object_new (GTK_TYPE_MODEL_BUTTON,
+ "popover", submenu,
+ NULL);
+ g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
+ }
+ else
+ {
+ GtkWidget *stack = NULL;
+ GtkWidget *parent = NULL;
+ gchar *name;
+
+ widget = g_object_new (GTK_TYPE_MODEL_BUTTON,
+ "menu-name", gtk_menu_tracker_item_get_label (item),
+ "indicator-size-group", box->indicators,
+ NULL);
+ g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
+
+ get_ancestors (GTK_WIDGET (box->toplevel), GTK_TYPE_STACK, &stack, &parent);
+ g_object_get (gtk_stack_get_page (GTK_STACK (stack), parent), "name", &name, NULL);
+ gtk_menu_section_box_new_submenu (item, box->toplevel, widget, name);
+ g_free (name);
+ }
}
else
{
@@ -453,13 +472,15 @@ update_popover_position_cb (GObject *source,
}
void
-gtk_menu_section_box_new_toplevel (GtkPopoverMenu *popover,
- GMenuModel *model)
+gtk_menu_section_box_new_toplevel (GtkPopoverMenu *popover,
+ GMenuModel *model,
+ GtkPopoverMenuFlags flags)
{
GtkMenuSectionBox *box;
box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, NULL);
box->indicators = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ box->flags = flags;
gtk_popover_menu_add_submenu (popover, GTK_WIDGET (box), "main");
@@ -482,6 +503,7 @@ gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, NULL);
box->indicators = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL);
+ box->flags = toplevel->flags;
button = g_object_new (GTK_TYPE_MODEL_BUTTON,
"menu-name", name,
@@ -521,6 +543,7 @@ gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
box->indicators = g_object_ref (parent->indicators);
box->toplevel = parent->toplevel;
box->depth = parent->depth + 1;
+ box->flags = parent->flags;
label = gtk_menu_tracker_item_get_label (item);
hint = gtk_menu_tracker_item_get_display_hint (item);
diff --git a/gtk/gtkmenusectionboxprivate.h b/gtk/gtkmenusectionboxprivate.h
index 01508fe43a..05d6bd294e 100644
--- a/gtk/gtkmenusectionboxprivate.h
+++ b/gtk/gtkmenusectionboxprivate.h
@@ -41,8 +41,9 @@ G_BEGIN_DECLS
typedef struct _GtkMenuSectionBox GtkMenuSectionBox;
GType gtk_menu_section_box_get_type (void) G_GNUC_CONST;
-void gtk_menu_section_box_new_toplevel (GtkPopoverMenu *popover,
- GMenuModel *model);
+void gtk_menu_section_box_new_toplevel (GtkPopoverMenu *popover,
+ GMenuModel *model,
+ GtkPopoverMenuFlags flags);
G_END_DECLS
diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c
index 80552ec33b..c798b1d42d 100644
--- a/gtk/gtkmodelbutton.c
+++ b/gtk/gtkmodelbutton.c
@@ -43,6 +43,7 @@
#include "gtkactionable.h"
#include "gtkeventcontrollermotion.h"
#include "gtkeventcontrollerkey.h"
+#include "gtknative.h"
/**
* SECTION:gtkmodelbutton
@@ -162,6 +163,7 @@ struct _GtkModelButton
GtkWidget *start_indicator;
GtkWidget *end_box;
GtkWidget *end_indicator;
+ GtkWidget *popover;
gboolean active;
gboolean centered;
gboolean iconic;
@@ -184,6 +186,7 @@ enum
PROP_USE_MARKUP,
PROP_ACTIVE,
PROP_MENU_NAME,
+ PROP_POPOVER,
PROP_ICONIC,
PROP_ACCEL,
PROP_INDICATOR_SIZE_GROUP,
@@ -275,7 +278,8 @@ gtk_model_button_update_state (GtkModelButton *button)
case GTK_BUTTON_ROLE_NORMAL:
start_type = GTK_CSS_IMAGE_BUILTIN_NONE;
- if (button->menu_name != NULL)
+ if (button->menu_name != NULL ||
+ button->popover != NULL)
end_type = GTK_CSS_IMAGE_BUILTIN_ARROW_RIGHT;
else
end_type = GTK_CSS_IMAGE_BUILTIN_NONE;
@@ -344,7 +348,7 @@ update_node_name (GtkModelButton *button)
case GTK_BUTTON_ROLE_NORMAL:
a11y_role = ATK_ROLE_PUSH_BUTTON;
start_name = I_("none");
- if (button->menu_name)
+ if (button->menu_name || button->popover)
end_name = I_("arrow");
else
end_name = I_("none");
@@ -519,6 +523,28 @@ gtk_model_button_set_iconic (GtkModelButton *button,
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_ICONIC]);
}
+static void
+gtk_model_button_set_popover (GtkModelButton *button,
+ GtkWidget *popover)
+{
+ if (button->popover)
+ gtk_popover_set_relative_to (GTK_POPOVER (button->popover), NULL);
+
+ button->popover = popover;
+
+ if (button->popover)
+ {
+ gtk_popover_set_relative_to (GTK_POPOVER (button->popover), GTK_WIDGET (button));
+ gtk_popover_set_position (GTK_POPOVER (button->popover), GTK_POS_RIGHT);
+ }
+
+ update_node_name (button);
+ gtk_model_button_update_state (button);
+
+ gtk_widget_queue_resize (GTK_WIDGET (button));
+ g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_POPOVER]);
+}
+
static void
update_accel (GtkModelButton *button,
const char *accel)
@@ -591,6 +617,10 @@ gtk_model_button_get_property (GObject *object,
g_value_set_string (value, button->menu_name);
break;
+ case PROP_POPOVER:
+ g_value_set_object (value, button->popover);
+ break;
+
case PROP_ICONIC:
g_value_set_boolean (value, button->iconic);
break;
@@ -643,6 +673,10 @@ gtk_model_button_set_property (GObject *object,
gtk_model_button_set_menu_name (button, g_value_get_string (value));
break;
+ case PROP_POPOVER:
+ gtk_model_button_set_popover (button, (GtkWidget *)g_value_get_object (value));
+ break;
+
case PROP_ICONIC:
gtk_model_button_set_iconic (button, g_value_get_boolean (value));
break;
@@ -783,7 +817,9 @@ gtk_model_button_size_allocate (GtkWidget *widget,
int height,
int baseline)
{
- if (GTK_MODEL_BUTTON (widget)->iconic)
+ GtkModelButton *button = GTK_MODEL_BUTTON (widget);
+
+ if (button->iconic)
{
GTK_WIDGET_CLASS (gtk_model_button_parent_class)->size_allocate (widget,
width,
@@ -792,14 +828,12 @@ gtk_model_button_size_allocate (GtkWidget *widget,
}
else
{
- GtkModelButton *button;
GtkAllocation child_allocation;
GtkWidget *child;
int start_width, start_height;
int end_width, end_height;
int min;
- button = GTK_MODEL_BUTTON (widget);
child = gtk_bin_get_child (GTK_BIN (widget));
gtk_widget_measure (button->start_box,
@@ -860,6 +894,9 @@ gtk_model_button_size_allocate (GtkWidget *widget,
gtk_widget_size_allocate (child, &child_allocation, baseline);
}
}
+
+ if (button->popover)
+ gtk_native_check_resize (GTK_NATIVE (button->popover));
}
static void
@@ -888,8 +925,14 @@ close_menu (GtkModelButton *button)
GtkWidget *popover;
popover = gtk_widget_get_ancestor (GTK_WIDGET (button), GTK_TYPE_POPOVER);
- if (popover != NULL)
- gtk_popover_popdown (GTK_POPOVER (popover));
+ while (popover != NULL)
+ {
+ gtk_popover_popdown (GTK_POPOVER (popover));
+ if (GTK_IS_POPOVER_MENU (popover))
+ popover = gtk_popover_menu_get_parent_menu (GTK_POPOVER_MENU (popover));
+ else
+ popover = NULL;
+ }
}
static void
@@ -901,6 +944,10 @@ gtk_model_button_clicked (GtkButton *button)
{
switch_menu (model_button);
}
+ else if (model_button->popover != NULL)
+ {
+ gtk_popover_popup (GTK_POPOVER (model_button->popover));
+ }
else if (model_button->role == GTK_BUTTON_ROLE_NORMAL)
{
close_menu (model_button);
@@ -915,6 +962,7 @@ gtk_model_button_finalize (GObject *object)
gtk_widget_unparent (button->start_box);
gtk_widget_unparent (button->end_box);
g_free (button->accel);
+ g_clear_pointer (&button->popover, gtk_widget_unparent);
G_OBJECT_CLASS (gtk_model_button_parent_class)->finalize (object);
}
@@ -979,6 +1027,13 @@ gtk_model_button_focus (GtkWidget *widget,
switch_menu (button);
return TRUE;
}
+ else if (direction == GTK_DIR_RIGHT &&
+ button->role == GTK_BUTTON_ROLE_NORMAL &&
+ button->popover != NULL)
+ {
+ gtk_popover_popup (GTK_POPOVER (button->popover));
+ return TRUE;
+ }
}
else
{
@@ -1080,8 +1135,7 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
/**
* GtkModelButton:menu-name:
*
- * The name of a submenu to open when the button is activated.
- * If this is set, the button should not have an action associated with it.
+ * The name of a submenu to open when the button is activated. * If this is set, the button should not
have an action associated with it.
*/
properties[PROP_MENU_NAME] =
g_param_spec_string ("menu-name",
@@ -1090,6 +1144,13 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
NULL,
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+ properties[PROP_POPOVER] =
+ g_param_spec_object ("popover",
+ P_("Popover"),
+ P_("Popover to open"),
+ GTK_TYPE_POPOVER,
+ G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
/**
* GtkModelButton:iconic:
*
@@ -1129,6 +1190,38 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
gtk_widget_class_set_css_name (GTK_WIDGET_CLASS (class), I_("modelbutton"));
}
+static void
+close_submenus (GtkPopoverMenu *menu)
+{
+ GtkWidget *submenu;
+
+ submenu = gtk_popover_menu_get_open_submenu (menu);
+ if (submenu)
+ {
+ close_submenus (GTK_POPOVER_MENU (submenu));
+ gtk_popover_popdown (GTK_POPOVER (submenu));
+ gtk_popover_menu_set_open_submenu (menu, NULL);
+ }
+}
+
+static void
+open_submenu (GtkPopoverMenu *menu)
+{
+ GtkWidget *active_item;
+
+ active_item = gtk_popover_menu_get_active_item (menu);
+ if (GTK_IS_MODEL_BUTTON (active_item) &&
+ GTK_MODEL_BUTTON (active_item)->popover)
+ {
+ GtkWidget *submenu;
+
+ submenu = GTK_MODEL_BUTTON (active_item)->popover;
+ gtk_popover_popup (GTK_POPOVER (submenu));
+ gtk_popover_menu_set_open_submenu (menu, submenu);
+ gtk_popover_menu_set_parent_menu (GTK_POPOVER_MENU (submenu), GTK_WIDGET (menu));
+ }
+}
+
static void
enter_cb (GtkEventController *controller,
double x,
@@ -1141,6 +1234,7 @@ enter_cb (GtkEventController *controller,
GtkWidget *popover;
gboolean is;
gboolean contains;
+ GtkWidget *active_item;
target = gtk_event_controller_get_widget (controller);
popover = gtk_widget_get_ancestor (target, GTK_TYPE_POPOVER_MENU);
@@ -1150,8 +1244,15 @@ enter_cb (GtkEventController *controller,
"contains-pointer-focus", &contains,
NULL);
- if (popover && (is || contains))
- gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), target);
+ active_item = gtk_popover_menu_get_active_item (GTK_POPOVER_MENU (popover));
+ if (popover && (is || contains) && active_item != target)
+ {
+ close_submenus (GTK_POPOVER_MENU (popover));
+
+ gtk_popover_menu_set_active_item (GTK_POPOVER_MENU (popover), target);
+
+ open_submenu (GTK_POPOVER_MENU (popover));
+ }
}
static void
@@ -1231,8 +1332,8 @@ gtk_model_button_init (GtkModelButton *button)
update_node_ordering (button);
controller = gtk_event_controller_motion_new ();
- g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), NULL);
- g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), NULL);
+ g_signal_connect (controller, "enter", G_CALLBACK (enter_cb), button);
+ g_signal_connect (controller, "leave", G_CALLBACK (leave_cb), button);
gtk_widget_add_controller (GTK_WIDGET (button), controller);
controller = gtk_event_controller_key_new ();
diff --git a/gtk/gtkpopovermenu.c b/gtk/gtkpopovermenu.c
index 856b017cb5..bf3b701217 100644
--- a/gtk/gtkpopovermenu.c
+++ b/gtk/gtkpopovermenu.c
@@ -124,6 +124,8 @@ struct _GtkPopoverMenu
GtkPopover parent_instance;
GtkWidget *active_item;
+ GtkWidget *open_submenu;
+ GtkWidget *parent_menu;
};
struct _GtkPopoverMenuClass
@@ -137,6 +139,39 @@ enum {
G_DEFINE_TYPE (GtkPopoverMenu, gtk_popover_menu, GTK_TYPE_POPOVER)
+GtkWidget *
+gtk_popover_menu_get_parent_menu (GtkPopoverMenu *menu)
+{
+ return menu->parent_menu;
+}
+
+void
+gtk_popover_menu_set_parent_menu (GtkPopoverMenu *menu,
+ GtkWidget *parent)
+{
+ menu->parent_menu = parent;
+}
+
+GtkWidget *
+gtk_popover_menu_get_open_submenu (GtkPopoverMenu *menu)
+{
+ return menu->open_submenu;
+}
+
+void
+gtk_popover_menu_set_open_submenu (GtkPopoverMenu *menu,
+ GtkWidget *submenu)
+{
+ if (menu->open_submenu != submenu)
+ menu->open_submenu = submenu;
+}
+
+GtkWidget *
+gtk_popover_menu_get_active_item (GtkPopoverMenu *menu)
+{
+ return menu->active_item;
+}
+
void
gtk_popover_menu_set_active_item (GtkPopoverMenu *menu,
GtkWidget *item)
@@ -508,6 +543,15 @@ gtk_popover_menu_add_submenu (GtkPopoverMenu *popover,
GtkWidget *
gtk_popover_menu_new_from_model (GtkWidget *relative_to,
GMenuModel *model)
+
+{
+ return gtk_popover_menu_new_from_model_full (relative_to, model, 0);
+}
+
+GtkWidget *
+gtk_popover_menu_new_from_model_full (GtkWidget *relative_to,
+ GMenuModel *model,
+ GtkPopoverMenuFlags flags)
{
GtkWidget *popover;
@@ -515,7 +559,8 @@ gtk_popover_menu_new_from_model (GtkWidget *relative_to,
g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL);
popover = gtk_popover_menu_new (relative_to);
- gtk_menu_section_box_new_toplevel (GTK_POPOVER_MENU (popover), model);
+ gtk_menu_section_box_new_toplevel (GTK_POPOVER_MENU (popover), model, flags);
return popover;
}
+
diff --git a/gtk/gtkpopovermenu.h b/gtk/gtkpopovermenu.h
index 143a190b70..350bea6a4f 100644
--- a/gtk/gtkpopovermenu.h
+++ b/gtk/gtkpopovermenu.h
@@ -42,6 +42,15 @@ GDK_AVAILABLE_IN_ALL
GtkWidget * gtk_popover_menu_new_from_model (GtkWidget *relative_to,
GMenuModel *model);
+typedef enum {
+ GTK_POPOVER_MENU_NESTED = 1 << 0
+} GtkPopoverMenuFlags;
+
+GDK_AVAILABLE_IN_ALL
+GtkWidget * gtk_popover_menu_new_from_model_full (GtkWidget *relative_to,
+ GMenuModel *model,
+ GtkPopoverMenuFlags flags);
+
GDK_AVAILABLE_IN_ALL
void gtk_popover_menu_add_submenu (GtkPopoverMenu *popover,
GtkWidget *submenu,
diff --git a/gtk/gtkpopovermenuprivate.h b/gtk/gtkpopovermenuprivate.h
index 024d20c91c..898dc60f30 100644
--- a/gtk/gtkpopovermenuprivate.h
+++ b/gtk/gtkpopovermenuprivate.h
@@ -22,8 +22,15 @@
G_BEGIN_DECLS
-void gtk_popover_menu_set_active_item (GtkPopoverMenu *popover,
- GtkWidget *item);
+GtkWidget *gtk_popover_menu_get_active_item (GtkPopoverMenu *menu);
+void gtk_popover_menu_set_active_item (GtkPopoverMenu *menu,
+ GtkWidget *item);
+GtkWidget *gtk_popover_menu_get_open_submenu (GtkPopoverMenu *menu);
+void gtk_popover_menu_set_open_submenu (GtkPopoverMenu *menu,
+ GtkWidget *submenu);
+GtkWidget *gtk_popover_menu_get_parent_menu (GtkPopoverMenu *menu);
+void gtk_popover_menu_set_parent_menu (GtkPopoverMenu *menu,
+ GtkWidget *parent);
G_END_DECLS
diff --git a/tests/popover2.ui b/tests/popover2.ui
index d934e6f45a..49cd3f72e2 100644
--- a/tests/popover2.ui
+++ b/tests/popover2.ui
@@ -1,5 +1,6 @@
<interface>
<object class="GtkPopoverMenu" id="popover">
+ <property name="autohide">True</property>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
@@ -105,14 +106,14 @@
</child>
<child>
<object class="GtkModelButton">
- <property name="text">Submenu 1</property>
- <property name="menu-name">submenu1</property>
+ <property name="label">Submenu 1</property>
+ <property name="popover">submenu1</property>
</object>
</child>
<child>
<object class="GtkModelButton">
- <property name="text">Submenu 2</property>
- <property name="menu-name">submenu2</property>
+ <property name="label">Submenu 2</property>
+ <property name="popover">submenu2</property>
</object>
</child>
<child>
@@ -151,17 +152,13 @@
</child>
</object>
</child>
+ </object>
+ <object class="GtkPopoverMenu" id="submenu1">
<child>
<object class="GtkBox">
<property name="name">submenu1</property>
<property name="orientation">vertical</property>
<property name="margin">10</property>
- <child>
- <object class="GtkModelButton">
- <property name="text">Submenu 1</property>
- <property name="menu-name">main</property>
- </object>
- </child>
<child>
<object class="GtkBox">
<property name="orientation">vertical</property>
@@ -352,17 +349,13 @@
</child>
</object>
</child>
+ </object>
+ <object class="GtkPopoverMenu" id="submenu2">
<child>
<object class="GtkBox">
<property name="name">submenu2</property>
<property name="orientation">vertical</property>
<property name="margin">10</property>
- <child>
- <object class="GtkModelButton">
- <property name="text">Submenu 2</property>
- <property name="menu-name">main</property>
- </object>
- </child>
<child>
<object class="GtkModelButton">
<property name="action-name">top.action7</property>
@@ -377,24 +370,19 @@
</child>
<child>
<object class="GtkModelButton">
- <property name="text">Subsubmenu</property>
- <property name="icon">icon9</property>
- <property name="menu-name">subsubmenu</property>
+ <property name="label">Subsubmenu</property>
+ <property name="popover">subsubmenu</property>
</object>
</child>
</object>
</child>
+ </object>
+ <object class="GtkPopoverMenu" id="subsubmenu">
<child>
<object class="GtkBox">
<property name="name">subsubmenu</property>
<property name="orientation">vertical</property>
<property name="margin">10</property>
- <child>
- <object class="GtkModelButton">
- <property name="text">Subsubmenu</property>
- <property name="menu-name">submenu2</property>
- </object>
- </child>
<child>
<object class="GtkModelButton">
<property name="action-name">action8</property>
diff --git a/tests/testpopover.c b/tests/testpopover.c
index 3ece11139b..ce23dc0636 100644
--- a/tests/testpopover.c
+++ b/tests/testpopover.c
@@ -37,6 +37,7 @@ main (int argc, char *argv[])
GtkWidget *win;
GtkWidget *box;
GtkWidget *button;
+ GtkWidget *button1;
GtkWidget *button2;
GtkBuilder *builder;
GMenuModel *model;
@@ -44,6 +45,7 @@ main (int argc, char *argv[])
GtkWidget *overlay;
GtkWidget *grid;
GtkWidget *popover;
+ GtkWidget *popover1;
GtkWidget *popover2;
GtkWidget *label;
GtkWidget *check;
@@ -93,6 +95,8 @@ main (int argc, char *argv[])
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
button = gtk_menu_button_new ();
gtk_container_add (GTK_CONTAINER (box), button);
+ button1 = gtk_menu_button_new ();
+ gtk_container_add (GTK_CONTAINER (box), button1);
button2 = gtk_menu_button_new ();
gtk_container_add (GTK_CONTAINER (box), button2);
@@ -100,6 +104,9 @@ main (int argc, char *argv[])
gtk_menu_button_set_use_popover (GTK_MENU_BUTTON (button), TRUE);
popover = GTK_WIDGET (gtk_menu_button_get_popover (GTK_MENU_BUTTON (button)));
+ popover1 = gtk_popover_menu_new_from_model_full (NULL, model, GTK_POPOVER_MENU_NESTED);
+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (button1), popover1);
+
builder = gtk_builder_new_from_file ("popover2.ui");
popover2 = (GtkWidget *)gtk_builder_get_object (builder, "popover");
gtk_menu_button_set_popover (GTK_MENU_BUTTON (button2), popover2);
@@ -110,6 +117,7 @@ main (int argc, char *argv[])
label = gtk_label_new ("Popover hexpand");
check = gtk_check_button_new ();
g_object_bind_property (check, "active", popover, "hexpand", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (check, "active", popover1, "hexpand", G_BINDING_SYNC_CREATE);
g_object_bind_property (check, "active", popover2, "hexpand", G_BINDING_SYNC_CREATE);
gtk_grid_attach (GTK_GRID (grid), label , 1, 1, 1, 1);
gtk_grid_attach (GTK_GRID (grid), check, 2, 1, 1, 1);
@@ -117,6 +125,7 @@ main (int argc, char *argv[])
label = gtk_label_new ("Popover vexpand");
check = gtk_check_button_new ();
g_object_bind_property (check, "active", popover, "vexpand", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (check, "active", popover1, "vexpand", G_BINDING_SYNC_CREATE);
g_object_bind_property (check, "active", popover2, "vexpand", G_BINDING_SYNC_CREATE);
gtk_grid_attach (GTK_GRID (grid), label , 1, 2, 1, 1);
gtk_grid_attach (GTK_GRID (grid), check, 2, 2, 1, 1);
@@ -129,6 +138,7 @@ main (int argc, char *argv[])
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "right", "Right");
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 1);
g_object_bind_property (combo, "active", button, "direction", G_BINDING_SYNC_CREATE);
+ g_object_bind_property (combo, "active", button1, "direction", G_BINDING_SYNC_CREATE);
g_object_bind_property (combo, "active", button2, "direction", G_BINDING_SYNC_CREATE);
gtk_grid_attach (GTK_GRID (grid), label , 1, 3, 1, 1);
gtk_grid_attach (GTK_GRID (grid), combo, 2, 3, 1, 1);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]