Compare commits
19 Commits
main
...
popover-me
Author | SHA1 | Date | |
---|---|---|---|
|
5cf0bff0ba | ||
|
aa90e6fd02 | ||
|
9b8043be93 | ||
|
78585c9b38 | ||
|
e0f6605d50 | ||
|
e068b048b5 | ||
|
e449ab5fa3 | ||
|
4589aec1aa | ||
|
6b27f63008 | ||
|
faa793610a | ||
|
4d02a65111 | ||
|
c413ddefc1 | ||
|
7dcda2a17a | ||
|
5ce97bb77e | ||
|
fe0aa6e18c | ||
|
44ad311eeb | ||
|
2fe9779b52 | ||
|
660bc6adf6 | ||
|
70005e0918 |
@@ -114,6 +114,7 @@
|
||||
<xi:include href="xml/gtkscalebutton.xml" />
|
||||
<xi:include href="xml/gtkvolumebutton.xml" />
|
||||
<xi:include href="xml/gtklockbutton.xml" />
|
||||
<xi:include href="xml/gtkmodelbutton.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="NumericEntry">
|
||||
@@ -191,6 +192,7 @@
|
||||
<xi:include href="xml/gtktoggletoolbutton.xml" />
|
||||
<xi:include href="xml/gtkradiotoolbutton.xml" />
|
||||
<xi:include href="xml/gtkpopover.xml" />
|
||||
<xi:include href="xml/gtkpopovermenu.xml" />
|
||||
</chapter>
|
||||
|
||||
<chapter id="SelectorWidgets">
|
||||
|
@@ -7955,6 +7955,22 @@ gtk_popover_set_modal
|
||||
gtk_popover_get_modal
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkpopovermenu</FILE>
|
||||
<TITLE>GtkPopoverMenu</TITLE>
|
||||
GtkPopoverMenu
|
||||
gtk_popover_menu_new
|
||||
gtk_popover_menu_open_submenu
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkmodelbutton</FILE>
|
||||
<TITLE>GtkModelButton</TITLE>
|
||||
GtkModelButton
|
||||
GtkButtonRole
|
||||
gtk_model_button_new
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
<FILE>gtkeventcontroller</FILE>
|
||||
<TITLE>GtkEventController</TITLE>
|
||||
|
@@ -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
|
||||
|
@@ -393,6 +393,7 @@ gtk_public_h_sources = \
|
||||
gtkmenushell.h \
|
||||
gtkmenutoolbutton.h \
|
||||
gtkmessagedialog.h \
|
||||
gtkmodelbutton.h \
|
||||
gtkmodules.h \
|
||||
gtkmountoperation.h \
|
||||
gtknotebook.h \
|
||||
@@ -405,6 +406,7 @@ gtk_public_h_sources = \
|
||||
gtkplacessidebar.h \
|
||||
gtkplug.h \
|
||||
gtkpopover.h \
|
||||
gtkpopovermenu.h \
|
||||
gtkprintcontext.h \
|
||||
gtkprintoperation.h \
|
||||
gtkprintoperationpreview.h \
|
||||
@@ -624,7 +626,6 @@ gtk_private_h_sources = \
|
||||
gtkmenutrackeritem.h \
|
||||
gtkmnemonichash.h \
|
||||
gtkmodelmenuitem.h \
|
||||
gtkmodelbutton.h \
|
||||
gtkmodifierstyle.h \
|
||||
gtkmodulesprivate.h \
|
||||
gtkmountoperationprivate.h \
|
||||
@@ -1008,6 +1009,7 @@ gtk_base_c_sources = \
|
||||
gtkprogressbar.c \
|
||||
gtkpixelcache.c \
|
||||
gtkpopover.c \
|
||||
gtkpopovermenu.c \
|
||||
gtkradiobutton.c \
|
||||
gtkradiomenuitem.c \
|
||||
gtkradiotoolbutton.c \
|
||||
|
@@ -141,6 +141,7 @@
|
||||
#include <gtk/gtkmenushell.h>
|
||||
#include <gtk/gtkmenutoolbutton.h>
|
||||
#include <gtk/gtkmessagedialog.h>
|
||||
#include <gtk/gtkmodelbutton.h>
|
||||
#include <gtk/gtkmodules.h>
|
||||
#include <gtk/gtkmountoperation.h>
|
||||
#include <gtk/gtknotebook.h>
|
||||
@@ -152,6 +153,7 @@
|
||||
#include <gtk/gtkpaned.h>
|
||||
#include <gtk/gtkplacessidebar.h>
|
||||
#include <gtk/gtkpopover.h>
|
||||
#include <gtk/gtkpopovermenu.h>
|
||||
#include <gtk/gtkprintcontext.h>
|
||||
#include <gtk/gtkprintoperation.h>
|
||||
#include <gtk/gtkprintoperationpreview.h>
|
||||
|
@@ -23,6 +23,8 @@
|
||||
#include "gtkwidget.h"
|
||||
#include "gtkwidgetprivate.h"
|
||||
#include "gtkdebug.h"
|
||||
#include "gtkmodelbutton.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
@@ -66,6 +68,8 @@ struct _GtkActionHelper
|
||||
gboolean enabled;
|
||||
gboolean active;
|
||||
|
||||
GtkButtonRole role;
|
||||
|
||||
gint reporting;
|
||||
};
|
||||
|
||||
@@ -74,6 +78,7 @@ enum
|
||||
PROP_0,
|
||||
PROP_ENABLED,
|
||||
PROP_ACTIVE,
|
||||
PROP_ROLE,
|
||||
N_PROPS
|
||||
};
|
||||
|
||||
@@ -107,6 +112,17 @@ gtk_action_helper_report_change (GtkActionHelper *helper,
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_ROLE:
|
||||
{
|
||||
GParamSpec *pspec;
|
||||
|
||||
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (helper->widget), "role");
|
||||
|
||||
if (pspec && G_PARAM_SPEC_VALUE_TYPE (pspec) == GTK_TYPE_BUTTON_ROLE)
|
||||
g_object_set (G_OBJECT (helper->widget), "role", helper->role, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@@ -146,10 +162,19 @@ gtk_action_helper_action_added (GtkActionHelper *helper,
|
||||
GTK_NOTE(ACTIONS, g_message("actionhelper: %s found and enabled", helper->action_name));
|
||||
|
||||
if (helper->target != NULL && state != NULL)
|
||||
helper->active = g_variant_equal (state, helper->target);
|
||||
|
||||
{
|
||||
helper->active = g_variant_equal (state, helper->target);
|
||||
helper->role = GTK_BUTTON_ROLE_RADIO;
|
||||
}
|
||||
else if (state != NULL && g_variant_is_of_type (state, G_VARIANT_TYPE_BOOLEAN))
|
||||
helper->active = g_variant_get_boolean (state);
|
||||
{
|
||||
helper->active = g_variant_get_boolean (state);
|
||||
helper->role = GTK_BUTTON_ROLE_CHECK;
|
||||
}
|
||||
else
|
||||
{
|
||||
helper->role = GTK_BUTTON_ROLE_NORMAL;
|
||||
}
|
||||
|
||||
if (should_emit_signals)
|
||||
{
|
||||
@@ -158,6 +183,8 @@ gtk_action_helper_action_added (GtkActionHelper *helper,
|
||||
|
||||
if (helper->active)
|
||||
gtk_action_helper_report_change (helper, PROP_ACTIVE);
|
||||
|
||||
gtk_action_helper_report_change (helper, PROP_ROLE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,6 +269,10 @@ gtk_action_helper_get_property (GObject *object, guint prop_id,
|
||||
g_value_set_boolean (value, helper->active);
|
||||
break;
|
||||
|
||||
case PROP_ROLE:
|
||||
g_value_set_enum (value, helper->role);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
@@ -313,6 +344,10 @@ gtk_action_helper_class_init (GtkActionHelperClass *class)
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
gtk_action_helper_pspecs[PROP_ACTIVE] = g_param_spec_boolean ("active", "active", "active", FALSE,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
gtk_action_helper_pspecs[PROP_ROLE] = g_param_spec_enum ("role", "role", "role",
|
||||
GTK_TYPE_BUTTON_ROLE,
|
||||
GTK_BUTTON_ROLE_NORMAL,
|
||||
G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (class, N_PROPS, gtk_action_helper_pspecs);
|
||||
}
|
||||
|
||||
|
@@ -51,6 +51,7 @@
|
||||
#include "gtkwidgetpath.h"
|
||||
#include "a11y/gtkcontaineraccessible.h"
|
||||
#include "a11y/gtkcontaineraccessibleprivate.h"
|
||||
#include "gtkpopovermenu.h"
|
||||
|
||||
/**
|
||||
* SECTION:gtkcontainer
|
||||
@@ -608,7 +609,10 @@ gtk_container_buildable_set_child_property (GtkContainer *container,
|
||||
GValue gvalue = G_VALUE_INIT;
|
||||
GError *error = NULL;
|
||||
|
||||
if (gtk_widget_get_parent (child) != (GtkWidget *)container && !GTK_IS_ASSISTANT (container) && !GTK_IS_ACTION_BAR (container))
|
||||
if (gtk_widget_get_parent (child) != (GtkWidget *)container &&
|
||||
!GTK_IS_ASSISTANT (container) &&
|
||||
!GTK_IS_ACTION_BAR (container) &&
|
||||
!GTK_IS_POPOVER_MENU (container))
|
||||
{
|
||||
/* This can happen with internal children of complex widgets.
|
||||
* Silently ignore the child properties in this case. We explicitly
|
||||
|
@@ -50,13 +50,14 @@ struct _GtkMenuSectionBox
|
||||
|
||||
G_DEFINE_TYPE (GtkMenuSectionBox, gtk_menu_section_box, GTK_TYPE_BOX)
|
||||
|
||||
void gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
|
||||
gint *n_items);
|
||||
void gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
|
||||
GtkMenuSectionBox *toplevel,
|
||||
GtkWidget *focus);
|
||||
GtkWidget * gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
|
||||
GtkMenuSectionBox *parent);
|
||||
static void gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
|
||||
gint *n_items);
|
||||
static void gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
|
||||
GtkMenuSectionBox *toplevel,
|
||||
GtkWidget *focus,
|
||||
const gchar *name);
|
||||
static GtkWidget * gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
|
||||
GtkMenuSectionBox *parent);
|
||||
|
||||
static void
|
||||
gtk_menu_section_box_sync_item (GtkWidget *widget,
|
||||
@@ -79,7 +80,7 @@ gtk_menu_section_box_sync_item (GtkWidget *widget,
|
||||
* no items before it
|
||||
* (rule 5: these rules don't apply exactly the same way for subsections)
|
||||
*/
|
||||
void
|
||||
static void
|
||||
gtk_menu_section_box_sync_separators (GtkMenuSectionBox *box,
|
||||
gint *n_items)
|
||||
{
|
||||
@@ -209,16 +210,12 @@ close_submenu (GtkWidget *button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkMenuTrackerItem *item = data;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *parent;
|
||||
GtkWidget *focus;
|
||||
|
||||
if (gtk_menu_tracker_item_get_should_request_show (item))
|
||||
gtk_menu_tracker_item_request_submenu_shown (item, FALSE);
|
||||
|
||||
focus = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"));
|
||||
get_ancestors (focus, GTK_TYPE_STACK, &stack, &parent);
|
||||
gtk_stack_set_visible_child (GTK_STACK (stack), parent);
|
||||
gtk_widget_grab_focus (focus);
|
||||
}
|
||||
|
||||
@@ -227,16 +224,12 @@ open_submenu (GtkWidget *button,
|
||||
gpointer data)
|
||||
{
|
||||
GtkMenuTrackerItem *item = data;
|
||||
GtkWidget *stack;
|
||||
GtkWidget *child;
|
||||
GtkWidget *focus;
|
||||
|
||||
if (gtk_menu_tracker_item_get_should_request_show (item))
|
||||
gtk_menu_tracker_item_request_submenu_shown (item, TRUE);
|
||||
|
||||
focus = GTK_WIDGET (g_object_get_data (G_OBJECT (button), "focus"));
|
||||
get_ancestors (focus, GTK_TYPE_STACK, &stack, &child);
|
||||
gtk_stack_set_visible_child (GTK_STACK (stack), child);
|
||||
gtk_widget_grab_focus (focus);
|
||||
}
|
||||
|
||||
@@ -254,17 +247,25 @@ gtk_menu_section_box_insert_func (GtkMenuTrackerItem *item,
|
||||
}
|
||||
else if (gtk_menu_tracker_item_get_has_link (item, G_MENU_LINK_SUBMENU))
|
||||
{
|
||||
widget = g_object_new (GTK_TYPE_MODEL_BUTTON, "has-submenu", TRUE, NULL);
|
||||
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),
|
||||
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);
|
||||
gtk_menu_section_box_new_submenu (item, box->toplevel, widget);
|
||||
gtk_widget_show (widget);
|
||||
|
||||
get_ancestors (GTK_WIDGET (box->item_box), GTK_TYPE_STACK, &stack, &parent);
|
||||
gtk_container_child_get (GTK_CONTAINER (stack), parent, "name", &name, NULL);
|
||||
gtk_menu_section_box_new_submenu (item, box->toplevel, widget, name);
|
||||
g_free (name);
|
||||
}
|
||||
else
|
||||
{
|
||||
widget = gtk_model_button_new ();
|
||||
|
||||
g_object_bind_property (item, "label", widget, "text", G_BINDING_SYNC_CREATE);
|
||||
|
||||
if (box->iconic)
|
||||
@@ -276,10 +277,8 @@ gtk_menu_section_box_insert_func (GtkMenuTrackerItem *item,
|
||||
g_object_bind_property (item, "icon", widget, "icon", G_BINDING_SYNC_CREATE);
|
||||
|
||||
g_object_bind_property (item, "sensitive", widget, "sensitive", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (item, "role", widget, "action-role", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (item, "toggled", widget, "toggled", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (item, "accel", widget, "accel", G_BINDING_SYNC_CREATE);
|
||||
|
||||
g_object_bind_property (item, "role", widget, "role", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (item, "toggled", widget, "active", G_BINDING_SYNC_CREATE);
|
||||
g_signal_connect (widget, "clicked", G_CALLBACK (gtk_popover_item_activate), item);
|
||||
}
|
||||
|
||||
@@ -367,10 +366,11 @@ gtk_menu_section_box_new_toplevel (GtkStack *stack,
|
||||
gtk_widget_show (GTK_WIDGET (box));
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
|
||||
GtkMenuSectionBox *toplevel,
|
||||
GtkWidget *focus)
|
||||
GtkWidget *focus,
|
||||
const gchar *name)
|
||||
{
|
||||
GtkMenuSectionBox *box;
|
||||
GtkWidget *button;
|
||||
@@ -378,10 +378,11 @@ gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
|
||||
box = g_object_new (GTK_TYPE_MENU_SECTION_BOX, "margin", 10, NULL);
|
||||
|
||||
button = g_object_new (GTK_TYPE_MODEL_BUTTON,
|
||||
"has-submenu", TRUE,
|
||||
"menu-name", name,
|
||||
"inverted", TRUE,
|
||||
"centered", TRUE,
|
||||
NULL);
|
||||
|
||||
g_object_bind_property (item, "label", button, "text", G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (item, "icon", button, "icon", G_BINDING_SYNC_CREATE);
|
||||
|
||||
@@ -404,7 +405,7 @@ gtk_menu_section_box_new_submenu (GtkMenuTrackerItem *item,
|
||||
box);
|
||||
}
|
||||
|
||||
GtkWidget *
|
||||
static GtkWidget *
|
||||
gtk_menu_section_box_new_section (GtkMenuTrackerItem *item,
|
||||
GtkMenuSectionBox *parent)
|
||||
{
|
||||
|
@@ -31,19 +31,53 @@
|
||||
#include "gtkrender.h"
|
||||
#include "gtkstylecontext.h"
|
||||
#include "gtktypebuiltins.h"
|
||||
#include "gtkstack.h"
|
||||
#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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
struct _GtkModelButton
|
||||
{
|
||||
GtkButton parent_instance;
|
||||
|
||||
GtkWidget *box;
|
||||
GtkWidget *image;
|
||||
GtkWidget *label;
|
||||
gboolean toggled;
|
||||
gboolean has_submenu;
|
||||
gboolean active;
|
||||
gboolean centered;
|
||||
gboolean inverted;
|
||||
gboolean iconic;
|
||||
GtkMenuTrackerItemRole role;
|
||||
gchar *menu_name;
|
||||
GtkButtonRole role;
|
||||
};
|
||||
|
||||
typedef GtkButtonClass GtkModelButtonClass;
|
||||
@@ -53,20 +87,41 @@ G_DEFINE_TYPE (GtkModelButton, gtk_model_button, GTK_TYPE_BUTTON)
|
||||
enum
|
||||
{
|
||||
PROP_0,
|
||||
PROP_ACTION_ROLE,
|
||||
PROP_ROLE,
|
||||
PROP_ICON,
|
||||
PROP_TEXT,
|
||||
PROP_TOGGLED,
|
||||
PROP_ACCEL,
|
||||
PROP_HAS_SUBMENU,
|
||||
PROP_ACTIVE,
|
||||
PROP_MENU_NAME,
|
||||
PROP_INVERTED,
|
||||
PROP_CENTERED,
|
||||
PROP_ICONIC
|
||||
PROP_ICONIC,
|
||||
LAST_PROPERTY
|
||||
};
|
||||
|
||||
static GParamSpec *properties[LAST_PROPERTY] = { NULL, };
|
||||
|
||||
static void
|
||||
gtk_model_button_set_action_role (GtkModelButton *button,
|
||||
GtkMenuTrackerItemRole role)
|
||||
gtk_model_button_update_state (GtkModelButton *button)
|
||||
{
|
||||
GtkStateFlags state;
|
||||
|
||||
if (button->role == GTK_BUTTON_ROLE_NORMAL)
|
||||
return;
|
||||
|
||||
state = gtk_widget_get_state_flags (GTK_WIDGET (button));
|
||||
|
||||
state &= ~GTK_STATE_FLAG_CHECKED;
|
||||
|
||||
if (button->active && !button->menu_name)
|
||||
state |= GTK_STATE_FLAG_CHECKED;
|
||||
|
||||
gtk_widget_set_state_flags (GTK_WIDGET (button), state, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_model_button_set_role (GtkModelButton *button,
|
||||
GtkButtonRole role)
|
||||
{
|
||||
AtkObject *accessible;
|
||||
AtkRole a11y_role;
|
||||
@@ -75,20 +130,19 @@ gtk_model_button_set_action_role (GtkModelButton *button,
|
||||
return;
|
||||
|
||||
button->role = role;
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
|
||||
accessible = gtk_widget_get_accessible (GTK_WIDGET (button));
|
||||
switch (role)
|
||||
{
|
||||
case GTK_MENU_TRACKER_ITEM_ROLE_NORMAL:
|
||||
case GTK_BUTTON_ROLE_NORMAL:
|
||||
a11y_role = ATK_ROLE_PUSH_BUTTON;
|
||||
break;
|
||||
|
||||
case GTK_MENU_TRACKER_ITEM_ROLE_CHECK:
|
||||
case GTK_BUTTON_ROLE_CHECK:
|
||||
a11y_role = ATK_ROLE_CHECK_BOX;
|
||||
break;
|
||||
|
||||
case GTK_MENU_TRACKER_ITEM_ROLE_RADIO:
|
||||
case GTK_BUTTON_ROLE_RADIO:
|
||||
a11y_role = ATK_ROLE_RADIO_BUTTON;
|
||||
break;
|
||||
|
||||
@@ -97,6 +151,10 @@ gtk_model_button_set_action_role (GtkModelButton *button,
|
||||
}
|
||||
|
||||
atk_object_set_role (accessible, a11y_role);
|
||||
|
||||
gtk_model_button_update_state (button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_ROLE]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -118,6 +176,7 @@ gtk_model_button_set_icon (GtkModelButton *button,
|
||||
{
|
||||
gtk_image_set_from_gicon (GTK_IMAGE (button->image), icon, GTK_ICON_SIZE_MENU);
|
||||
update_visibility (button);
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_ICON]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -126,64 +185,56 @@ gtk_model_button_set_text (GtkModelButton *button,
|
||||
{
|
||||
gtk_label_set_text_with_mnemonic (GTK_LABEL (button->label), text);
|
||||
update_visibility (button);
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_TEXT]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_model_button_set_accel (GtkModelButton *button,
|
||||
const gchar *accel)
|
||||
gtk_model_button_set_active (GtkModelButton *button,
|
||||
gboolean active)
|
||||
{
|
||||
/* ignore */
|
||||
}
|
||||
if (button->active == active)
|
||||
return;
|
||||
|
||||
static void
|
||||
gtk_model_button_update_state (GtkModelButton *button)
|
||||
{
|
||||
GtkStateFlags state;
|
||||
|
||||
state = gtk_widget_get_state_flags (GTK_WIDGET (button));
|
||||
|
||||
state &= ~GTK_STATE_FLAG_CHECKED;
|
||||
|
||||
if (button->toggled && !button->has_submenu)
|
||||
state |= GTK_STATE_FLAG_CHECKED;
|
||||
|
||||
gtk_widget_set_state_flags (GTK_WIDGET (button), state, TRUE);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
gtk_model_button_set_toggled (GtkModelButton *button,
|
||||
gboolean toggled)
|
||||
{
|
||||
button->toggled = toggled;
|
||||
button->active = active;
|
||||
gtk_model_button_update_state (button);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_ACTIVE]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_model_button_set_has_submenu (GtkModelButton *button,
|
||||
gboolean has_submenu)
|
||||
gtk_model_button_set_menu_name (GtkModelButton *button,
|
||||
const gchar *menu_name)
|
||||
{
|
||||
button->has_submenu = has_submenu;
|
||||
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));
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_MENU_NAME]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_model_button_set_inverted (GtkModelButton *button,
|
||||
gboolean inverted)
|
||||
{
|
||||
if (button->inverted == inverted)
|
||||
return;
|
||||
|
||||
button->inverted = inverted;
|
||||
gtk_widget_queue_resize (GTK_WIDGET (button));
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_INVERTED]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_model_button_set_centered (GtkModelButton *button,
|
||||
gboolean centered)
|
||||
{
|
||||
if (button->centered == centered)
|
||||
return;
|
||||
|
||||
button->centered = centered;
|
||||
gtk_widget_set_halign (button->box, button->centered ? GTK_ALIGN_CENTER : GTK_ALIGN_FILL);
|
||||
gtk_widget_queue_draw (GTK_WIDGET (button));
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_CENTERED]);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -192,6 +243,9 @@ gtk_model_button_set_iconic (GtkModelButton *button,
|
||||
{
|
||||
GtkStyleContext *context;
|
||||
|
||||
if (button->iconic == iconic)
|
||||
return;
|
||||
|
||||
button->iconic = iconic;
|
||||
|
||||
context = gtk_widget_get_style_context (GTK_WIDGET (button));
|
||||
@@ -210,6 +264,58 @@ gtk_model_button_set_iconic (GtkModelButton *button,
|
||||
|
||||
update_visibility (button);
|
||||
gtk_widget_queue_resize (GTK_WIDGET (button));
|
||||
g_object_notify_by_pspec (G_OBJECT (button), properties[PROP_ICONIC]);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_model_button_get_property (GObject *object,
|
||||
guint prop_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkModelButton *button = GTK_MODEL_BUTTON (object);
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ROLE:
|
||||
g_value_set_enum (value, button->role);
|
||||
break;
|
||||
|
||||
case PROP_ICON:
|
||||
{
|
||||
GIcon *icon;
|
||||
gtk_image_get_gicon (GTK_IMAGE (button->image), &icon, NULL);
|
||||
g_value_set_object (value, icon);
|
||||
}
|
||||
break;
|
||||
|
||||
case PROP_TEXT:
|
||||
g_value_set_string (value, gtk_label_get_text (GTK_LABEL (button->label)));
|
||||
break;
|
||||
|
||||
case PROP_ACTIVE:
|
||||
g_value_set_boolean (value, button->active);
|
||||
break;
|
||||
|
||||
case PROP_MENU_NAME:
|
||||
g_value_set_string (value, button->menu_name);
|
||||
break;
|
||||
|
||||
case PROP_INVERTED:
|
||||
g_value_set_boolean (value, button->inverted);
|
||||
break;
|
||||
|
||||
case PROP_CENTERED:
|
||||
g_value_set_boolean (value, button->centered);
|
||||
break;
|
||||
|
||||
case PROP_ICONIC:
|
||||
g_value_set_boolean (value, button->iconic);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -222,8 +328,8 @@ gtk_model_button_set_property (GObject *object,
|
||||
|
||||
switch (prop_id)
|
||||
{
|
||||
case PROP_ACTION_ROLE:
|
||||
gtk_model_button_set_action_role (button, g_value_get_enum (value));
|
||||
case PROP_ROLE:
|
||||
gtk_model_button_set_role (button, g_value_get_enum (value));
|
||||
break;
|
||||
|
||||
case PROP_ICON:
|
||||
@@ -234,16 +340,12 @@ gtk_model_button_set_property (GObject *object,
|
||||
gtk_model_button_set_text (button, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_TOGGLED:
|
||||
gtk_model_button_set_toggled (button, g_value_get_boolean (value));
|
||||
case PROP_ACTIVE:
|
||||
gtk_model_button_set_active (button, g_value_get_boolean (value));
|
||||
break;
|
||||
|
||||
case PROP_ACCEL:
|
||||
gtk_model_button_set_accel (button, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_HAS_SUBMENU:
|
||||
gtk_model_button_set_has_submenu (button, g_value_get_boolean (value));
|
||||
case PROP_MENU_NAME:
|
||||
gtk_model_button_set_menu_name (button, g_value_get_string (value));
|
||||
break;
|
||||
|
||||
case PROP_INVERTED:
|
||||
@@ -311,7 +413,7 @@ has_sibling_with_indicator (GtkWidget *button)
|
||||
continue;
|
||||
|
||||
if (!sibling->centered &&
|
||||
(sibling->has_submenu || sibling->role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL))
|
||||
(sibling->menu_name || sibling->role != GTK_BUTTON_ROLE_NORMAL))
|
||||
{
|
||||
has_indicator = TRUE;
|
||||
break;
|
||||
@@ -326,7 +428,7 @@ has_sibling_with_indicator (GtkWidget *button)
|
||||
static gboolean
|
||||
needs_indicator (GtkModelButton *button)
|
||||
{
|
||||
if (button->role != GTK_MENU_TRACKER_ITEM_ROLE_NORMAL)
|
||||
if (button->role != GTK_BUTTON_ROLE_NORMAL)
|
||||
return TRUE;
|
||||
|
||||
return has_sibling_with_indicator (GTK_WIDGET (button));
|
||||
@@ -388,12 +490,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;
|
||||
@@ -570,9 +672,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);
|
||||
@@ -603,7 +703,7 @@ gtk_model_button_draw (GtkWidget *widget,
|
||||
width - 2 * border_width,
|
||||
height - 2 * border_width);
|
||||
|
||||
if (model_button->has_submenu)
|
||||
if (model_button->menu_name)
|
||||
{
|
||||
GtkStateFlags state;
|
||||
|
||||
@@ -620,14 +720,14 @@ gtk_model_button_draw (GtkWidget *widget,
|
||||
gtk_render_expander (context, cr, x, y, indicator_size, indicator_size);
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else if (model_button->role == GTK_MENU_TRACKER_ITEM_ROLE_CHECK)
|
||||
else if (model_button->role == GTK_BUTTON_ROLE_CHECK)
|
||||
{
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_CHECK);
|
||||
gtk_render_check (context, cr, x, y, indicator_size, indicator_size);
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
else if (model_button->role == GTK_MENU_TRACKER_ITEM_ROLE_RADIO)
|
||||
else if (model_button->role == GTK_BUTTON_ROLE_RADIO)
|
||||
{
|
||||
gtk_style_context_save (context);
|
||||
gtk_style_context_add_class (context, GTK_STYLE_CLASS_RADIO);
|
||||
@@ -655,12 +755,36 @@ 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_BUTTON_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;
|
||||
|
||||
widget_class->get_preferred_width = gtk_model_button_get_preferred_width;
|
||||
@@ -671,36 +795,131 @@ gtk_model_button_class_init (GtkModelButtonClass *class)
|
||||
widget_class->size_allocate = gtk_model_button_size_allocate;
|
||||
widget_class->draw = gtk_model_button_draw;
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ACTION_ROLE,
|
||||
g_param_spec_enum ("action-role", "", "",
|
||||
GTK_TYPE_MENU_TRACKER_ITEM_ROLE,
|
||||
GTK_MENU_TRACKER_ITEM_ROLE_NORMAL,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_ICON,
|
||||
g_param_spec_object ("icon", "", "", G_TYPE_ICON,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_TEXT,
|
||||
g_param_spec_string ("text", "", "", NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_TOGGLED,
|
||||
g_param_spec_boolean ("toggled", "", "", FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_ACCEL,
|
||||
g_param_spec_string ("accel", "", "", NULL,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
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_INVERTED,
|
||||
g_param_spec_boolean ("inverted", "", "", FALSE,
|
||||
button_class->clicked = gtk_model_button_clicked;
|
||||
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_CENTERED,
|
||||
g_param_spec_boolean ("centered", "", "", FALSE,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
g_object_class_install_property (object_class, PROP_ICONIC,
|
||||
g_param_spec_boolean ("iconic", "", "", TRUE,
|
||||
G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
|
||||
/**
|
||||
* 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"),
|
||||
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_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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
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"),
|
||||
TRUE,
|
||||
G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
|
||||
g_object_class_install_properties (object_class, LAST_PROPERTY, properties);
|
||||
|
||||
gtk_widget_class_set_accessible_role (GTK_WIDGET_CLASS (class), ATK_ROLE_PUSH_BUTTON);
|
||||
}
|
||||
@@ -710,12 +929,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 ();
|
||||
|
@@ -20,21 +20,41 @@
|
||||
#ifndef __GTK_MODEL_BUTTON_H__
|
||||
#define __GTK_MODEL_BUTTON_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkwidget.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_MODEL_BUTTON (gtk_model_button_get_type ())
|
||||
#define GTK_MODEL_BUTTON(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||
GTK_TYPE_MODEL_BUTTON, GtkModelButton))
|
||||
#define GTK_IS_MODEL_BUTTON(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
GTK_TYPE_MODEL_BUTTON))
|
||||
#define GTK_TYPE_MODEL_BUTTON (gtk_model_button_get_type ())
|
||||
#define GTK_MODEL_BUTTON(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
|
||||
GTK_TYPE_MODEL_BUTTON, GtkModelButton))
|
||||
#define GTK_IS_MODEL_BUTTON(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
|
||||
GTK_TYPE_MODEL_BUTTON))
|
||||
|
||||
typedef struct _GtkModelButton GtkModelButton;
|
||||
typedef struct _GtkModelButton GtkModelButton;
|
||||
|
||||
GType gtk_model_button_get_type (void) G_GNUC_CONST;
|
||||
/**
|
||||
* 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,
|
||||
GTK_BUTTON_ROLE_RADIO
|
||||
} GtkButtonRole;
|
||||
|
||||
GtkWidget * gtk_model_button_new (void);
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
GType gtk_model_button_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
GtkWidget * gtk_model_button_new (void);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
259
gtk/gtkpopovermenu.c
Normal file
259
gtk/gtkpopovermenu.c
Normal file
@@ -0,0 +1,259 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
#include "gtkpopovermenu.h"
|
||||
#include "gtkstack.h"
|
||||
#include "gtkbox.h"
|
||||
#include "gtkintl.h"
|
||||
|
||||
|
||||
/**
|
||||
* SECTION:gtkpopovermenu
|
||||
* @Short_description: Popovers to use as menus
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
struct _GtkPopoverMenu
|
||||
{
|
||||
GtkPopover parent_instance;
|
||||
};
|
||||
|
||||
enum {
|
||||
CHILD_PROP_SUBMENU = 1
|
||||
};
|
||||
|
||||
G_DEFINE_TYPE (GtkPopoverMenu, gtk_popover_menu, GTK_TYPE_POPOVER)
|
||||
|
||||
static void
|
||||
gtk_popover_menu_init (GtkPopoverMenu *popover)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
|
||||
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_widget_show (stack);
|
||||
gtk_container_add (GTK_CONTAINER (popover), stack);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_menu_map (GtkWidget *widget)
|
||||
{
|
||||
GTK_WIDGET_CLASS (gtk_popover_menu_parent_class)->map (widget);
|
||||
gtk_popover_menu_open_submenu (GTK_POPOVER_MENU (widget), "main");
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_menu_unmap (GtkWidget *widget)
|
||||
{
|
||||
gtk_popover_menu_open_submenu (GTK_POPOVER_MENU (widget), "main");
|
||||
GTK_WIDGET_CLASS (gtk_popover_menu_parent_class)->unmap (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_menu_add (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
|
||||
stack = gtk_bin_get_child (GTK_BIN (container));
|
||||
|
||||
if (stack == NULL)
|
||||
{
|
||||
gtk_widget_set_parent (child, GTK_WIDGET (container));
|
||||
_gtk_bin_set_child (GTK_BIN (container), child);
|
||||
}
|
||||
else
|
||||
{
|
||||
gchar *name;
|
||||
|
||||
if (gtk_stack_get_child_by_name (GTK_STACK (stack), "main"))
|
||||
name = "submenu";
|
||||
else
|
||||
name = "main";
|
||||
|
||||
gtk_stack_add_named (GTK_STACK (stack), child, name);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_menu_remove (GtkContainer *container,
|
||||
GtkWidget *child)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
|
||||
stack = gtk_bin_get_child (GTK_BIN (container));
|
||||
|
||||
if (child == stack)
|
||||
GTK_CONTAINER_CLASS (gtk_popover_menu_parent_class)->remove (container, child);
|
||||
else
|
||||
gtk_container_remove (GTK_CONTAINER (stack), child);
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_menu_get_child_property (GtkContainer *container,
|
||||
GtkWidget *child,
|
||||
guint property_id,
|
||||
GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
|
||||
stack = gtk_bin_get_child (GTK_BIN (container));
|
||||
|
||||
if (child == stack)
|
||||
return;
|
||||
|
||||
switch (property_id)
|
||||
|
||||
{
|
||||
case CHILD_PROP_SUBMENU:
|
||||
{
|
||||
gchar *name;
|
||||
gtk_container_child_get (GTK_CONTAINER (stack), child, "name", &name, NULL);
|
||||
g_value_set_string (value, name);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_menu_set_child_property (GtkContainer *container,
|
||||
GtkWidget *child,
|
||||
guint property_id,
|
||||
const GValue *value,
|
||||
GParamSpec *pspec)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
|
||||
stack = gtk_bin_get_child (GTK_BIN (container));
|
||||
|
||||
if (child == stack)
|
||||
return;
|
||||
|
||||
switch (property_id)
|
||||
{
|
||||
case CHILD_PROP_SUBMENU:
|
||||
{
|
||||
const gchar *name;
|
||||
name = g_value_get_string (value);
|
||||
gtk_container_child_set (GTK_CONTAINER (stack), child, "name", name, NULL);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
GTK_CONTAINER_WARN_INVALID_CHILD_PROPERTY_ID (container, property_id, pspec);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
gtk_popover_menu_class_init (GtkPopoverMenuClass *klass)
|
||||
{
|
||||
GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
|
||||
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
||||
|
||||
widget_class->map = gtk_popover_menu_map;
|
||||
widget_class->unmap = gtk_popover_menu_unmap;
|
||||
|
||||
container_class->add = gtk_popover_menu_add;
|
||||
container_class->remove = gtk_popover_menu_remove;
|
||||
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",
|
||||
P_("Submenu"),
|
||||
P_("The name of the submenu"),
|
||||
NULL,
|
||||
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)
|
||||
{
|
||||
return g_object_new (GTK_TYPE_POPOVER_MENU, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* gtk_popover_menu_open_submenu:
|
||||
* @popover: a #GtkPopoverMenu
|
||||
* @name: the name of the menu to switch to
|
||||
*
|
||||
* Opens a submenu of the @popover. The @name
|
||||
* must be one of the names given to the submenus
|
||||
* of @popover with #GtkPopoverMenu:submenu, or
|
||||
* "main" to switch back to the main menu.
|
||||
*
|
||||
* #GtkModelButton will open submenus automatically
|
||||
* when the #GtkModelButton:menu-name property is set,
|
||||
* so this function is only needed when you are using
|
||||
* other kinds of widgets to initiate menu changes.
|
||||
*
|
||||
* Since: 3.16
|
||||
*/
|
||||
void
|
||||
gtk_popover_menu_open_submenu (GtkPopoverMenu *popover,
|
||||
const gchar *name)
|
||||
{
|
||||
GtkWidget *stack;
|
||||
|
||||
g_return_if_fail (GTK_IS_POPOVER_MENU (popover));
|
||||
|
||||
stack = gtk_bin_get_child (GTK_BIN (popover));
|
||||
gtk_stack_set_visible_child_name (GTK_STACK (stack), name);
|
||||
}
|
62
gtk/gtkpopovermenu.h
Normal file
62
gtk/gtkpopovermenu.h
Normal file
@@ -0,0 +1,62 @@
|
||||
/* GTK - The GIMP Toolkit
|
||||
* Copyright © 2014 Red Hat, Inc.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef __GTK_POPOVER_MENU_H__
|
||||
#define __GTK_POPOVER_MENU_H__
|
||||
|
||||
#if !defined (__GTK_H_INSIDE__) && !defined (GTK_COMPILATION)
|
||||
#error "Only <gtk/gtk.h> can be included directly."
|
||||
#endif
|
||||
|
||||
#include <gtk/gtkpopover.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define GTK_TYPE_POPOVER_MENU (gtk_popover_menu_get_type ())
|
||||
#define GTK_POPOVER_MENU(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GTK_TYPE_POPOVER_MENU, GtkPopoverMenu))
|
||||
#define GTK_POPOVER_MENU_CLASS(c) (G_TYPE_CHECK_CLASS_CAST ((c), GTK_TYPE_POPOVER_MENU, GtkPopoverMenuClass))
|
||||
#define GTK_IS_POPOVER_MENU(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GTK_TYPE_POPOVER_MENU))
|
||||
#define GTK_IS_POPOVER_MENU_CLASS(o) (G_TYPE_CHECK_CLASS_TYPE ((o), GTK_TYPE_POPOVER_MENU))
|
||||
#define GTK_POPOVER_MENU_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GTK_TYPE_POPOVER_MENU, GtkPopoverMenuClass))
|
||||
|
||||
typedef struct _GtkPopoverMenu GtkPopoverMenu;
|
||||
typedef struct _GtkPopoverMenuClass GtkPopoverMenuClass;
|
||||
|
||||
struct _GtkPopoverMenuClass
|
||||
{
|
||||
GtkPopoverClass parent_class;
|
||||
|
||||
/*< private >*/
|
||||
|
||||
/* Padding for future expansion */
|
||||
gpointer reserved[10];
|
||||
};
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
GType gtk_popover_menu_get_type (void) G_GNUC_CONST;
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
GtkWidget * gtk_popover_menu_new (void);
|
||||
|
||||
GDK_AVAILABLE_IN_3_16
|
||||
void gtk_popover_menu_open_submenu (GtkPopoverMenu *popover,
|
||||
const gchar *name);
|
||||
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* __GTK_POPOVER_MENU_H__ */
|
@@ -21,6 +21,7 @@ LDADD = \
|
||||
$(GDK_DEP_LIBS) \
|
||||
-lm
|
||||
|
||||
|
||||
if USE_X11
|
||||
testsocket_programs = testsocket testsocket_child
|
||||
endif
|
||||
|
569
tests/popover2.ui
Normal file
569
tests/popover2.ui
Normal file
@@ -0,0 +1,569 @@
|
||||
<?xml version="1.0"?>
|
||||
<interface>
|
||||
<object class="GtkPopoverMenu" id="popover">
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">10</property>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">Edit</property>
|
||||
<style>
|
||||
<class name="separator"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.cut</property>
|
||||
<property name="text">Cut</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.copy</property>
|
||||
<property name="text">Copy</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.paste</property>
|
||||
<property name="text">Paste</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">3</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">action1</property>
|
||||
<property name="text">No action</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action2</property>
|
||||
<property name="text">Toggle</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action2a</property>
|
||||
<property name="text">Another Toggle</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">Middle Section</property>
|
||||
<style>
|
||||
<class name="separator"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action3</property>
|
||||
<property name="action-target">'three'</property>
|
||||
<property name="text">Radio 1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action3</property>
|
||||
<property name="action-target">'four'</property>
|
||||
<property name="text">Radio 2</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Submenu 1</property>
|
||||
<property name="menu-name">submenu1</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Submenu 2</property>
|
||||
<property name="menu-name">submenu2</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">End Section</property>
|
||||
<style>
|
||||
<class name="separator"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action9</property>
|
||||
<property name="text">Another Item 9</property>
|
||||
<property name="icon">icon9</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action10</property>
|
||||
<property name="text">Another Item 10</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">10</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Submenu 1</property>
|
||||
<property name="inverted">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="menu-name">main</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">5555</property>
|
||||
<style>
|
||||
<class name="separator"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action5</property>
|
||||
<property name="text">Item 5</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action5</property>
|
||||
<property name="text">Item 5a</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action5</property>
|
||||
<property name="text">Item 5b</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="margin-top">10</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">List</property>
|
||||
<property name="action-name">top.set-view</property>
|
||||
<property name="action-target">'list'</property>
|
||||
<property name="iconic">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="icon">icon-list</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Grid</property>
|
||||
<property name="action-name">top.set-view</property>
|
||||
<property name="action-target">'grid'</property>
|
||||
<property name="iconic">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="icon">icon-grid</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action5</property>
|
||||
<property name="text">Item 5c</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action5</property>
|
||||
<property name="text">Item 5d</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">Format</property>
|
||||
<style>
|
||||
<class name="separator"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="halign">fill</property>
|
||||
<property name="margin-top">10</property>
|
||||
<style>
|
||||
<class name="linked"/>
|
||||
</style>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Bold</property>
|
||||
<property name="action-name">top.bold</property>
|
||||
<property name="iconic">True</property>
|
||||
<property name="centered">True</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Italic</property>
|
||||
<property name="action-name">top.italic</property>
|
||||
<property name="iconic">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="icon">icon-italic</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Strikethrough</property>
|
||||
<property name="action-name">top.strikethrough</property>
|
||||
<property name="iconic">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="icon">icon-strikethrough</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Underline</property>
|
||||
<property name="action-name">top.underline</property>
|
||||
<property name="iconic">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="icon">icon-underline</property>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="expand">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">6</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
<child>
|
||||
<object class="GtkLabel">
|
||||
<property name="visible">True</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="label">6666</property>
|
||||
<style>
|
||||
<class name="separator"/>
|
||||
</style>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action6</property>
|
||||
<property name="text">Item 6</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action6</property>
|
||||
<property name="text">Item 6a</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action6</property>
|
||||
<property name="text">Item 6b</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action6</property>
|
||||
<property name="text">Item 6c</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action6</property>
|
||||
<property name="text">Item 6d</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="submenu">submenu1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">10</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Submenu 2</property>
|
||||
<property name="inverted">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="menu-name">main</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action7</property>
|
||||
<property name="text">Item 7</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkScale">
|
||||
<property name="visible">True</property>
|
||||
<property name="draw-value">False</property>
|
||||
<property name="adjustment">adjustment</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Subsubmenu</property>
|
||||
<property name="icon">icon9</property>
|
||||
<property name="menu-name">subsubmenu</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="submenu">submenu2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">vertical</property>
|
||||
<property name="margin">10</property>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="text">Subsubmenu</property>
|
||||
<property name="inverted">True</property>
|
||||
<property name="centered">True</property>
|
||||
<property name="menu-name">submenu2</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">action8</property>
|
||||
<property name="text">Item 8</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkSeparator">
|
||||
<property name="visible">True</property>
|
||||
<property name="orientation">horizontal</property>
|
||||
<property name="margin-start">12</property>
|
||||
<property name="margin-end">12</property>
|
||||
<property name="margin-top">3</property>
|
||||
<property name="margin-bottom">3</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action9</property>
|
||||
<property name="text">Item 9</property>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkModelButton">
|
||||
<property name="visible">True</property>
|
||||
<property name="action-name">top.action10</property>
|
||||
<property name="text">Item 10</property>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
<packing>
|
||||
<property name="submenu">subsubmenu</property>
|
||||
</packing>
|
||||
</child>
|
||||
</object>
|
||||
<object class="GThemedIcon" id="icon9">
|
||||
<property name="name">preferences-desktop-font</property>
|
||||
</object>
|
||||
<object class="GThemedIcon" id="icon-grid">
|
||||
<property name="name">view-grid-symbolic</property>
|
||||
</object>
|
||||
<object class="GThemedIcon" id="icon-list">
|
||||
<property name="name">view-list-symbolic</property>
|
||||
</object>
|
||||
<object class="GThemedIcon" id="icon-italic">
|
||||
<property name="name">format-text-italic-symbolic</property>
|
||||
</object>
|
||||
<object class="GThemedIcon" id="icon-strikethrough">
|
||||
<property name="name">format-text-strikethrough-symbolic</property>
|
||||
</object>
|
||||
<object class="GThemedIcon" id="icon-underline">
|
||||
<property name="name">format-text-underline-symbolic</property>
|
||||
</object>
|
||||
<object class="GtkAdjustment" id="adjustment">
|
||||
<property name="lower">0</property>
|
||||
<property name="upper">100</property>
|
||||
<property name="value">50</property>
|
||||
</object>
|
||||
</interface>
|
@@ -30,16 +30,20 @@ static GActionEntry entries[] = {
|
||||
{ "action10", activate, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
int main (int argc, char *argv[])
|
||||
int
|
||||
main (int argc, char *argv[])
|
||||
{
|
||||
GtkWidget *win;
|
||||
GtkWidget *box;
|
||||
GtkWidget *button;
|
||||
GtkWidget *button2;
|
||||
GtkBuilder *builder;
|
||||
GMenuModel *model;
|
||||
GSimpleActionGroup *actions;
|
||||
GtkWidget *overlay;
|
||||
GtkWidget *grid;
|
||||
GtkWidget *popover;
|
||||
GtkWidget *popover2;
|
||||
GtkWidget *label;
|
||||
GtkWidget *check;
|
||||
GtkWidget *combo;
|
||||
@@ -76,30 +80,36 @@ int main (int argc, char *argv[])
|
||||
builder = gtk_builder_new_from_file ("popover.ui");
|
||||
model = (GMenuModel *)gtk_builder_get_object (builder, "menu");
|
||||
|
||||
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
||||
button = gtk_menu_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (box), button);
|
||||
button2 = gtk_menu_button_new ();
|
||||
gtk_container_add (GTK_CONTAINER (box), button2);
|
||||
|
||||
gtk_menu_button_set_menu_model (GTK_MENU_BUTTON (button), model);
|
||||
gtk_menu_button_set_use_popover (GTK_MENU_BUTTON (button), TRUE);
|
||||
|
||||
popover = GTK_WIDGET (gtk_menu_button_get_popover (GTK_MENU_BUTTON (button)));
|
||||
|
||||
g_object_set (button, "margin", 10, NULL);
|
||||
gtk_widget_set_halign (button, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (button, GTK_ALIGN_START);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), button);
|
||||
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);
|
||||
|
||||
g_object_set (box, "margin", 10, NULL);
|
||||
gtk_widget_set_halign (box, GTK_ALIGN_END);
|
||||
gtk_widget_set_valign (box, GTK_ALIGN_START);
|
||||
gtk_overlay_add_overlay (GTK_OVERLAY (overlay), box);
|
||||
|
||||
label = gtk_label_new ("Popover hexpand");
|
||||
check = gtk_check_button_new ();
|
||||
g_object_bind_property (popover, "hexpand",
|
||||
check, "active",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (check, "active", popover, "hexpand", G_BINDING_DEFAULT);
|
||||
g_object_bind_property (check, "active", popover2, "hexpand", G_BINDING_DEFAULT);
|
||||
gtk_grid_attach (GTK_GRID (grid), label , 1, 1, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), check, 2, 1, 1, 1);
|
||||
|
||||
label = gtk_label_new ("Popover vexpand");
|
||||
check = gtk_check_button_new ();
|
||||
g_object_bind_property (popover, "vexpand",
|
||||
check, "active",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (check, "active", popover, "vexpand", G_BINDING_DEFAULT);
|
||||
g_object_bind_property (check, "active", popover2, "vexpand", G_BINDING_DEFAULT);
|
||||
gtk_grid_attach (GTK_GRID (grid), label , 1, 2, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), check, 2, 2, 1, 1);
|
||||
|
||||
@@ -110,9 +120,8 @@ int main (int argc, char *argv[])
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "left", "Left");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "right", "Right");
|
||||
|
||||
g_object_bind_property (button, "direction",
|
||||
combo, "active",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (combo, "active", button, "direction", G_BINDING_DEFAULT);
|
||||
g_object_bind_property (combo, "active", button2, "direction", G_BINDING_DEFAULT);
|
||||
gtk_grid_attach (GTK_GRID (grid), label , 1, 3, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), combo, 2, 3, 1, 1);
|
||||
|
||||
@@ -122,9 +131,7 @@ int main (int argc, char *argv[])
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "start", "Start");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "end", "End");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center", "Center");
|
||||
g_object_bind_property (button, "halign",
|
||||
combo, "active",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (combo, "active", box, "halign", G_BINDING_DEFAULT);
|
||||
gtk_grid_attach (GTK_GRID (grid), label , 1, 4, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), combo, 2, 4, 1, 1);
|
||||
|
||||
@@ -134,9 +141,7 @@ int main (int argc, char *argv[])
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "start", "Start");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "end", "End");
|
||||
gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (combo), "center", "Center");
|
||||
g_object_bind_property (button, "valign",
|
||||
combo, "active",
|
||||
G_BINDING_BIDIRECTIONAL | G_BINDING_SYNC_CREATE);
|
||||
g_object_bind_property (combo, "active", box, "valign", G_BINDING_DEFAULT);
|
||||
gtk_grid_attach (GTK_GRID (grid), label , 1, 5, 1, 1);
|
||||
gtk_grid_attach (GTK_GRID (grid), combo, 2, 5, 1, 1);
|
||||
|
||||
|
Reference in New Issue
Block a user