]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktree.c
do not avoid to queue for a resize if the container is not visible, we
[~andy/gtk] / gtk / gtktree.c
index 317a4749ce31954d106d5504867862057fbb5aff..bbb1f9cae9af60a095a1562c53535b3f4f5bd52d 100644 (file)
@@ -12,8 +12,9 @@
  * Library General Public License for more details.
  *
  * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
  */
 #include "gtktree.h"
 #include "gtktreeitem.h"
@@ -68,14 +69,15 @@ static void gtk_tree_marshal_signal (GtkObject      *object,
                                     GtkSignalFunc   func,
                                     gpointer        func_data,
                                     GtkArg         *args);
+static GtkType gtk_tree_child_type  (GtkContainer   *container);
 
 static GtkContainerClass *parent_class = NULL;
-static gint tree_signals[LAST_SIGNAL] = { 0 };
+static guint tree_signals[LAST_SIGNAL] = { 0 };
 
-guint
-gtk_tree_get_type ()
+GtkType
+gtk_tree_get_type (void)
 {
-  static guint tree_type = 0;
+  static GtkType tree_type = 0;
 
   if (!tree_type)
     {
@@ -152,12 +154,19 @@ gtk_tree_class_init (GtkTreeClass *class)
   container_class->remove = 
              (void (*)(GtkContainer *, GtkWidget *)) gtk_tree_remove_item;
   container_class->foreach = gtk_tree_foreach;
+  container_class->child_type = gtk_tree_child_type;
 
   class->selection_changed = NULL;
   class->select_child = gtk_real_tree_select_child;
   class->unselect_child = gtk_real_tree_unselect_child;
 }
 
+static GtkType
+gtk_tree_child_type (GtkContainer     *container)
+{
+  return GTK_TYPE_TREE_ITEM;
+}
+
 static void
 gtk_tree_init (GtkTree *tree)
 {
@@ -174,55 +183,59 @@ gtk_tree_init (GtkTree *tree)
 }
 
 GtkWidget*
-gtk_tree_new ()
+gtk_tree_new (void)
 {
   return GTK_WIDGET (gtk_type_new (gtk_tree_get_type ()));
 }
 
 void
 gtk_tree_append (GtkTree   *tree,
-                GtkWidget *child)
+                GtkWidget *tree_item)
 {
-
   g_return_if_fail (tree != NULL);
-  g_return_if_fail (GTK_IS_TREE_ITEM (child));
+  g_return_if_fail (GTK_IS_TREE (tree));
+  g_return_if_fail (tree_item != NULL);
+  g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
 
-  gtk_tree_insert(tree, child, -1);
+  gtk_tree_insert(tree, tree_item, -1);
 }
 
 void
 gtk_tree_prepend (GtkTree   *tree,
-                 GtkWidget *child)
+                 GtkWidget *tree_item)
 {
   g_return_if_fail (tree != NULL);
-  g_return_if_fail (GTK_IS_TREE_ITEM (child));
-
-  gtk_tree_insert(tree, child, 0);
+  g_return_if_fail (GTK_IS_TREE (tree));
+  g_return_if_fail (tree_item != NULL);
+  g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
 
+  gtk_tree_insert(tree, tree_item, 0);
 }
 
 void
 gtk_tree_insert (GtkTree   *tree,
-                GtkWidget *child,
+                GtkWidget *tree_item,
                 gint       position)
 {
   gint nchildren;
     
-  g_return_if_fail (tree != NULL || child != NULL);
-  g_return_if_fail (GTK_IS_TREE_ITEM(child));
+  g_return_if_fail (tree != NULL);
+  g_return_if_fail (GTK_IS_TREE (tree));
+  g_return_if_fail (tree_item != NULL);
+  g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
 
   /* set parent widget to item */
-  gtk_widget_set_parent (child, GTK_WIDGET (tree));
+  gtk_widget_set_parent (tree_item, GTK_WIDGET (tree));
     
-  if (GTK_WIDGET_VISIBLE (child->parent))
+  if (GTK_WIDGET_VISIBLE (tree_item->parent))
     {
-      if (GTK_WIDGET_REALIZED (child->parent) &&
-         !GTK_WIDGET_REALIZED (child))
-       gtk_widget_realize (child);
+      if (GTK_WIDGET_REALIZED (tree_item->parent) &&
+         !GTK_WIDGET_REALIZED (tree_item))
+       gtk_widget_realize (tree_item);
 
-      if (GTK_WIDGET_MAPPED (child->parent) &&
-         !GTK_WIDGET_MAPPED (child))
-       gtk_widget_map (child);
+      if (GTK_WIDGET_MAPPED (tree_item->parent) &&
+         !GTK_WIDGET_MAPPED (tree_item))
+       gtk_widget_map (tree_item);
     }
 
   nchildren = g_list_length (tree->children);
@@ -232,11 +245,11 @@ gtk_tree_insert (GtkTree   *tree,
 
   if (position == nchildren)
     {
-      tree->children = g_list_append(tree->children, child);
+      tree->children = g_list_append(tree->children, tree_item);
     }
   else
     {
-      tree->children = g_list_insert(tree->children, child, position);
+      tree->children = g_list_insert(tree->children, tree_item, position);
     }
     
   if (GTK_WIDGET_VISIBLE (tree))
@@ -253,6 +266,7 @@ gtk_tree_add (GtkContainer *container,
   g_return_if_fail (container != NULL);
   g_return_if_fail (GTK_IS_TREE (container));
   g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_TREE_ITEM (widget));
 
   tree = GTK_TREE (container);
 
@@ -294,9 +308,12 @@ gtk_tree_button_press (GtkWidget      *widget,
   tree = GTK_TREE (widget);
   item = gtk_get_event_widget ((GdkEvent*) event);
 
-  while (!gtk_type_is_a (GTK_WIDGET_TYPE (item), gtk_tree_item_get_type ()))
+  while (item && !GTK_IS_TREE_ITEM (item))
     item = item->parent;
 
+  if (!item || (item->parent != widget))
+    return FALSE;
+  
   switch(event->button) 
     {
     case 1:
@@ -363,9 +380,39 @@ gtk_tree_clear_items (GtkTree *tree,
                      gint     start,
                      gint     end)
 {
+  GtkWidget *widget;
+  GList *clear_list;
+  GList *tmp_list;
+  guint nchildren;
+  guint index;
+  
   g_return_if_fail (tree != NULL);
   g_return_if_fail (GTK_IS_TREE (tree));
-
+  
+  nchildren = g_list_length (tree->children);
+  
+  if (nchildren > 0)
+    {
+      if ((end < 0) || (end > nchildren))
+       end = nchildren;
+      
+      if (start >= end)
+       return;
+      
+      tmp_list = g_list_nth (tree->children, start);
+      clear_list = NULL;
+      index = start;
+      while (tmp_list && index <= end)
+       {
+         widget = tmp_list->data;
+         tmp_list = tmp_list->next;
+         index++;
+         
+         clear_list = g_list_prepend (clear_list, widget);
+       }
+      
+      gtk_tree_remove_items (tree, clear_list);
+    }
 }
 
 static void
@@ -551,10 +598,13 @@ gtk_tree_map (GtkWidget *widget)
          !GTK_WIDGET_MAPPED (child))
        gtk_widget_map (child);
 
-      if ((child = GTK_WIDGET(GTK_TREE_ITEM(child)->subtree)) &&
-         GTK_WIDGET_VISIBLE (child) &&
-         !GTK_WIDGET_MAPPED (child))
-       gtk_widget_map (child);
+      if (GTK_TREE_ITEM (child)->subtree)
+       {
+         child = GTK_WIDGET (GTK_TREE_ITEM (child)->subtree);
+
+         if (GTK_WIDGET_VISIBLE (child) && !GTK_WIDGET_MAPPED (child))
+           gtk_widget_map (child);
+       }
     }
 }
 
@@ -606,7 +656,7 @@ gtk_tree_realize (GtkWidget *widget)
   attributes.wclass = GDK_INPUT_OUTPUT;
   attributes.visual = gtk_widget_get_visual (widget);
   attributes.colormap = gtk_widget_get_colormap (widget);
-  attributes.event_mask = GDK_EXPOSURE_MASK;
+  attributes.event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
@@ -616,7 +666,6 @@ gtk_tree_realize (GtkWidget *widget)
   widget->style = gtk_style_attach (widget->style, widget->window);
   gdk_window_set_background (widget->window, 
                             &widget->style->base[GTK_STATE_NORMAL]);
-
 }
 
 void
