diff --git a/docs/reference/gtk/gtk-docs.sgml b/docs/reference/gtk/gtk-docs.sgml index e2ac6172f1..e6712a35c2 100644 --- a/docs/reference/gtk/gtk-docs.sgml +++ b/docs/reference/gtk/gtk-docs.sgml @@ -114,6 +114,7 @@ + @@ -191,6 +192,7 @@ + diff --git a/docs/reference/gtk/gtk3-sections.txt b/docs/reference/gtk/gtk3-sections.txt index c1e6af1cc9..0e0bd6cf0b 100644 --- a/docs/reference/gtk/gtk3-sections.txt +++ b/docs/reference/gtk/gtk3-sections.txt @@ -7955,6 +7955,21 @@ gtk_popover_set_modal gtk_popover_get_modal +
+gtkpopovermenu +GtkPopoverMenu +GtkPopoverMenu +gtk_popover_menu_new +
+ +
+gtkmodelbutton +GtkModelButton +GtkModelButton +GtkButtonRole +gtk_model_button_new +
+
gtkeventcontroller GtkEventController diff --git a/docs/reference/gtk/gtk3.types.in b/docs/reference/gtk/gtk3.types.in index 8f7ff3cca2..0bc2c6a055 100644 --- a/docs/reference/gtk/gtk3.types.in +++ b/docs/reference/gtk/gtk3.types.in @@ -126,6 +126,7 @@ gtk_menu_shell_get_type gtk_menu_tool_button_get_type gtk_message_dialog_get_type gtk_misc_get_type +gtk_model_button_get_type gtk_mount_operation_get_type gtk_notebook_get_type gtk_numerable_icon_get_type @@ -139,6 +140,7 @@ gtk_paper_size_get_type gtk_places_sidebar_get_type @ENABLE_ON_X11@gtk_plug_get_type gtk_popover_get_type +gtk_popover_menu_get_type @DISABLE_ON_W32@gtk_printer_get_type gtk_print_context_get_type @DISABLE_ON_W32@gtk_print_job_get_type diff --git a/gtk/gtkmodelbutton.c b/gtk/gtkmodelbutton.c index 5cb627e50a..fa71c8a79a 100644 --- a/gtk/gtkmodelbutton.c +++ b/gtk/gtkmodelbutton.c @@ -35,9 +35,79 @@ #include "gtkpopover.h" #include "gtkintl.h" +/** + * SECTION:gtkmodelbutton + * @Short_description: A button that uses a GAction as model + * @Title: GtkModelButton + * + * GtkModelButton is a button class that can use a #GAction as its model. + * In contrast to #GtkToggleButton or #GtkRadioButton, which can also + * be backed by a #Gaction via the #GtkActionable:action-name property, + * GtkModelButton will adapt its appearance according to the kind of + * action it is backed by, and appear either as a plain, check or + * radio button. + * + * Model buttons are used when popovers from a menu model with + * gtk_popover_new_from_model(); they can also be used manually in + * a #GtkPopoverMenu. + * + * When the action is specified via the #GtkActionable:action-name + * and #GtkActionable:action-target properties, the role of the button + * (i.e. whether it is a plain, check or radio button) is determined by + * the type of the action and doesn't have to be explicitly specified + * with the #GtkModelButton:role property. + * + * The content of the button is specified by the #GtkModelButton:text + * and #GtkModelButton:icon properties. + * + * The appearance of model buttons can be influenced with the + * #GtkModelButton:centered and #GtkModelButton:iconic properties. + * + * Model buttons have built-in support for submenus in #GtkPopoverMenu. + * To make a GtkModelButton that opens a submenu when activated, set + * the #GtkModelButton:menu-name property. To make a button that goes + * back to the parent menu, you should set the #GtkModelButton:inverted + * property to place the submenu indicator at the opposite side. + * + * # Example + * + * |[ + * + * + * + * True + * 10 + * + * + * True + * view.cut + * Cut + * + * + * + * + * True + * view.copy + * Copy + * + * + * + * + * True + * view.paste + * Paste + * + * + * + * + * + * ]| + */ + struct _GtkModelButton { GtkButton parent_instance; + GtkWidget *box; GtkWidget *image; GtkWidget *label; @@ -459,12 +529,12 @@ gtk_model_button_get_preferred_width (GtkWidget *widget, } static void -gtk_model_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget, - gint width, - gint *minimum, - gint *natural, - gint *minimum_baseline, - gint *natural_baseline) +gtk_model_button_get_preferred_height_and_baseline_for_width (GtkWidget *widget, + gint width, + gint *minimum, + gint *natural, + gint *minimum_baseline, + gint *natural_baseline) { GtkModelButton *button = GTK_MODEL_BUTTON (widget); GtkWidget *child; @@ -641,9 +711,7 @@ gtk_model_button_draw (GtkWidget *widget, gint baseline; if (model_button->iconic) - { - return GTK_WIDGET_CLASS (gtk_model_button_parent_class)->draw (widget, cr); - } + return GTK_WIDGET_CLASS (gtk_model_button_parent_class)->draw (widget, cr); context = gtk_widget_get_style_context (widget); width = gtk_widget_get_allocated_width (widget); @@ -768,37 +836,126 @@ gtk_model_button_class_init (GtkModelButtonClass *class) button_class->clicked = gtk_model_button_clicked; + /** + * GtkModelButton:role: + * + * Specifies whether the button is a plain, check or radio button. + * When #GtkActionable:action-name is set, the role will be determined + * from the action and does not have to be set explicitly. + * + * Since: 3.16 + */ properties[PROP_ROLE] = - g_param_spec_enum ("role", P_("Role"), P_("The role of this button"), + g_param_spec_enum ("role", + P_("Role"), + P_("The role of this button"), GTK_TYPE_BUTTON_ROLE, GTK_BUTTON_ROLE_NORMAL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkModelButton:icon: + * + * A #GIcon that will be used if iconic appearance for the button is + * desired. + * + * Since: 3.16 + */ properties[PROP_ICON] = - g_param_spec_object ("icon", P_("Icon"), P_("The icon"), + g_param_spec_object ("icon", + P_("Icon"), + P_("The icon"), G_TYPE_ICON, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkModelButton:text: + * + * The label for the button. + * + * Since: 3.16 + */ properties[PROP_TEXT] = - g_param_spec_string ("text", P_("Text"), P_("The text"), + g_param_spec_string ("text", + P_("Text"), + P_("The text"), NULL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkModelButton:active: + * + * The state of the button. This is reflecting the state of the associated + * #GAction. + * + * Since: 3.16 + */ properties[PROP_ACTIVE] = - g_param_spec_boolean ("active", P_("Active"), P_("Active"), + g_param_spec_boolean ("active", + P_("Active"), + P_("Active"), FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * 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. + * + * Since: 3.16 + */ properties[PROP_MENU_NAME] = - g_param_spec_string ("menu-name", P_("Menu name"), P_("The name of the menu to open"), + g_param_spec_string ("menu-name", + P_("Menu name"), + P_("The name of the menu to open"), NULL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkModelButton:inverted: + * + * Whether to show the submenu indicator at the opposite side than normal. + * This property should be set for model buttons that 'go back' to a parent + * menu. + * + * Since: 3.16 + */ properties[PROP_INVERTED] = - g_param_spec_boolean ("inverted", P_("Inverted"), P_("Whether the menu is a parent"), + g_param_spec_boolean ("inverted", + P_("Inverted"), + P_("Whether the menu is a parent"), FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkModelButton:centered: + * + * Wether to render the button contents centered instead of left-aligned. + * This property should be set for title-like items. + * + * Since: 3.16 + */ properties[PROP_CENTERED] = - g_param_spec_boolean ("centered", P_("Centered"), P_("Whether to center the contents"), + g_param_spec_boolean ("centered", + P_("Centered"), + P_("Whether to center the contents"), FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GtkModelButton:iconic: + * + * If this property is set, the button will show an icon if one is set. + * If no icon is set, the text will be used. This is typically used for + * horizontal sections of linked buttons. + * + * Since: 3.16 + */ properties[PROP_ICONIC] = - g_param_spec_boolean ("iconic", P_("Iconic"), P_("Whether to prefer the icon over text"), + g_param_spec_boolean ("iconic", + P_("Iconic"), + P_("Whether to prefer the icon over text"), TRUE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROPERTY, properties); @@ -811,12 +968,10 @@ gtk_model_button_init (GtkModelButton *button) { gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE); button->box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6); - g_object_set (button->box, - "margin-start", 12, - "margin-end", 12, - "margin-top", 3, - "margin-bottom", 3, - NULL); + gtk_widget_set_margin_start (button->box, 12); + gtk_widget_set_margin_end (button->box, 12); + gtk_widget_set_margin_top (button->box, 3); + gtk_widget_set_margin_bottom (button->box, 3); gtk_widget_set_halign (button->box, GTK_ALIGN_FILL); gtk_widget_show (button->box); button->image = gtk_image_new (); diff --git a/gtk/gtkmodelbutton.h b/gtk/gtkmodelbutton.h index 154c932fb3..3ac8eb0c6e 100644 --- a/gtk/gtkmodelbutton.h +++ b/gtk/gtkmodelbutton.h @@ -36,6 +36,14 @@ G_BEGIN_DECLS typedef struct _GtkModelButton GtkModelButton; +/** + * GtkButtonRole: + * @GTK_BUTTON_ROLE_NORMAL: A plain button + * @GTK_BUTTON_ROLE_CHECK: A check button + * @GTK_BUTTON_ROLE_RADIO: A radio button + * + * The role specifies the desired appearance of a #GtkModelButton. + */ typedef enum { GTK_BUTTON_ROLE_NORMAL, GTK_BUTTON_ROLE_CHECK, diff --git a/gtk/gtkpopovermenu.c b/gtk/gtkpopovermenu.c index e791a50ac1..0e7e1113c2 100644 --- a/gtk/gtkpopovermenu.c +++ b/gtk/gtkpopovermenu.c @@ -22,6 +22,82 @@ #include "gtkintl.h" +/** + * SECTION:gtkpopovermenu + * @Short_description: Popovers to use as menus + * @Title: GtkPopoverMenu + * + * GtkPopoverMenu is a subclass of #GtkPopover that treats its + * childen like menus and allows switching between them. It is + * meant to be used primarily together with #GtkModelButton, but + * any widget can be used, such as #GtkSpinButton or #GtkScale. + * In this respect, GtkPopoverMenu is more flexible than popovers + * that are created from a #GMenuModel with gtk_popover_new_from_model(). + * + * To add a child as a submenu, set the #GtkPopoverMenu:submenu + * child property to the name of the submenu. To let the user open + * this submenu, add a #GtkModelButton whose #GtkModelButton:menu-name + * property is set to the name you've given to the submenu. + * + * By convention, the first child of a submenu should be a #GtkModelButton + * to switch back to the parent menu. Such a button should use the + * #GtkModelButton:inverted and #GtkModelButton:centered properties + * to achieve a title-like appearance and place the submenu indicator + * at the opposite side. To switch back to the main menu, use "main" + * as the menu name. + * + * # Example + * + * |[ + * + * + * + * True + * 10 + * + * + * True + * win.frob + * Frob + * + * + * + * + * True + * more + * More + * + * + * + * + * + * + * True + * 10 + * + * + * True + * win.foo + * Foo + * + * + * + * + * True + * win.bar + * Bar + * + * + * + * + * more + * + * + * + * ]| +* + */ + struct _GtkPopoverMenu { GtkPopover parent_instance; @@ -183,6 +259,15 @@ gtk_popover_menu_class_init (GtkPopoverMenuClass *klass) container_class->set_child_property = gtk_popover_menu_set_child_property; container_class->get_child_property = gtk_popover_menu_get_child_property; + /** + * GtkPopoverMenu:submenu: + * + * The submenu child property specifies the name of the submenu + * If it is %NULL or "main", the child is used as the main menu, + * which is shown initially when the popover is mapped. + * + * Since: 3.16 + */ gtk_container_class_install_child_property (container_class, CHILD_PROP_SUBMENU, g_param_spec_string ("submenu", @@ -192,6 +277,15 @@ gtk_popover_menu_class_init (GtkPopoverMenuClass *klass) G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS)); } +/** + * gtk_popover_menu_new: + * + * Creates a new popover menu. + * + * Returns: a new #GtkPopoverMenu + * + * Since: 3.16 + */ GtkWidget * gtk_popover_menu_new (void) {