[gtk/kill-tree-menu: 13/51] toolbar: Simplify overflow implementation
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/kill-tree-menu: 13/51] toolbar: Simplify overflow implementation
- Date: Sun, 29 Dec 2019 22:14:33 +0000 (UTC)
commit da77f77b2b38ac8c1389b4676a0f7acdd5ed7cbf
Author: Matthias Clasen <mclasen redhat com>
Date: Fri Dec 27 01:32:27 2019 -0500
toolbar: Simplify overflow implementation
Do away with the proxy menu items, and instead
just have toolitems provide a label for overflow
items. We create the overflow widgets ourselves
already, as model buttons.
Also replace the toggle button used for overflow
with a menubutton, simplifying things further.
docs/reference/gtk/gtk4-sections.txt | 5 +-
gtk/gtkseparatortoolitem.c | 17 ---
gtk/gtktoggletoolbutton.c | 104 ------------------
gtk/gtktoolbar.c | 196 +++++++++-------------------------
gtk/gtktoolbutton.c | 94 ++--------------
gtk/gtktoolitem.c | 200 ++++++-----------------------------
gtk/gtktoolitem.h | 14 +--
7 files changed, 98 insertions(+), 532 deletions(-)
---
diff --git a/docs/reference/gtk/gtk4-sections.txt b/docs/reference/gtk/gtk4-sections.txt
index 698e116302..0c9fa7dc4e 100644
--- a/docs/reference/gtk/gtk4-sections.txt
+++ b/docs/reference/gtk/gtk4-sections.txt
@@ -3278,9 +3278,8 @@ gtk_tool_item_get_orientation
gtk_tool_item_get_toolbar_style
gtk_tool_item_get_text_alignment
gtk_tool_item_get_text_orientation
-gtk_tool_item_retrieve_proxy_menu_item
-gtk_tool_item_get_proxy_menu_item
-gtk_tool_item_set_proxy_menu_item
+gtk_tool_item_set_overflow_text
+gtk_tool_item_get_overflow_text
gtk_tool_item_rebuild_menu
gtk_tool_item_toolbar_reconfigured
gtk_tool_item_get_text_size_group
diff --git a/gtk/gtkseparatortoolitem.c b/gtk/gtkseparatortoolitem.c
index a51e5ef9d7..d85ab09891 100644
--- a/gtk/gtkseparatortoolitem.c
+++ b/gtk/gtkseparatortoolitem.c
@@ -69,7 +69,6 @@ enum {
PROP_DRAW
};
-static gboolean gtk_separator_tool_item_create_menu_proxy (GtkToolItem *item);
static void gtk_separator_tool_item_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -88,19 +87,15 @@ gtk_separator_tool_item_class_init (GtkSeparatorToolItemClass *class)
{
GObjectClass *object_class;
GtkContainerClass *container_class;
- GtkToolItemClass *toolitem_class;
GtkWidgetClass *widget_class;
object_class = (GObjectClass *)class;
container_class = (GtkContainerClass *)class;
- toolitem_class = (GtkToolItemClass *)class;
widget_class = (GtkWidgetClass *)class;
object_class->set_property = gtk_separator_tool_item_set_property;
object_class->get_property = gtk_separator_tool_item_get_property;
- toolitem_class->create_menu_proxy = gtk_separator_tool_item_create_menu_proxy;
-
container_class->add = gtk_separator_tool_item_add;
g_object_class_install_property (object_class,
@@ -126,18 +121,6 @@ gtk_separator_tool_item_add (GtkContainer *container,
g_warning ("attempt to add a child to a GtkSeparatorToolItem");
}
-static gboolean
-gtk_separator_tool_item_create_menu_proxy (GtkToolItem *item)
-{
- GtkWidget *menu_item = NULL;
-
- menu_item = gtk_separator_menu_item_new ();
-
- gtk_tool_item_set_proxy_menu_item (item, MENU_ID, menu_item);
-
- return TRUE;
-}
-
static void
gtk_separator_tool_item_set_property (GObject *object,
guint prop_id,
diff --git a/gtk/gtktoggletoolbutton.c b/gtk/gtktoggletoolbutton.c
index acdb56118a..36241a764f 100644
--- a/gtk/gtktoggletoolbutton.c
+++ b/gtk/gtktoggletoolbutton.c
@@ -72,12 +72,8 @@ static void gtk_toggle_tool_button_get_property (GObject *object
GValue *value,
GParamSpec *pspec);
-static gboolean gtk_toggle_tool_button_create_menu_proxy (GtkToolItem *button);
-
static void button_toggled (GtkWidget *widget,
GtkToggleToolButton *button);
-static void menu_item_activated (GtkWidget *widget,
- GtkToggleToolButton *button);
static guint toggle_signals[LAST_SIGNAL] = { 0 };
@@ -89,17 +85,14 @@ static void
gtk_toggle_tool_button_class_init (GtkToggleToolButtonClass *klass)
{
GObjectClass *object_class;
- GtkToolItemClass *toolitem_class;
GtkToolButtonClass *toolbutton_class;
object_class = (GObjectClass *)klass;
- toolitem_class = (GtkToolItemClass *)klass;
toolbutton_class = (GtkToolButtonClass *)klass;
object_class->set_property = gtk_toggle_tool_button_set_property;
object_class->get_property = gtk_toggle_tool_button_get_property;
- toolitem_class->create_menu_proxy = gtk_toggle_tool_button_create_menu_proxy;
toolbutton_class->button_type = GTK_TYPE_TOGGLE_BUTTON;
/**
@@ -189,94 +182,6 @@ gtk_toggle_tool_button_get_property (GObject *object,
}
}
-static gboolean
-gtk_toggle_tool_button_create_menu_proxy (GtkToolItem *item)
-{
- GtkToolButton *tool_button = GTK_TOOL_BUTTON (item);
- GtkToggleToolButton *toggle_tool_button = GTK_TOGGLE_TOOL_BUTTON (item);
- GtkWidget *menu_item = NULL;
- gboolean use_mnemonic = TRUE;
- const char *label;
- GtkWidget *label_widget;
- const gchar *label_text;
-
- if (_gtk_tool_item_create_menu_proxy (item))
- return TRUE;
-
- label_widget = gtk_tool_button_get_label_widget (tool_button);
- label_text = gtk_tool_button_get_label (tool_button);
-
- if (GTK_IS_LABEL (label_widget))
- {
- label = gtk_label_get_label (GTK_LABEL (label_widget));
- use_mnemonic = gtk_label_get_use_underline (GTK_LABEL (label_widget));
- }
- else if (label_text)
- {
- label = label_text;
- use_mnemonic = gtk_tool_button_get_use_underline (tool_button);
- }
- else
- {
- label = "";
- }
-
- if (use_mnemonic)
- menu_item = gtk_check_menu_item_new_with_mnemonic (label);
- else
- menu_item = gtk_check_menu_item_new_with_label (label);
-
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item),
- toggle_tool_button->priv->active);
-
- if (GTK_IS_RADIO_TOOL_BUTTON (toggle_tool_button))
- {
- gtk_check_menu_item_set_draw_as_radio (GTK_CHECK_MENU_ITEM (menu_item),
- TRUE);
- }
-
- g_signal_connect_closure_by_id (menu_item,
- g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
- g_cclosure_new_object (G_CALLBACK (menu_item_activated),
- G_OBJECT (toggle_tool_button)),
- FALSE);
-
- gtk_tool_item_set_proxy_menu_item (item, MENU_ID, menu_item);
-
- return TRUE;
-}
-
-/* There are two activatable widgets, a toggle button and a menu item.
- *
- * If a widget is activated and the state of the tool button is the same as
- * the new state of the activated widget, then the other widget was the one
- * that was activated by the user and updated the tool button’s state.
- *
- * If the state of the tool button is not the same as the new state of the
- * activated widget, then the activation was activated by the user, and the
- * widget needs to make sure the tool button is updated before the other
- * widget is activated. This will make sure the other widget a tool button
- * in a state that matches its own new state.
- */
-static void
-menu_item_activated (GtkWidget *menu_item,
- GtkToggleToolButton *toggle_tool_button)
-{
- GtkToolButton *tool_button = GTK_TOOL_BUTTON (toggle_tool_button);
- gboolean menu_active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item));
-
- if (toggle_tool_button->priv->active != menu_active)
- {
- toggle_tool_button->priv->active = menu_active;
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (_gtk_tool_button_get_button (tool_button)),
- toggle_tool_button->priv->active);
-
- g_object_notify (G_OBJECT (toggle_tool_button), "active");
- g_signal_emit (toggle_tool_button, toggle_signals[TOGGLED], 0);
- }
-}
-
static void
button_toggled (GtkWidget *widget,
GtkToggleToolButton *toggle_tool_button)
@@ -287,17 +192,8 @@ button_toggled (GtkWidget *widget,
if (toggle_tool_button->priv->active != toggle_active)
{
- GtkWidget *menu_item;
-
toggle_tool_button->priv->active = toggle_active;
- if ((menu_item =
- gtk_tool_item_get_proxy_menu_item (GTK_TOOL_ITEM (toggle_tool_button), MENU_ID)))
- {
- gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM (menu_item),
- toggle_tool_button->priv->active);
- }
-
g_object_notify (G_OBJECT (toggle_tool_button), "active");
g_signal_emit (toggle_tool_button, toggle_signals[TOGGLED], 0);
}
diff --git a/gtk/gtktoolbar.c b/gtk/gtktoolbar.c
index 102fffd1cb..fc232996f2 100644
--- a/gtk/gtktoolbar.c
+++ b/gtk/gtktoolbar.c
@@ -64,6 +64,7 @@
#include "gtkwindowprivate.h"
#include "gtkgestureclick.h"
#include "gtkbuttonprivate.h"
+#include "gtkmenubutton.h"
/**
@@ -143,7 +144,6 @@ struct _GtkToolbarPrivate
GtkToolbarStyle style;
GtkToolItem *highlight_tool_item;
- GtkWidget *arrow;
GtkWidget *arrow_button;
GtkAllocation prev_allocation;
@@ -233,13 +233,6 @@ static void gtk_toolbar_real_style_changed (GtkToolbar *toolbar
GtkToolbarStyle style);
static gboolean gtk_toolbar_focus_home_or_end (GtkToolbar *toolbar,
gboolean focus_home);
-static void gtk_toolbar_arrow_button_press (GtkGesture *gesture,
- int n_press,
- double x,
- double y,
- GtkToolbar *toolbar);
-static void gtk_toolbar_arrow_button_clicked (GtkWidget *button,
- GtkToolbar *toolbar);
static gboolean gtk_toolbar_popup_menu (GtkWidget *toolbar);
static void gtk_toolbar_reconfigured (GtkToolbar *toolbar);
@@ -306,7 +299,9 @@ static void toolbar_content_set_size_request (ToolbarContent
gint height);
static void toolbar_content_toolbar_reconfigured (ToolbarContent *content,
GtkToolbar *toolbar);
-static GtkWidget * toolbar_content_retrieve_menu_item (ToolbarContent *content);
+static const char * toolbar_content_get_overflow_text (ToolbarContent *content);
+static GtkButtonRole toolbar_content_get_button_role (ToolbarContent *content);
+static gboolean toolbar_content_get_active (ToolbarContent *content);
static gboolean toolbar_content_has_proxy_menu_item (ToolbarContent *content);
static gboolean toolbar_content_is_separator (ToolbarContent *content);
static void toolbar_content_set_expand (ToolbarContent *content,
@@ -316,6 +311,8 @@ static void toolbar_tool_shell_iface_init (GtkToolShellIface
static GtkOrientation toolbar_get_orientation (GtkToolShell *shell);
static GtkToolbarStyle toolbar_get_style (GtkToolShell *shell);
static void toolbar_rebuild_menu (GtkToolShell *shell);
+static void create_popup_func (GtkMenuButton *button,
+ gpointer data);
G_DEFINE_TYPE_WITH_CODE (GtkToolbar, gtk_toolbar, GTK_TYPE_CONTAINER,
@@ -558,18 +555,11 @@ gtk_toolbar_init (GtkToolbar *toolbar)
_gtk_orientable_set_style_classes (GTK_ORIENTABLE (toolbar));
- priv->arrow_button = gtk_toggle_button_new ();
- g_signal_connect (gtk_button_get_gesture (GTK_BUTTON (priv->arrow_button)), "pressed",
- G_CALLBACK (gtk_toolbar_arrow_button_press), toolbar);
- g_signal_connect (priv->arrow_button, "clicked",
- G_CALLBACK (gtk_toolbar_arrow_button_clicked), toolbar);
+ priv->arrow_button = gtk_menu_button_new ();
+ gtk_menu_button_set_create_popup_func (GTK_MENU_BUTTON (priv->arrow_button), create_popup_func, toolbar,
NULL);
gtk_widget_set_focus_on_click (priv->arrow_button, FALSE);
- priv->arrow = gtk_image_new_from_icon_name ("pan-down-symbolic");
- gtk_widget_set_name (priv->arrow, "gtk-toolbar-arrow");
- gtk_container_add (GTK_CONTAINER (priv->arrow_button), priv->arrow);
-
gtk_widget_set_parent (priv->arrow_button, widget);
/* which child position a drop will occur at */
@@ -656,9 +646,7 @@ gtk_toolbar_snapshot (GtkWidget *widget,
toolbar_content_snapshot (content, GTK_CONTAINER (widget), snapshot);
}
- gtk_widget_snapshot_child (widget,
- priv->arrow_button,
- snapshot);
+ gtk_widget_snapshot_child (widget, priv->arrow_button, snapshot);
}
static void
@@ -742,8 +730,7 @@ gtk_toolbar_measure (GtkWidget *widget,
arrow_requisition.width = 0;
if (priv->show_arrow)
- gtk_widget_get_preferred_size (priv->arrow_button,
- &arrow_requisition, NULL);
+ gtk_widget_get_preferred_size (priv->arrow_button, &arrow_requisition, NULL);
if (priv->orientation == GTK_ORIENTATION_HORIZONTAL)
{
@@ -1104,15 +1091,6 @@ remove_item (GtkWidget *menu_item,
menu_item);
}
-static void
-menu_deactivated (GtkWidget *menu,
- GtkToolbar *toolbar)
-{
- GtkToolbarPrivate *priv = toolbar->priv;
-
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
-}
-
static void
button_clicked (GtkWidget *button,
GtkWidget *item)
@@ -1123,19 +1101,19 @@ button_clicked (GtkWidget *button,
}
static void
-rebuild_menu (GtkToolbar *toolbar)
+create_popup_func (GtkMenuButton *menu_button,
+ gpointer data)
{
+ GtkToolbar *toolbar = data;
GtkToolbarPrivate *priv = toolbar->priv;
GList *list;
if (!priv->menu)
{
priv->menu = gtk_popover_menu_new (priv->arrow_button);
+ gtk_menu_button_set_popover (GTK_MENU_BUTTON (priv->arrow_button), priv->menu);
priv->menu_box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
gtk_popover_menu_add_submenu (GTK_POPOVER_MENU (priv->menu), priv->menu_box, "main");
-
- g_signal_connect (priv->menu, "closed",
- G_CALLBACK (menu_deactivated), toolbar);
}
gtk_container_foreach (GTK_CONTAINER (priv->menu_box), remove_item, NULL);
@@ -1147,49 +1125,15 @@ rebuild_menu (GtkToolbar *toolbar)
if (toolbar_content_get_state (content) == OVERFLOWN &&
!toolbar_content_is_placeholder (content))
{
- GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
-
- if (menu_item)
+ if (toolbar_content_is_separator (content))
+ gtk_container_add (GTK_CONTAINER (priv->menu_box), gtk_separator_new
(GTK_ORIENTATION_HORIZONTAL));
+ else if (toolbar_content_has_proxy_menu_item (content))
{
- GtkWidget *button, *widget;
- const char *text;
- GtkButtonRole role;
- gboolean active;
+ const char *text = toolbar_content_get_overflow_text (content);
+ GtkButtonRole role = toolbar_content_get_button_role (content);
+ gboolean active = toolbar_content_get_active (content);
- g_assert (GTK_IS_MENU_ITEM (menu_item));
- text = gtk_menu_item_get_label (GTK_MENU_ITEM (menu_item));
- if (text == NULL)
- {
- GtkWidget *box, *child;
- box = gtk_bin_get_child (GTK_BIN (menu_item));
- for (child = gtk_widget_get_first_child (box);
- child;
- child = gtk_widget_get_next_sibling (child))
- {
- if (GTK_IS_LABEL (child))
- {
- text = gtk_label_get_label (GTK_LABEL (child));
- break;
- }
- }
- }
-
- if (GTK_IS_SEPARATOR_MENU_ITEM (menu_item))
- {
- gtk_container_add (GTK_CONTAINER (priv->menu_box), gtk_separator_new
(GTK_ORIENTATION_HORIZONTAL));
- continue;
- }
- else if (GTK_IS_RADIO_MENU_ITEM (menu_item))
- role = GTK_BUTTON_ROLE_RADIO;
- else if (GTK_IS_CHECK_MENU_ITEM (menu_item))
- role = GTK_BUTTON_ROLE_CHECK;
- else
- role = GTK_BUTTON_ROLE_NORMAL;
-
- if (GTK_IS_CHECK_MENU_ITEM (menu_item))
- active = gtk_check_menu_item_get_active (GTK_CHECK_MENU_ITEM (menu_item));
- else
- active = FALSE;
+ GtkWidget *button, *widget;
button = gtk_model_button_new ();
g_object_set (button,
@@ -1198,8 +1142,7 @@ rebuild_menu (GtkToolbar *toolbar)
"active", active,
NULL);
widget = toolbar_content_get_widget (content);
- g_signal_connect (button, "clicked",
- G_CALLBACK (button_clicked), widget);
+ g_signal_connect (button, "clicked", G_CALLBACK (button_clicked), widget);
gtk_container_add (GTK_CONTAINER (priv->menu_box), button);
}
}
@@ -1484,7 +1427,7 @@ gtk_toolbar_size_allocate (GtkWidget *widget,
}
if (priv->menu && priv->need_rebuild)
- rebuild_menu (toolbar);
+ create_popup_func (GTK_MENU_BUTTON (priv->arrow_button), toolbar);
if (need_arrow)
{
@@ -1494,9 +1437,6 @@ gtk_toolbar_size_allocate (GtkWidget *widget,
else
{
gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
-
- if (priv->menu && gtk_widget_get_visible (GTK_WIDGET (priv->menu)))
- gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
}
g_free (allocations);
@@ -2116,9 +2056,9 @@ gtk_toolbar_orientation_changed (GtkToolbar *toolbar,
priv->orientation = orientation;
if (orientation == GTK_ORIENTATION_HORIZONTAL)
- gtk_image_set_from_icon_name (GTK_IMAGE (priv->arrow), "pan-down-symbolic");
+ gtk_menu_button_set_direction (GTK_MENU_BUTTON (priv->arrow_button), GTK_ARROW_DOWN);
else
- gtk_image_set_from_icon_name (GTK_IMAGE (priv->arrow), "pan-end-symbolic");
+ gtk_menu_button_set_direction (GTK_MENU_BUTTON (priv->arrow_button), GTK_ARROW_RIGHT);
gtk_toolbar_reconfigured (toolbar);
@@ -2145,50 +2085,6 @@ gtk_toolbar_real_style_changed (GtkToolbar *toolbar,
}
}
-static void
-show_menu (GtkToolbar *toolbar,
- GdkEventButton *event)
-{
- GtkToolbarPrivate *priv = toolbar->priv;
-
- rebuild_menu (toolbar);
-
- gtk_popover_popup (GTK_POPOVER (priv->menu));
-}
-
-static void
-gtk_toolbar_arrow_button_clicked (GtkWidget *button,
- GtkToolbar *toolbar)
-{
- GtkToolbarPrivate *priv = toolbar->priv;
-
- if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
- (!priv->menu || !gtk_widget_get_visible (GTK_WIDGET (priv->menu))))
- {
- /* We only get here when the button is clicked with the keyboard,
- * because mouse button presses result in the menu being shown so
- * that priv->menu would be non-NULL and visible.
- */
- show_menu (toolbar, NULL);
- gtk_menu_shell_select_first (GTK_MENU_SHELL (priv->menu), FALSE);
- }
-}
-
-static void
-gtk_toolbar_arrow_button_press (GtkGesture *gesture,
- int n_press,
- double x,
- double y,
- GtkToolbar *toolbar)
-{
- GtkWidget *button;
-
- button = gtk_event_controller_get_widget (GTK_EVENT_CONTROLLER (gesture));
- show_menu (toolbar, NULL);
- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), TRUE);
-}
-
-
static void
gtk_toolbar_pressed_cb (GtkGestureClick *gesture,
int n_press,
@@ -2520,14 +2416,6 @@ gtk_toolbar_dispose (GObject *object)
g_clear_pointer (&priv->arrow_button, gtk_widget_unparent);
- if (priv->menu)
- {
- g_signal_handlers_disconnect_by_func (priv->menu,
- menu_deactivated, toolbar);
- gtk_widget_destroy (GTK_WIDGET (priv->menu));
- priv->menu = NULL;
- }
-
if (priv->settings_connection > 0)
{
g_signal_handler_disconnect (priv->settings, priv->settings_connection);
@@ -2867,27 +2755,27 @@ toolbar_content_toolbar_reconfigured (ToolbarContent *content,
gtk_tool_item_toolbar_reconfigured (content->item);
}
-static GtkWidget *
-toolbar_content_retrieve_menu_item (ToolbarContent *content)
+static const char *
+toolbar_content_get_overflow_text (ToolbarContent *content)
{
- return gtk_tool_item_retrieve_proxy_menu_item (content->item);
+ return gtk_tool_item_get_overflow_text (content->item);
}
static gboolean
toolbar_content_has_proxy_menu_item (ToolbarContent *content)
{
- GtkWidget *menu_item;
+ const char *text;
if (content->has_menu == YES)
return TRUE;
else if (content->has_menu == NO)
return FALSE;
- menu_item = toolbar_content_retrieve_menu_item (content);
+ text = toolbar_content_get_overflow_text (content);
- content->has_menu = menu_item? YES : NO;
+ content->has_menu = text ? YES : NO;
- return menu_item != NULL;
+ return text != NULL;
}
static void
@@ -2896,6 +2784,26 @@ toolbar_content_set_unknown_menu_status (ToolbarContent *content)
content->has_menu = UNKNOWN;
}
+static GtkButtonRole
+toolbar_content_get_button_role (ToolbarContent *content)
+{
+ if (GTK_IS_RADIO_TOOL_BUTTON (content->item))
+ return GTK_BUTTON_ROLE_RADIO;
+ else if (GTK_IS_TOGGLE_TOOL_BUTTON (content->item))
+ return GTK_BUTTON_ROLE_CHECK;
+ else
+ return GTK_BUTTON_ROLE_NORMAL;
+}
+
+static gboolean
+toolbar_content_get_active (ToolbarContent *content)
+{
+ if (GTK_IS_TOGGLE_TOOL_BUTTON (content->item))
+ return gtk_toggle_tool_button_get_active (GTK_TOGGLE_TOOL_BUTTON (content->item));
+ else
+ return FALSE;
+}
+
static gboolean
toolbar_content_is_separator (ToolbarContent *content)
{
diff --git a/gtk/gtktoolbutton.c b/gtk/gtktoolbutton.c
index fedbe37faa..6bdeb7bc27 100644
--- a/gtk/gtktoolbutton.c
+++ b/gtk/gtktoolbutton.c
@@ -95,7 +95,6 @@ static void gtk_tool_button_property_notify (GObject *object,
static void gtk_tool_button_finalize (GObject *object);
static void gtk_tool_button_toolbar_reconfigured (GtkToolItem *tool_item);
-static gboolean gtk_tool_button_create_menu_proxy (GtkToolItem *item);
static void button_clicked (GtkWidget *widget,
GtkToolButton *button);
@@ -168,7 +167,6 @@ gtk_tool_button_class_init (GtkToolButtonClass *klass)
object_class->notify = gtk_tool_button_property_notify;
object_class->finalize = gtk_tool_button_finalize;
- tool_item_class->create_menu_proxy = gtk_tool_button_create_menu_proxy;
tool_item_class->toolbar_reconfigured = gtk_tool_button_toolbar_reconfigured;
klass->button_type = GTK_TYPE_BUTTON;
@@ -706,92 +704,6 @@ gtk_tool_button_finalize (GObject *object)
parent_class->finalize (object);
}
-static GtkWidget *
-clone_image_menu_size (GtkImage *image)
-{
- GtkImageType storage_type = gtk_image_get_storage_type (image);
-
- if (storage_type == GTK_IMAGE_ICON_NAME)
- {
- const gchar *icon_name = gtk_image_get_icon_name (image);
-
- return gtk_image_new_from_icon_name (icon_name);
- }
- else if (storage_type == GTK_IMAGE_GICON)
- {
- GIcon *icon = gtk_image_get_gicon (image);
-
- return gtk_image_new_from_gicon (icon);
- }
-
- return NULL;
-}
-
-static void
-click_button (GtkButton *button)
-{
- g_signal_emit_by_name (button, "clicked");
-}
-
-static gboolean
-gtk_tool_button_create_menu_proxy (GtkToolItem *item)
-{
- GtkToolButton *button = GTK_TOOL_BUTTON (item);
- GtkWidget *menu_item;
- GtkWidget *menu_image = NULL;
- gboolean use_mnemonic = TRUE;
- const char *label_text;
- GtkWidget *box;
- GtkWidget *label;
-
- if (_gtk_tool_item_create_menu_proxy (item))
- return TRUE;
-
- if (GTK_IS_LABEL (button->priv->label_widget))
- {
- label_text = gtk_label_get_label (GTK_LABEL (button->priv->label_widget));
- use_mnemonic = gtk_label_get_use_underline (GTK_LABEL (button->priv->label_widget));
- }
- else if (button->priv->label_text)
- {
- label_text = button->priv->label_text;
- use_mnemonic = button->priv->use_underline;
- }
- else
- {
- label_text = "";
- }
-
- if (GTK_IS_IMAGE (button->priv->icon_widget))
- {
- menu_image = clone_image_menu_size (GTK_IMAGE (button->priv->icon_widget));
- }
-
- box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
- if (use_mnemonic)
- label = gtk_label_new_with_mnemonic (label_text);
- else
- label = gtk_label_new (label_text);
-
- if (menu_image)
- gtk_container_add (GTK_CONTAINER (box), menu_image);
-
- gtk_container_add (GTK_CONTAINER (box), label);
-
- menu_item = gtk_menu_item_new ();
- gtk_container_add (GTK_CONTAINER (menu_item), box);
-
- g_signal_connect_closure_by_id (menu_item,
- g_signal_lookup ("activate", G_OBJECT_TYPE (menu_item)), 0,
- g_cclosure_new_object_swap (G_CALLBACK (click_button),
- G_OBJECT (GTK_TOOL_BUTTON
(button)->priv->button)),
- FALSE);
-
- gtk_tool_item_set_proxy_menu_item (GTK_TOOL_ITEM (button), MENU_ID, menu_item);
-
- return TRUE;
-}
-
static void
button_clicked (GtkWidget *widget,
GtkToolButton *button)
@@ -848,6 +760,7 @@ gtk_tool_button_set_label (GtkToolButton *button,
gchar *old_label;
gchar *elided_label;
AtkObject *accessible;
+ const char *old_overflow_text;
g_return_if_fail (GTK_IS_TOOL_BUTTON (button));
@@ -864,6 +777,11 @@ gtk_tool_button_set_label (GtkToolButton *button,
g_free (elided_label);
}
+ old_overflow_text = gtk_tool_item_get_overflow_text (GTK_TOOL_ITEM (button));
+ if (old_overflow_text == NULL ||
+ strcmp (old_overflow_text, old_label) == 0)
+ gtk_tool_item_set_overflow_text (GTK_TOOL_ITEM (button), label);
+
g_free (old_label);
g_object_notify (G_OBJECT (button), "label");
diff --git a/gtk/gtktoolitem.c b/gtk/gtktoolitem.c
index d21389d138..ffbbace135 100644
--- a/gtk/gtktoolitem.c
+++ b/gtk/gtktoolitem.c
@@ -70,6 +70,7 @@ enum {
PROP_IS_IMPORTANT,
PROP_HOMOGENEOUS,
PROP_EXPAND_ITEM,
+ PROP_OVERFLOW_TEXT
};
@@ -84,8 +85,7 @@ struct _GtkToolItemPrivate
guint expand : 1;
guint is_important : 1;
- gchar *menu_item_id;
- GtkWidget *menu_item;
+ char *overflow_text;
};
static void gtk_tool_item_finalize (GObject *object);
@@ -100,8 +100,6 @@ static void gtk_tool_item_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
-static void gtk_tool_item_property_notify (GObject *object,
- GParamSpec *pspec);
static guint toolitem_signals[LAST_SIGNAL] = { 0 };
@@ -120,10 +118,7 @@ gtk_tool_item_class_init (GtkToolItemClass *klass)
object_class->set_property = gtk_tool_item_set_property;
object_class->get_property = gtk_tool_item_get_property;
object_class->finalize = gtk_tool_item_finalize;
- object_class->notify = gtk_tool_item_property_notify;
- klass->create_menu_proxy = _gtk_tool_item_create_menu_proxy;
-
g_object_class_install_property (object_class,
PROP_VISIBLE_HORIZONTAL,
g_param_spec_boolean ("visible-horizontal",
@@ -161,41 +156,13 @@ gtk_tool_item_class_init (GtkToolItemClass *klass)
P_("Whether the item should be the same size as
other homogeneous items"),
FALSE,
GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
-
-/**
- * GtkToolItem::create-menu-proxy:
- * @tool_item: the object the signal was emitted on
- *
- * This signal is emitted when the toolbar needs information from @tool_item
- * about whether the item should appear in the toolbar overflow menu. In
- * response the tool item should either
- *
- * - call gtk_tool_item_set_proxy_menu_item() with a %NULL
- * pointer and return %TRUE to indicate that the item should not appear
- * in the overflow menu
- *
- * - call gtk_tool_item_set_proxy_menu_item() with a new menu
- * item and return %TRUE, or
- *
- * - return %FALSE to indicate that the signal was not handled by the item.
- * This means that the item will not appear in the overflow menu unless
- * a later handler installs a menu item.
- *
- * The toolbar may cache the result of this signal. When the tool item changes
- * how it will respond to this signal it must call gtk_tool_item_rebuild_menu()
- * to invalidate the cache and ensure that the toolbar rebuilds its overflow
- * menu.
- *
- * Returns: %TRUE if the signal was handled, %FALSE if not
- **/
- toolitem_signals[CREATE_MENU_PROXY] =
- g_signal_new (I_("create-menu-proxy"),
- G_OBJECT_CLASS_TYPE (klass),
- G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GtkToolItemClass, create_menu_proxy),
- _gtk_boolean_handled_accumulator, NULL,
- _gtk_marshal_BOOLEAN__VOID,
- G_TYPE_BOOLEAN, 0);
+ g_object_class_install_property (object_class,
+ PROP_OVERFLOW_TEXT,
+ g_param_spec_string ("overflow-text",
+ P_("Overflow text"),
+ P_("Overflow text"),
+ NULL,
+ GTK_PARAM_READWRITE|G_PARAM_EXPLICIT_NOTIFY));
/**
* GtkToolItem::toolbar-reconfigured:
@@ -239,13 +206,6 @@ gtk_tool_item_init (GtkToolItem *toolitem)
static void
gtk_tool_item_finalize (GObject *object)
{
- GtkToolItem *item = GTK_TOOL_ITEM (object);
-
- g_free (item->priv->menu_item_id);
-
- if (item->priv->menu_item)
- g_object_unref (item->priv->menu_item);
-
G_OBJECT_CLASS (gtk_tool_item_parent_class)->finalize (object);
}
@@ -285,6 +245,9 @@ gtk_tool_item_set_property (GObject *object,
case PROP_HOMOGENEOUS:
gtk_tool_item_set_homogeneous (toolitem, g_value_get_boolean (value));
break;
+ case PROP_OVERFLOW_TEXT:
+ gtk_tool_item_set_overflow_text (toolitem, g_value_get_string (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -316,32 +279,15 @@ gtk_tool_item_get_property (GObject *object,
case PROP_HOMOGENEOUS:
g_value_set_boolean (value, toolitem->priv->homogeneous);
break;
+ case PROP_OVERFLOW_TEXT:
+ g_value_set_string (value, toolitem->priv->overflow_text);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
-static void
-gtk_tool_item_property_notify (GObject *object,
- GParamSpec *pspec)
-{
- GtkToolItem *tool_item = GTK_TOOL_ITEM (object);
-
- if (tool_item->priv->menu_item && strcmp (pspec->name, "sensitive") == 0)
- gtk_widget_set_sensitive (tool_item->priv->menu_item,
- gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
-
- if (G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify)
- G_OBJECT_CLASS (gtk_tool_item_parent_class)->notify (object, pspec);
-}
-
-gboolean
-_gtk_tool_item_create_menu_proxy (GtkToolItem *item)
-{
- return FALSE;
-}
-
/**
* gtk_tool_item_new:
*
@@ -779,60 +725,6 @@ gtk_tool_item_get_visible_vertical (GtkToolItem *toolitem)
return toolitem->priv->visible_vertical;
}
-/**
- * gtk_tool_item_retrieve_proxy_menu_item:
- * @tool_item: a #GtkToolItem
- *
- * Returns the #GtkMenuItem that was last set by
- * gtk_tool_item_set_proxy_menu_item(), ie. the #GtkMenuItem
- * that is going to appear in the overflow menu.
- *
- * Returns: (transfer none): The #GtkMenuItem that is going to appear in the
- * overflow menu for @tool_item.
- **/
-GtkWidget *
-gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item)
-{
- gboolean retval;
-
- g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
-
- g_signal_emit (tool_item, toolitem_signals[CREATE_MENU_PROXY], 0,
- &retval);
-
- return tool_item->priv->menu_item;
-}
-
-/**
- * gtk_tool_item_get_proxy_menu_item:
- * @tool_item: a #GtkToolItem
- * @menu_item_id: a string used to identify the menu item
- *
- * If @menu_item_id matches the string passed to
- * gtk_tool_item_set_proxy_menu_item() return the corresponding #GtkMenuItem.
- *
- * Custom subclasses of #GtkToolItem should use this function to
- * update their menu item when the #GtkToolItem changes. That the
- * @menu_item_ids must match ensures that a #GtkToolItem
- * will not inadvertently change a menu item that they did not create.
- *
- * Returns: (transfer none) (nullable): The #GtkMenuItem passed to
- * gtk_tool_item_set_proxy_menu_item(), if the @menu_item_ids
- * match.
- **/
-GtkWidget *
-gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
- const gchar *menu_item_id)
-{
- g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
- g_return_val_if_fail (menu_item_id != NULL, NULL);
-
- if (tool_item->priv->menu_item_id && strcmp (tool_item->priv->menu_item_id, menu_item_id) == 0)
- return tool_item->priv->menu_item;
-
- return NULL;
-}
-
/**
* gtk_tool_item_rebuild_menu:
* @tool_item: a #GtkToolItem
@@ -860,48 +752,6 @@ gtk_tool_item_rebuild_menu (GtkToolItem *tool_item)
gtk_tool_shell_rebuild_menu (GTK_TOOL_SHELL (parent));
}
-/**
- * gtk_tool_item_set_proxy_menu_item:
- * @tool_item: a #GtkToolItem
- * @menu_item_id: a string used to identify @menu_item
- * @menu_item: (nullable): a #GtkMenuItem to use in the overflow menu, or %NULL
- *
- * Sets the #GtkMenuItem used in the toolbar overflow menu. The
- * @menu_item_id is used to identify the caller of this function and
- * should also be used with gtk_tool_item_get_proxy_menu_item().
- *
- * See also #GtkToolItem::create-menu-proxy.
- **/
-void
-gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
- const gchar *menu_item_id,
- GtkWidget *menu_item)
-{
- g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
- g_return_if_fail (menu_item == NULL || GTK_IS_MENU_ITEM (menu_item));
- g_return_if_fail (menu_item_id != NULL);
-
- g_free (tool_item->priv->menu_item_id);
-
- tool_item->priv->menu_item_id = g_strdup (menu_item_id);
-
- if (tool_item->priv->menu_item != menu_item)
- {
- if (tool_item->priv->menu_item)
- g_object_unref (tool_item->priv->menu_item);
-
- if (menu_item)
- {
- g_object_ref_sink (menu_item);
-
- gtk_widget_set_sensitive (menu_item,
- gtk_widget_get_sensitive (GTK_WIDGET (tool_item)));
- }
-
- tool_item->priv->menu_item = menu_item;
- }
-}
-
/**
* gtk_tool_item_toolbar_reconfigured:
* @tool_item: a #GtkToolItem
@@ -926,3 +776,23 @@ gtk_tool_item_toolbar_reconfigured (GtkToolItem *tool_item)
gtk_widget_queue_resize (GTK_WIDGET (tool_item));
}
+
+void
+gtk_tool_item_set_overflow_text (GtkToolItem *tool_item,
+ const char *overflow_text)
+{
+ g_return_if_fail (GTK_IS_TOOL_ITEM (tool_item));
+
+ g_free (tool_item->priv->overflow_text);
+ tool_item->priv->overflow_text = g_strdup (overflow_text);
+
+ g_object_notify (G_OBJECT (tool_item), "overflow-text");
+}
+
+const char *
+gtk_tool_item_get_overflow_text (GtkToolItem *tool_item)
+{
+ g_return_val_if_fail (GTK_IS_TOOL_ITEM (tool_item), NULL);
+
+ return tool_item->priv->overflow_text;
+}
diff --git a/gtk/gtktoolitem.h b/gtk/gtktoolitem.h
index 6482a09e20..5dcdc80315 100644
--- a/gtk/gtktoolitem.h
+++ b/gtk/gtktoolitem.h
@@ -53,9 +53,6 @@ struct _GtkToolItem
/**
* GtkToolItemClass:
* @parent_class: The parent class.
- * @create_menu_proxy: Signal emitted when the toolbar needs
- * information from tool_item about whether the item should appear in
- * the toolbar overflow menu.
* @toolbar_reconfigured: Signal emitted when some property of the
* toolbar that the item is a child of changes.
*/
@@ -64,7 +61,6 @@ struct _GtkToolItemClass
GtkBinClass parent_class;
/* signals */
- gboolean (* create_menu_proxy) (GtkToolItem *tool_item);
void (* toolbar_reconfigured) (GtkToolItem *tool_item);
/*< private >*/
@@ -127,14 +123,10 @@ GDK_AVAILABLE_IN_ALL
GtkSizeGroup * gtk_tool_item_get_text_size_group (GtkToolItem *tool_item);
GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_tool_item_retrieve_proxy_menu_item (GtkToolItem *tool_item);
+const char * gtk_tool_item_get_overflow_text (GtkToolItem *tool_item);
GDK_AVAILABLE_IN_ALL
-GtkWidget * gtk_tool_item_get_proxy_menu_item (GtkToolItem *tool_item,
- const gchar *menu_item_id);
-GDK_AVAILABLE_IN_ALL
-void gtk_tool_item_set_proxy_menu_item (GtkToolItem *tool_item,
- const gchar *menu_item_id,
- GtkWidget *menu_item);
+void gtk_tool_item_set_overflow_text (GtkToolItem *tool_item,
+ const char *overflow_text);
GDK_AVAILABLE_IN_ALL
void gtk_tool_item_rebuild_menu (GtkToolItem *tool_item);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]