diff --git a/demos/widget-factory/widget-factory.c b/demos/widget-factory/widget-factory.c index cd7e7cc20b..976661b8c8 100644 --- a/demos/widget-factory/widget-factory.c +++ b/demos/widget-factory/widget-factory.c @@ -1627,7 +1627,7 @@ static void set_up_context_popover (GtkWidget *widget, GMenuModel *model) { - GtkWidget *popover = gtk_popover_new_from_model (widget, model); + GtkWidget *popover = gtk_popover_menu_new_from_model (widget, model); GtkGesture *gesture; g_object_set (popover, "has-arrow", FALSE, NULL); diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt index 75fe4b1a9b..4696255497 100644 --- a/docs/reference/gtk/gtk4-sections.txt +++ b/docs/reference/gtk/gtk4-sections.txt @@ -6438,8 +6438,6 @@ gtk_flow_box_child_get_type GtkPopover GtkPopover gtk_popover_new -gtk_popover_new_from_model -gtk_popover_bind_model gtk_popover_popup gtk_popover_popdown gtk_popover_set_relative_to @@ -6477,6 +6475,7 @@ gtk_popover_get_type GtkPopoverMenu GtkPopoverMenu gtk_popover_menu_new +gtk_popover_menu_new_from_model gtk_popover_menu_add_submenu gtk_popover_menu_open_submenu diff --git a/gtk/gtkmenubutton.c b/gtk/gtkmenubutton.c index 485e46dacc..7937982a77 100644 --- a/gtk/gtkmenubutton.c +++ b/gtk/gtkmenubutton.c @@ -118,6 +118,7 @@ #include "gtkmenubutton.h" #include "gtkmenubuttonprivate.h" #include "gtkpopover.h" +#include "gtkpopovermenu.h" #include "gtkprivate.h" #include "gtkstylecontext.h" #include "gtktypebuiltins.h" @@ -901,7 +902,7 @@ gtk_menu_button_set_menu_model (GtkMenuButton *menu_button, { GtkWidget *popover; - popover = gtk_popover_new_from_model (GTK_WIDGET (menu_button), menu_model); + popover = gtk_popover_menu_new_from_model (GTK_WIDGET (menu_button), menu_model); gtk_menu_button_set_popover (menu_button, popover); } else diff --git a/gtk/gtkmenusectionbox.c b/gtk/gtkmenusectionbox.c index e512d7bc33..47f443b637 100644 --- a/gtk/gtkmenusectionbox.c +++ b/gtk/gtkmenusectionbox.c @@ -30,7 +30,7 @@ #include "gtksizegroup.h" #include "gtkstack.h" #include "gtkstylecontext.h" -#include "gtkpopover.h" +#include "gtkpopovermenu.h" #include "gtkorientable.h" #include "gtkiconprivate.h" @@ -453,20 +453,18 @@ update_popover_position_cb (GObject *source, } void -gtk_menu_section_box_new_toplevel (GtkStack *stack, - GMenuModel *model, - const gchar *action_namespace, - GtkPopover *popover) +gtk_menu_section_box_new_toplevel (GtkPopoverMenu *popover, + GMenuModel *model) { GtkMenuSectionBox *box; box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, NULL); box->indicators = gtk_size_group_new (GTK_SIZE_GROUP_HORIZONTAL); - gtk_stack_add_named (stack, GTK_WIDGET (box), "main"); + gtk_popover_menu_add_submenu (popover, GTK_WIDGET (box), "main"); box->tracker = gtk_menu_tracker_new (GTK_ACTION_OBSERVABLE (_gtk_widget_get_action_muxer (GTK_WIDGET (box), TRUE)), - model, TRUE, FALSE, FALSE, action_namespace, + model, TRUE, FALSE, FALSE, NULL, gtk_menu_section_box_insert_func, gtk_menu_section_box_remove_func, box); diff --git a/gtk/gtkmenusectionbox.h b/gtk/gtkmenusectionbox.h index c300abea14..c5d9772af9 100644 --- a/gtk/gtkmenusectionbox.h +++ b/gtk/gtkmenusectionbox.h @@ -21,9 +21,8 @@ #define __GTK_MENU_SECTION_BOX_H__ #include -#include #include -#include +#include G_BEGIN_DECLS @@ -42,10 +41,8 @@ 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 (GtkStack *stack, - GMenuModel *model, - const gchar *action_namespace, - GtkPopover *popover); +void gtk_menu_section_box_new_toplevel (GtkPopoverMenu *popover, + GMenuModel *model); G_END_DECLS diff --git a/gtk/gtkpopover.c b/gtk/gtkpopover.c index 9c14e8d1d2..25fdbf23b0 100644 --- a/gtk/gtkpopover.c +++ b/gtk/gtkpopover.c @@ -44,10 +44,10 @@ * * GtkPopover is often used to replace menus. To facilitate this, it * supports being populated from a #GMenuModel, using - * gtk_popover_new_from_model(). In addition to all the regular menu - * model features, this function supports rendering sections in the - * model in a more compact form, as a row of icon buttons instead of - * menu items. + * gtk_popover_menu_new_from_model(). In addition to all the regular + * menu model features, this function supports rendering sections in + * the model in a more compact form, as a row of icon buttons instead + * of menu items. * * To use this rendering, set the ”display-hint” attribute of the * section to ”horizontal-buttons” and set the icons of your items @@ -77,23 +77,23 @@ * # CSS nodes * * |[ - * popover + * popover[.menu] * ├── arrow - * ╰── contents.background[.menu] + * ╰── contents.background * ╰── * ]| * - * The contents child node always gets the .background style class and it - * gets the .menu style class if the popover is menu-like (e.g. #GtkPopoverMenu - * or created using gtk_popover_new_from_model()). + * The contents child node always gets the .background style class and + * the popover itself gets the .menu style class if the popover is + * menu-like (ie #GtkPopoverMenu). * * Particular uses of GtkPopover, such as touch selection popups * or magnifiers in #GtkEntry or #GtkTextView get style classes * like .touch-selection or .magnifier to differentiate from * plain popovers. * - * When styling a popover directly, the popover node should usually not have any - * background. + * When styling a popover directly, the popover node should usually + * not have any background. * * Note that, in order to accomplish appropriate arrow visuals, #GtkPopover uses * custom drawing for the arrow node. This makes it possible for the arrow to change @@ -1708,92 +1708,6 @@ gtk_popover_popdown (GtkPopover *popover) gtk_widget_hide (GTK_WIDGET (popover)); } -static void -back_to_main (GtkWidget *popover) -{ - GtkWidget *stack; - - stack = gtk_bin_get_child (GTK_BIN (popover)); - gtk_stack_set_visible_child_name (GTK_STACK (stack), "main"); -} - -static void -gtk_popover_bind_model (GtkPopover *popover, - GMenuModel *model, - const gchar *action_namespace) -{ - GtkWidget *child; - GtkWidget *stack; - GtkStyleContext *style_context; - - g_return_if_fail (GTK_IS_POPOVER (popover)); - g_return_if_fail (model == NULL || G_IS_MENU_MODEL (model)); - - child = gtk_bin_get_child (GTK_BIN (popover)); - if (child) - gtk_widget_destroy (child); - - style_context = gtk_widget_get_style_context (GTK_WIDGET (popover)); - - if (model) - { - stack = gtk_stack_new (); - gtk_stack_set_vhomogeneous (GTK_STACK (stack), FALSE); - gtk_stack_set_transition_type (GTK_STACK (stack), GTK_STACK_TRANSITION_TYPE_SLIDE_LEFT_RIGHT); - gtk_stack_set_interpolate_size (GTK_STACK (stack), TRUE); - gtk_container_add (GTK_CONTAINER (popover), stack); - - gtk_menu_section_box_new_toplevel (GTK_STACK (stack), - model, - action_namespace, - popover); - gtk_stack_set_visible_child_name (GTK_STACK (stack), "main"); - - g_signal_connect (popover, "unmap", G_CALLBACK (back_to_main), NULL); - g_signal_connect (popover, "map", G_CALLBACK (back_to_main), NULL); - - gtk_style_context_add_class (style_context, GTK_STYLE_CLASS_MENU); - } - else - { - gtk_style_context_remove_class (style_context, GTK_STYLE_CLASS_MENU); - } -} - -/** - * gtk_popover_new_from_model: - * @relative_to: (allow-none): #GtkWidget the popover is related to - * @model: a #GMenuModel - * - * Creates a #GtkPopover and populates it according to - * @model. The popover is pointed to the @relative_to widget. - * - * The created buttons are connected to actions found in the - * #GtkApplicationWindow to which the popover belongs - typically - * by means of being attached to a widget that is contained within - * the #GtkApplicationWindows widget hierarchy. - * - * Actions can also be added using gtk_widget_insert_action_group() - * on the menus attach widget or on any of its parent widgets. - * - * Returns: the new #GtkPopover - */ -GtkWidget * -gtk_popover_new_from_model (GtkWidget *relative_to, - GMenuModel *model) -{ - GtkWidget *popover; - - g_return_val_if_fail (relative_to == NULL || GTK_IS_WIDGET (relative_to), NULL); - g_return_val_if_fail (G_IS_MENU_MODEL (model), NULL); - - popover = gtk_popover_new (relative_to); - gtk_popover_bind_model (GTK_POPOVER (popover), model, NULL); - - return popover; -} - - GtkWidget * gtk_popover_get_contents_widget (GtkPopover *popover) { diff --git a/gtk/gtkpopover.h b/gtk/gtkpopover.h index 9a0ae9866a..615cd9a79e 100644 --- a/gtk/gtkpopover.h +++ b/gtk/gtkpopover.h @@ -59,41 +59,37 @@ GDK_AVAILABLE_IN_ALL GType gtk_popover_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_ALL -GtkWidget * gtk_popover_new (GtkWidget *relative_to); - -GDK_AVAILABLE_IN_ALL -GtkWidget * gtk_popover_new_from_model (GtkWidget *relative_to, - GMenuModel *model); +GtkWidget * gtk_popover_new (GtkWidget *relative_to); GDK_AVAILABLE_IN_ALL void gtk_popover_set_relative_to (GtkPopover *popover, - GtkWidget *relative_to); + GtkWidget *relative_to); GDK_AVAILABLE_IN_ALL GtkWidget * gtk_popover_get_relative_to (GtkPopover *popover); GDK_AVAILABLE_IN_ALL -void gtk_popover_set_pointing_to (GtkPopover *popover, - const GdkRectangle *rect); +void gtk_popover_set_pointing_to (GtkPopover *popover, + const GdkRectangle *rect); GDK_AVAILABLE_IN_ALL -gboolean gtk_popover_get_pointing_to (GtkPopover *popover, - GdkRectangle *rect); +gboolean gtk_popover_get_pointing_to (GtkPopover *popover, + GdkRectangle *rect); GDK_AVAILABLE_IN_ALL -void gtk_popover_set_position (GtkPopover *popover, - GtkPositionType position); +void gtk_popover_set_position (GtkPopover *popover, + GtkPositionType position); GDK_AVAILABLE_IN_ALL -GtkPositionType gtk_popover_get_position (GtkPopover *popover); +GtkPositionType gtk_popover_get_position (GtkPopover *popover); GDK_AVAILABLE_IN_ALL -void gtk_popover_set_autohide (GtkPopover *popover, - gboolean autohide); +void gtk_popover_set_autohide (GtkPopover *popover, + gboolean autohide); GDK_AVAILABLE_IN_ALL -gboolean gtk_popover_get_autohide (GtkPopover *popover); +gboolean gtk_popover_get_autohide (GtkPopover *popover); GDK_AVAILABLE_IN_ALL -void gtk_popover_set_has_arrow (GtkPopover *popover, - gboolean has_arrow); +void gtk_popover_set_has_arrow (GtkPopover *popover, + gboolean has_arrow); GDK_AVAILABLE_IN_ALL -gboolean gtk_popover_get_has_arrow (GtkPopover *popover); +gboolean gtk_popover_get_has_arrow (GtkPopover *popover); GDK_AVAILABLE_IN_ALL void gtk_popover_popup (GtkPopover *popover); diff --git a/gtk/gtkpopovermenu.c b/gtk/gtkpopovermenu.c index f8d85f76de..65c1c87844 100644 --- a/gtk/gtkpopovermenu.c +++ b/gtk/gtkpopovermenu.c @@ -20,7 +20,12 @@ #include "gtkstack.h" #include "gtkstylecontext.h" #include "gtkintl.h" +#include "gtkmenusectionbox.h" +#include "gtkmenubutton.h" +#include "gtkactionmuxerprivate.h" +#include "gtkmenutracker.h" #include "gtkpopoverprivate.h" +#include "gtkwidgetprivate.h" /** @@ -276,15 +281,23 @@ gtk_popover_menu_class_init (GtkPopoverMenuClass *klass) /** * gtk_popover_menu_new: + * @relative_to: (allow-none): #GtkWidget the popover is related to * * Creates a new popover menu. * * Returns: a new #GtkPopoverMenu */ GtkWidget * -gtk_popover_menu_new (void) +gtk_popover_menu_new (GtkWidget *relative_to) { - return g_object_new (GTK_TYPE_POPOVER_MENU, NULL); + GtkWidget *popover; + + g_return_val_if_fail (relative_to == NULL || GTK_IS_WIDGET (relative_to), NULL); + + popover = g_object_new (GTK_TYPE_POPOVER_MENU, NULL); + gtk_popover_set_relative_to (GTK_POPOVER (popover), relative_to); + + return popover; } /** @@ -332,4 +345,37 @@ gtk_popover_menu_add_submenu (GtkPopoverMenu *popover, stack = gtk_bin_get_child (GTK_BIN (popover)); gtk_stack_add_named (GTK_STACK (stack), submenu, name); -} +} + +/** + * gtk_popover_menu_new_from_model: + * @relative_to: (allow-none): #GtkWidget the popover is related to + * @model: a #GMenuModel + * + * Creates a #GtkPopoverMenu and populates it according to + * @model. The popover is pointed to the @relative_to widget. + * + * The created buttons are connected to actions found in the + * #GtkApplicationWindow to which the popover belongs - typically + * by means of being attached to a widget that is contained within + * the #GtkApplicationWindows widget hierarchy. + * + * Actions can also be added using gtk_widget_insert_action_group() + * on the menus attach widget or on any of its parent widgets. + * + * Returns: the new #GtkPopoverMenu + */ +GtkWidget * +gtk_popover_menu_new_from_model (GtkWidget *relative_to, + GMenuModel *model) +{ + GtkWidget *popover; + + g_return_val_if_fail (relative_to == NULL || GTK_IS_WIDGET (relative_to), NULL); + 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); + + return popover; +} diff --git a/gtk/gtkpopovermenu.h b/gtk/gtkpopovermenu.h index e49bbd25f1..143a190b70 100644 --- a/gtk/gtkpopovermenu.h +++ b/gtk/gtkpopovermenu.h @@ -36,7 +36,11 @@ GDK_AVAILABLE_IN_ALL GType gtk_popover_menu_get_type (void) G_GNUC_CONST; GDK_AVAILABLE_IN_ALL -GtkWidget * gtk_popover_menu_new (void); +GtkWidget * gtk_popover_menu_new (GtkWidget *relative_to); + +GDK_AVAILABLE_IN_ALL +GtkWidget * gtk_popover_menu_new_from_model (GtkWidget *relative_to, + GMenuModel *model); GDK_AVAILABLE_IN_ALL void gtk_popover_menu_add_submenu (GtkPopoverMenu *popover,