]> Pileus Git - ~andy/gtk/commitdiff
Add a checkbox to queue an merge/unmerge. Patch from Matthias Clasen.
authorSoeren Sandmann <sandmann@daimi.au.dk>
Sat, 5 Jun 2004 18:24:53 +0000 (18:24 +0000)
committerSøren Sandmann Pedersen <ssp@src.gnome.org>
Sat, 5 Jun 2004 18:24:53 +0000 (18:24 +0000)
Sat Jun  5 20:05:39 2004  Soeren Sandmann  <sandmann@daimi.au.dk>

* tests/testmerge.c: Add a checkbox to queue an
merge/unmerge. Patch from Matthias Clasen.

* gtk/gtktoolbar.c (struct _GtkToolbarPrivate): Add a new flag
"need_rebuild"
(rebuild_menu): New function that rebuilds the overflow menu and
makes sure it doesn't start or end with a separator.
(toolbar_content_new_tool_item)
(toolbar_content_remove)
(toolbar_content_new_compatibility): Set the rebuild_needed flag
(gtk_toolbar_size_allocate): Only show the overflow arrow when we
have actually overflown an item with a proxy menu item. Also make
sure we rebuild the menu if needed.

Fix #125504, #142377, #143463

* gtk/gtkseparatortoolitem.c (gtk_separator_tool_item_expose):
Obey the "priv->draw" flag. (#143692)

ChangeLog
ChangeLog.pre-2-10
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gtk/gtkseparatortoolitem.c
gtk/gtktoolbar.c
tests/testmerge.c

index 1dcf0753e207b017f9833885985087d87f676f46..4ffac1967ded498a123840a5fb0990c54c87735d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+Sat Jun  5 20:05:39 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * tests/testmerge.c: Add a checkbox to queue an
+       merge/unmerge. Patch from Matthias Clasen.
+
+       * gtk/gtktoolbar.c (struct _GtkToolbarPrivate): Add a new flag
+       "need_rebuild"
+       (rebuild_menu): New function that rebuilds the overflow menu and
+       makes sure it doesn't start or end with a separator.
+       (toolbar_content_new_tool_item)
+       (toolbar_content_remove)
+       (toolbar_content_new_compatibility): Set the rebuild_needed flag
+       (gtk_toolbar_size_allocate): Only show the overflow arrow when we
+       have actually overflown an item with a proxy menu item. Also make
+       sure we rebuild the menu if needed.
+
+       Fix #125504, #142377, #143463
+       
+       * gtk/gtkseparatortoolitem.c (gtk_separator_tool_item_expose):
+       Obey the "priv->draw" flag. (#143692)
+
 2004-06-04  Matthias Clasen  <mclasen@redhat.com>
 
        * docs/widget_geometry.txt: Add a note about the !CAN_FOCUS
index 1dcf0753e207b017f9833885985087d87f676f46..4ffac1967ded498a123840a5fb0990c54c87735d 100644 (file)
@@ -1,3 +1,24 @@
+Sat Jun  5 20:05:39 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * tests/testmerge.c: Add a checkbox to queue an
+       merge/unmerge. Patch from Matthias Clasen.
+
+       * gtk/gtktoolbar.c (struct _GtkToolbarPrivate): Add a new flag
+       "need_rebuild"
+       (rebuild_menu): New function that rebuilds the overflow menu and
+       makes sure it doesn't start or end with a separator.
+       (toolbar_content_new_tool_item)
+       (toolbar_content_remove)
+       (toolbar_content_new_compatibility): Set the rebuild_needed flag
+       (gtk_toolbar_size_allocate): Only show the overflow arrow when we
+       have actually overflown an item with a proxy menu item. Also make
+       sure we rebuild the menu if needed.
+
+       Fix #125504, #142377, #143463
+       
+       * gtk/gtkseparatortoolitem.c (gtk_separator_tool_item_expose):
+       Obey the "priv->draw" flag. (#143692)
+
 2004-06-04  Matthias Clasen  <mclasen@redhat.com>
 
        * docs/widget_geometry.txt: Add a note about the !CAN_FOCUS
index 1dcf0753e207b017f9833885985087d87f676f46..4ffac1967ded498a123840a5fb0990c54c87735d 100644 (file)
@@ -1,3 +1,24 @@
+Sat Jun  5 20:05:39 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * tests/testmerge.c: Add a checkbox to queue an
+       merge/unmerge. Patch from Matthias Clasen.
+
+       * gtk/gtktoolbar.c (struct _GtkToolbarPrivate): Add a new flag
+       "need_rebuild"
+       (rebuild_menu): New function that rebuilds the overflow menu and
+       makes sure it doesn't start or end with a separator.
+       (toolbar_content_new_tool_item)
+       (toolbar_content_remove)
+       (toolbar_content_new_compatibility): Set the rebuild_needed flag
+       (gtk_toolbar_size_allocate): Only show the overflow arrow when we
+       have actually overflown an item with a proxy menu item. Also make
+       sure we rebuild the menu if needed.
+
+       Fix #125504, #142377, #143463
+       
+       * gtk/gtkseparatortoolitem.c (gtk_separator_tool_item_expose):
+       Obey the "priv->draw" flag. (#143692)
+
 2004-06-04  Matthias Clasen  <mclasen@redhat.com>
 
        * docs/widget_geometry.txt: Add a note about the !CAN_FOCUS
index 1dcf0753e207b017f9833885985087d87f676f46..4ffac1967ded498a123840a5fb0990c54c87735d 100644 (file)
@@ -1,3 +1,24 @@
+Sat Jun  5 20:05:39 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * tests/testmerge.c: Add a checkbox to queue an
+       merge/unmerge. Patch from Matthias Clasen.
+
+       * gtk/gtktoolbar.c (struct _GtkToolbarPrivate): Add a new flag
+       "need_rebuild"
+       (rebuild_menu): New function that rebuilds the overflow menu and
+       makes sure it doesn't start or end with a separator.
+       (toolbar_content_new_tool_item)
+       (toolbar_content_remove)
+       (toolbar_content_new_compatibility): Set the rebuild_needed flag
+       (gtk_toolbar_size_allocate): Only show the overflow arrow when we
+       have actually overflown an item with a proxy menu item. Also make
+       sure we rebuild the menu if needed.
+
+       Fix #125504, #142377, #143463
+       
+       * gtk/gtkseparatortoolitem.c (gtk_separator_tool_item_expose):
+       Obey the "priv->draw" flag. (#143692)
+
 2004-06-04  Matthias Clasen  <mclasen@redhat.com>
 
        * docs/widget_geometry.txt: Add a note about the !CAN_FOCUS
index e3682114721a07ea69707bf298b4b1a18f04c2d6..f39c04164b0abc7a36d41594a8682a6400ca2817 100644 (file)
@@ -229,12 +229,17 @@ gtk_separator_tool_item_expose (GtkWidget      *widget,
                                GdkEventExpose *event)
 {
   GtkToolbar *toolbar = NULL;
+  GtkSeparatorToolItemPrivate *priv =
+      GTK_SEPARATOR_TOOL_ITEM_GET_PRIVATE (widget);
 
-  if (widget->parent && GTK_IS_TOOLBAR (widget->parent))
-    toolbar = GTK_TOOLBAR (widget->parent);
+  if (priv->draw)
+    {
+      if (widget->parent && GTK_IS_TOOLBAR (widget->parent))
+       toolbar = GTK_TOOLBAR (widget->parent);
 
-  _gtk_toolbar_paint_space_line (widget, toolbar,
-                                &(event->area), &widget->allocation);
+      _gtk_toolbar_paint_space_line (widget, toolbar,
+                                    &(event->area), &widget->allocation);
+    }
   
   return FALSE;
 }
index 82bd8e9860da67e4e5fbb136845ccbefe6ca4cc7..70bccecd380d89655d7bdabd90025cd780ca5a3e 100644 (file)
@@ -51,6 +51,7 @@
 #include "gtkhbox.h"
 #include "gtkvbox.h"
 #include "gtkimage.h"
+#include "gtkseparatormenuitem.h"
 
 typedef struct _ToolbarContent ToolbarContent;
 
@@ -121,7 +122,6 @@ struct _GtkToolbarPrivate
   
   GtkWidget *  arrow;
   GtkWidget *  arrow_button;
-  
   GtkMenu *    menu;
   
   GdkWindow *  event_window;
@@ -136,6 +136,7 @@ struct _GtkToolbarPrivate
   guint                show_arrow : 1;
   guint                need_sync : 1;
   guint                is_sliding : 1;
+  guint                need_rebuild : 1;       /* whether the overflow menu should be regenerated */
 };
 
 static void       gtk_toolbar_init                 (GtkToolbar          *toolbar);
@@ -279,6 +280,7 @@ static void            toolbar_content_set_size_request     (ToolbarContent
 static void            toolbar_content_toolbar_reconfigured (ToolbarContent      *content,
                                                             GtkToolbar          *toolbar);
 static GtkWidget *     toolbar_content_retrieve_menu_item   (ToolbarContent      *content);
+static gboolean        toolbar_content_has_proxy_menu_item  (ToolbarContent     *content);
 static gboolean        toolbar_content_is_separator         (ToolbarContent      *content);
 static void            toolbar_content_show_all             (ToolbarContent      *content);
 static void            toolbar_content_hide_all             (ToolbarContent      *content);
@@ -1134,6 +1136,9 @@ gtk_toolbar_begin_sliding (GtkToolbar *toolbar)
    * item into content->start_allocation. For items that haven't
    * been allocated yet, we calculate their position and save that
    * in start_allocatino along with zero width and zero height.
+   *
+   * FIXME: It would be nice if we could share this code with
+   * the equivalent in gtk_widget_size_allocate().
    */
   priv->is_sliding = TRUE;
   
@@ -1246,6 +1251,93 @@ gtk_toolbar_stop_sliding (GtkToolbar *toolbar)
     }
 }
 
+static void
+remove_item (GtkWidget *menu_item,
+            gpointer   data)
+{
+  gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
+}
+
+static void
+menu_deactivated (GtkWidget  *menu,
+                 GtkToolbar *toolbar)
+{
+  GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
+}
+
+static void
+menu_detached (GtkWidget  *toolbar,
+              GtkMenu    *menu)
+{
+  GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+  priv->menu = NULL;
+}
+
+static void
+rebuild_menu (GtkToolbar *toolbar)
+{
+  GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
+  GList *list, *children;
+  
+  if (!priv->menu)
+    {
+      priv->menu = GTK_MENU (gtk_menu_new());
+      gtk_menu_attach_to_widget (priv->menu,
+                                GTK_WIDGET (toolbar),
+                                menu_detached);
+
+      g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
+    }
+
+  gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
+  
+  for (list = priv->content; list != NULL; list = list->next)
+    {
+      ToolbarContent *content = list->data;
+      
+      if (toolbar_content_get_state (content) == OVERFLOWN &&
+         !toolbar_content_is_placeholder (content))
+       {
+         GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
+         
+         if (menu_item)
+           {
+             g_assert (GTK_IS_MENU_ITEM (menu_item));
+             gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
+           }
+       }
+    }
+
+  /* Remove leading and trailing separator items */
+  children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
+  
+  list = children;
+  while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
+    {
+      GtkWidget *child = list->data;
+      
+      gtk_container_remove (GTK_CONTAINER (priv->menu), child);
+      list = list->next;
+    }
+  g_list_free (children);
+
+  /* Regenerate the list of children so we don't try to remove items twice */
+  children = gtk_container_get_children (GTK_CONTAINER (priv->menu));
+
+  list = g_list_last (children);
+  while (list && GTK_IS_SEPARATOR_MENU_ITEM (list->data))
+    {
+      GtkWidget *child = list->data;
+
+      gtk_container_remove (GTK_CONTAINER (priv->menu), child);
+      list = list->prev;
+    }
+  g_list_free (children);
+
+  priv->need_rebuild = FALSE;
+}
+
 static void
 gtk_toolbar_size_allocate (GtkWidget     *widget,
                           GtkAllocation *allocation)
@@ -1331,16 +1423,32 @@ gtk_toolbar_size_allocate (GtkWidget     *widget,
   new_states = g_new0 (ItemState, n_items);
   
   needed_size = 0;
+  need_arrow = FALSE;
   for (list = priv->content; list != NULL; list = list->next)
     {
       ToolbarContent *content = list->data;
       
       if (toolbar_content_visible (content, toolbar))
-       needed_size += get_item_size (toolbar, content);
+       {
+         needed_size += get_item_size (toolbar, content);
+
+         /* Do we need an arrow?
+          *
+          * Assume we don't, and see if any non-separator item with a
+          * proxy menu item is then going to overflow.
+          */
+         if (needed_size > available_size                      &&
+             !need_arrow                                       &&
+             priv->show_arrow                                  &&
+             priv->api_mode == NEW_API                         &&
+             toolbar_content_has_proxy_menu_item (content)     &&
+             !toolbar_content_is_separator (content))
+           {
+             need_arrow = TRUE;
+           }
+       }
     }
   
-  need_arrow = (needed_size > available_size) && priv->show_arrow && priv->api_mode == NEW_API;
-  
   if (need_arrow)
     size = available_size - arrow_size;
   else
@@ -1510,7 +1618,7 @@ gtk_toolbar_size_allocate (GtkWidget     *widget,
       if (toolbar_content_get_state (content) == NORMAL &&
          new_states[i] != NORMAL)
        {
-         /* an item disappeared, begin sliding */
+         /* an item disappeared and we didn't change size, so begin sliding */
          if (!size_changed && priv->api_mode == NEW_API)
            gtk_toolbar_begin_sliding (toolbar);
        }
@@ -1582,6 +1690,9 @@ gtk_toolbar_size_allocate (GtkWidget     *widget,
       toolbar_content_set_state (content, new_states[i]);
     }
   
+  if (priv->menu && priv->need_rebuild)
+    rebuild_menu (toolbar);
+  
   if (need_arrow)
     {
       gtk_widget_size_allocate (GTK_WIDGET (priv->arrow_button),
@@ -1591,8 +1702,11 @@ gtk_toolbar_size_allocate (GtkWidget     *widget,
   else
     {
       gtk_widget_hide (GTK_WIDGET (priv->arrow_button));
+
+      if (priv->menu && GTK_WIDGET_VISIBLE (priv->menu))
+       gtk_menu_shell_deactivate (GTK_MENU_SHELL (priv->menu));
     }
-  
+
   g_free (allocations);
   g_free (new_states);
 }
@@ -2400,64 +2514,13 @@ menu_position_func (GtkMenu  *menu,
   *push_in = TRUE;
 }
 
-static void
-menu_deactivated (GtkWidget  *menu,
-                 GtkToolbar *toolbar)
-{
-  GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (priv->arrow_button), FALSE);
-}
-
-static void
-menu_detached (GtkWidget  *toolbar,
-              GtkMenu    *menu)
-{
-  GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
-  priv->menu = NULL;
-}
-
-static void
-remove_item (GtkWidget *menu_item,
-            gpointer   data)
-{
-  gtk_container_remove (GTK_CONTAINER (menu_item->parent), menu_item);
-}
-
 static void
 show_menu (GtkToolbar     *toolbar,
           GdkEventButton *event)
 {
   GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);
-  GList *list;
-  
-  if (priv->menu)
-    {
-      gtk_container_foreach (GTK_CONTAINER (priv->menu), remove_item, NULL);
-      gtk_widget_destroy (GTK_WIDGET (priv->menu));
-    }
 
-  priv->menu = GTK_MENU (gtk_menu_new ());
-  gtk_menu_attach_to_widget (priv->menu,
-                            GTK_WIDGET (toolbar),
-                            menu_detached);
-  g_signal_connect (priv->menu, "deactivate", G_CALLBACK (menu_deactivated), toolbar);
-
-  for (list = priv->content; list != NULL; list = list->next)
-    {
-      ToolbarContent *content = list->data;
-      
-      if (toolbar_content_get_state (content) == OVERFLOWN &&
-         !toolbar_content_is_placeholder (content))
-       {
-         GtkWidget *menu_item = toolbar_content_retrieve_menu_item (content);
-         
-         if (menu_item)
-           {
-             g_assert (GTK_IS_MENU_ITEM (menu_item));
-             gtk_menu_shell_append (GTK_MENU_SHELL (priv->menu), menu_item);
-           }
-       }
-    }
+  rebuild_menu (toolbar);
 
   gtk_widget_show_all (GTK_WIDGET (priv->menu));
 
@@ -2474,9 +2537,9 @@ gtk_toolbar_arrow_button_clicked (GtkWidget  *button,
   GtkToolbarPrivate *priv = GTK_TOOLBAR_GET_PRIVATE (toolbar);  
   
   if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (priv->arrow_button)) &&
-      (!priv->menu || !GTK_WIDGET_VISIBLE (GTK_WIDGET (priv->menu))))
+      (!priv->menu || !GTK_WIDGET_VISIBLE (priv->menu)))
     {
-      /* We only get here when the button is clicked with the keybaord,
+      /* 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.
        */
@@ -2973,7 +3036,7 @@ gtk_toolbar_finalize (GObject *object)
   
   if (priv->idle_id)
     g_source_remove (priv->idle_id);
-  
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -3693,6 +3756,7 @@ toolbar_content_new_tool_item (GtkToolbar  *toolbar,
     }
 
   gtk_widget_queue_resize (GTK_WIDGET (toolbar));
+  priv->need_rebuild = TRUE;
   
   return content;
 }
@@ -3738,6 +3802,7 @@ toolbar_content_new_compatibility (GtkToolbar          *toolbar,
 
   priv->content = g_list_insert (priv->content, content, pos);
   toolbar->children = g_list_insert (toolbar->children, child, pos);
+  priv->need_rebuild = TRUE;
   
   toolbar->num_children++;
   
@@ -3780,6 +3845,7 @@ toolbar_content_remove (ToolbarContent *content,
     toolbar->num_children--;
 
   gtk_widget_queue_resize (GTK_WIDGET (toolbar));
+  priv->need_rebuild = TRUE;
 }
 
 static void
@@ -4369,6 +4435,16 @@ toolbar_content_retrieve_menu_item (ToolbarContent *content)
   return NULL; 
 }
 
+static gboolean
+toolbar_content_has_proxy_menu_item (ToolbarContent *content)
+{
+  GtkWidget *menu_item;
+
+  menu_item = toolbar_content_retrieve_menu_item (content);
+
+  return menu_item != NULL;
+}
 static gboolean
 toolbar_content_is_separator (ToolbarContent *content)
 {
@@ -4557,14 +4633,12 @@ _gtk_toolbar_paint_space_line (GtkWidget       *widget,
   const double start_fraction = (SPACE_LINE_START / SPACE_LINE_DIVISION);
   const double end_fraction = (SPACE_LINE_END / SPACE_LINE_DIVISION);
   
-  gint space_size;
   GtkToolbarSpaceStyle space_style;
   GtkOrientation orientation;
 
   g_return_if_fail (GTK_IS_WIDGET (widget));
   
-  space_size = get_space_size (toolbar);
-  space_style = get_space_style (toolbar);
+  space_style = toolbar? get_space_style (toolbar) : DEFAULT_SPACE_STYLE;
   orientation = toolbar? toolbar->orientation : GTK_ORIENTATION_HORIZONTAL;
 
   if (orientation == GTK_ORIENTATION_HORIZONTAL)
@@ -4574,7 +4648,7 @@ _gtk_toolbar_paint_space_line (GtkWidget       *widget,
                       "toolbar",
                       allocation->y + allocation->height * start_fraction,
                       allocation->y + allocation->height * end_fraction,
-                      allocation->x + (space_size - widget->style->xthickness) / 2);
+                      allocation->x + (allocation->width - widget->style->xthickness) / 2);
     }
   else
     {
@@ -4583,7 +4657,7 @@ _gtk_toolbar_paint_space_line (GtkWidget       *widget,
                       "toolbar",
                       allocation->x + allocation->width * start_fraction,
                       allocation->x + allocation->width * end_fraction,
-                      allocation->y + (space_size - widget->style->ythickness) / 2);
+                      allocation->y + (allocation->height - widget->style->ythickness) / 2);
     }
 }
 
index d1c6e4781d1995aa2e723010e2edb9891025efce..05bbf3133b525575e71601535befc28b791e097a 100644 (file)
@@ -66,9 +66,8 @@ toggle_tearoffs (GtkWidget    *button,
   gtk_ui_manager_set_add_tearoffs (merge, !add_tearoffs);
 }
 
-static void
-toggle_dynamic (GtkWidget    *button, 
-               GtkUIManager *merge)
+static gint
+delayed_toggle_dynamic (GtkUIManager *merge)
 {
   GtkAction *dyn;
   static GtkActionGroup *dynamic = NULL;
@@ -89,6 +88,7 @@ toggle_dynamic (GtkWidget    *button,
                          "label", "Dynamic action 2",
                          "stock_id", GTK_STOCK_EXECUTE,
                          NULL);
+      g_object_set (dyn, "name", "dyn2", NULL);
       gtk_action_group_add_action (dynamic, dyn);
     }
   
@@ -114,8 +114,16 @@ toggle_dynamic (GtkWidget    *button,
       gtk_ui_manager_remove_ui (merge, merge_id);
       merge_id = 0;
     }
+
+  return FALSE;
 }
 
+static void
+toggle_dynamic (GtkWidget    *button, 
+               GtkUIManager *merge)
+{
+  g_timeout_add (2000, delayed_toggle_dynamic, merge);
+}
 
 static void
 activate_action (GtkAction *action)