@@ -630,8 +679,7 @@ gtk_tree_remove_item (GtkTree      *container,
   g_return_if_fail (widget != NULL);
   g_return_if_fail (container == GTK_TREE (widget->parent));
 
-  item_list = g_list_alloc ();
-  item_list->data = widget;
+  item_list = g_list_append (NULL, widget);
   
   gtk_tree_remove_items (GTK_TREE (container), item_list);
 
@@ -670,7 +718,20 @@ gtk_tree_remove_items (GtkTree *tree,
   g_print("+ gtk_tree_remove_items [ tree %#x items list %#x ]\n", (int)tree, (int)items);
 #endif /* TREE_DEBUG */
 
-  root_tree = GTK_TREE(GTK_TREE_ROOT_TREE(tree));
+  /* We may not yet be mapped, so we actively have to find our
+   * root tree
+   */
+  if (tree->root_tree)
+    root_tree = tree->root_tree;
+  else
+    {
+      GtkWidget *tmp = GTK_WIDGET (tree);
+      while (tmp->parent && GTK_IS_TREE (tmp->parent))
+       tmp = tmp->parent;
+
+      root_tree = GTK_TREE (tmp);
+    }
+            
   tmp_list = items;
   selected_widgets = NULL;
   sorted_list = NULL;
@@ -679,8 +740,10 @@ gtk_tree_remove_items (GtkTree *tree,
 #ifdef TREE_DEBUG
   g_print("* sort list by depth\n");
 #endif /* TREE_DEBUG */
-  while(tmp_list)
+
+  while (tmp_list)
     {
+
 #ifdef TREE_DEBUG
       g_print("* item [%#x] depth [%d]\n", 
              (int)tmp_list->data,
@@ -709,6 +772,7 @@ gtk_tree_remove_items (GtkTree *tree,
 #ifdef TREE_DEBUG
   g_print("* scan sorted list\n");
 #endif /* TREE_DEBUG */
+
   tmp_list = sorted_list;
   while (tmp_list)
     {
@@ -736,9 +800,9 @@ gtk_tree_remove_items (GtkTree *tree,
 #endif /* TREE_DEBUG */
        }
 
-      /* remove this item of his real parent */
+      /* remove this item from its real parent */
 #ifdef TREE_DEBUG
-      g_print("* remove widget of his owner tree\n");
+      g_print("* remove widget from its owner tree\n");
 #endif /* TREE_DEBUG */
       real_tree->children = g_list_remove (real_tree->children, widget);
 
@@ -835,20 +899,22 @@ gtk_tree_remove_items (GtkTree *tree,
  
 void
 gtk_tree_select_child (GtkTree   *tree,
-                      GtkWidget *child)
+                      GtkWidget *tree_item)
 {
-
-  gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], child);
-
+  g_return_if_fail (tree != NULL);
+  g_return_if_fail (GTK_IS_TREE (tree));
+  g_return_if_fail (tree_item != NULL);
+  g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
+  
+  gtk_signal_emit (GTK_OBJECT (tree), tree_signals[SELECT_CHILD], tree_item);
 }
 
 void
 gtk_tree_select_item (GtkTree   *tree,
-                     gint     item)
+                     gint       item)
 {
   GList *tmp_list;
 
-
   g_return_if_fail (tree != NULL);
   g_return_if_fail (GTK_IS_TREE (tree));
 
@@ -884,7 +950,7 @@ gtk_tree_size_allocate (GtkWidget     *widget,
     {
       child_allocation.x = GTK_CONTAINER (tree)->border_width;
       child_allocation.y = GTK_CONTAINER (tree)->border_width;
-      child_allocation.width = allocation->width - child_allocation.x * 2;
+      child_allocation.width = MAX (1, allocation->width - child_allocation.x * 2);
 
       children = tree->children;
 
@@ -979,9 +1045,14 @@ gtk_tree_unmap (GtkWidget *widget)
 
 void
 gtk_tree_unselect_child (GtkTree   *tree,
-                        GtkWidget *child)
+                        GtkWidget *tree_item)
 {
-  gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], child);
+  g_return_if_fail (tree != NULL);
+  g_return_if_fail (GTK_IS_TREE (tree));
+  g_return_if_fail (tree_item != NULL);
+  g_return_if_fail (GTK_IS_TREE_ITEM (tree_item));
+
+  gtk_signal_emit (GTK_OBJECT (tree), tree_signals[UNSELECT_CHILD], tree_item);
 }
 
 void
@@ -990,7 +1061,6 @@ gtk_tree_unselect_item (GtkTree *tree,
 {
   GList *tmp_list;
 
-
   g_return_if_fail (tree != NULL);
   g_return_if_fail (GTK_IS_TREE (tree));
 
@@ -1008,7 +1078,6 @@ gtk_real_tree_select_child (GtkTree   *tree,
   GList *tmp_list;
   GtkWidget *tmp_item;
 
-
   g_return_if_fail (tree != NULL);
   g_return_if_fail (GTK_IS_TREE (tree));
   g_return_if_fail (child != NULL);
@@ -1129,7 +1198,6 @@ static void
 gtk_real_tree_unselect_child (GtkTree   *tree,
                              GtkWidget *child)
 {
-
   g_return_if_fail (tree != NULL);
   g_return_if_fail (GTK_IS_TREE (tree));
   g_return_if_fail (child != NULL);