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
+ *
+ * |[
+ *
+ * ]|
+ */
+
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
+ *
+ * |[
+ *
+ * ]|
+*
+ */
+
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)
{