[gtk/kill-tree-menu: 13/51] toolbar: Simplify overflow implementation



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]