]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkbox.c
Fix typo: Italian uses ISO-8859-1, not -2. Add en_GB.
[~andy/gtk] / gtk / gtkbox.c
index b63873ca74acc84d26dc12779999d20d14325dff..5c94a272bdae3e5d073ba37b2b9f27fbb9c971f5 100644 (file)
  * 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.
  */
+
+/*
+ * Modified by the GTK+ Team and others 1997-1999.  See the AUTHORS
+ * file for a list of people on the GTK+ Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
 #include "gtkbox.h"
 
 enum {
@@ -23,15 +32,23 @@ enum {
   ARG_HOMOGENEOUS
 };
 
+enum {
+  CHILD_ARG_0,
+  CHILD_ARG_EXPAND,
+  CHILD_ARG_FILL,
+  CHILD_ARG_PADDING,
+  CHILD_ARG_PACK_TYPE,
+  CHILD_ARG_POSITION
+};
+
 static void gtk_box_class_init (GtkBoxClass    *klass);
 static void gtk_box_init       (GtkBox         *box);
-static void gtk_box_get_arg    (GtkBox         *box,
+static void gtk_box_get_arg    (GtkObject      *object,
                                GtkArg         *arg,
                                guint           arg_id);
-static void gtk_box_set_arg    (GtkBox         *box,
+static void gtk_box_set_arg    (GtkObject      *object,
                                GtkArg         *arg,
                                guint           arg_id);
-static void gtk_box_destroy    (GtkObject      *object);
 static void gtk_box_map        (GtkWidget      *widget);
 static void gtk_box_unmap      (GtkWidget      *widget);
 static void gtk_box_draw       (GtkWidget      *widget,
@@ -42,33 +59,44 @@ static void gtk_box_add        (GtkContainer   *container,
                                GtkWidget      *widget);
 static void gtk_box_remove     (GtkContainer   *container,
                                GtkWidget      *widget);
-static void gtk_box_foreach    (GtkContainer   *container,
+static void gtk_box_forall     (GtkContainer   *container,
+                               gboolean        include_internals,
                                GtkCallback     callback,
                                gpointer        callback_data);
-
+static void gtk_box_set_child_arg (GtkContainer   *container,
+                                  GtkWidget      *child,
+                                  GtkArg         *arg,
+                                  guint           arg_id);
+static void gtk_box_get_child_arg (GtkContainer   *container,
+                                  GtkWidget      *child,
+                                  GtkArg         *arg,
+                                  guint           arg_id);
+static GtkType gtk_box_child_type (GtkContainer   *container);
+     
 
 static GtkContainerClass *parent_class = NULL;
 
 
-guint
-gtk_box_get_type ()
+GtkType
+gtk_box_get_type (void)
 {
-  static guint box_type = 0;
+  static GtkType box_type = 0;
 
   if (!box_type)
     {
-      GtkTypeInfo box_info =
+      static const GtkTypeInfo box_info =
       {
        "GtkBox",
        sizeof (GtkBox),
        sizeof (GtkBoxClass),
        (GtkClassInitFunc) gtk_box_class_init,
        (GtkObjectInitFunc) gtk_box_init,
-       (GtkArgSetFunc) gtk_box_set_arg,
-        (GtkArgGetFunc) gtk_box_get_arg,
+        /* reserved_1 */ NULL,
+       /* reserved_2 */ NULL,
+       (GtkClassInitFunc) NULL,
       };
 
-      box_type = gtk_type_unique (gtk_container_get_type (), &box_info);
+      box_type = gtk_type_unique (GTK_TYPE_CONTAINER, &box_info);
     }
 
   return box_type;
@@ -85,12 +113,18 @@ gtk_box_class_init (GtkBoxClass *class)
   widget_class = (GtkWidgetClass*) class;
   container_class = (GtkContainerClass*) class;
 
-  parent_class = gtk_type_class (gtk_container_get_type ());
+  parent_class = gtk_type_class (GTK_TYPE_CONTAINER);
 
-  gtk_object_add_arg_type ("GtkBox::spacing", GTK_TYPE_INT, ARG_SPACING);
-  gtk_object_add_arg_type ("GtkBox::homogeneous", GTK_TYPE_BOOL, ARG_HOMOGENEOUS);
+  gtk_object_add_arg_type ("GtkBox::spacing", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_SPACING);
+  gtk_object_add_arg_type ("GtkBox::homogeneous", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_HOMOGENEOUS);
+  gtk_container_add_child_arg_type ("GtkBox::expand", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_EXPAND);
+  gtk_container_add_child_arg_type ("GtkBox::fill", GTK_TYPE_BOOL, GTK_ARG_READWRITE, CHILD_ARG_FILL);
+  gtk_container_add_child_arg_type ("GtkBox::padding", GTK_TYPE_ULONG, GTK_ARG_READWRITE, CHILD_ARG_PADDING);
+  gtk_container_add_child_arg_type ("GtkBox::pack_type", GTK_TYPE_PACK_TYPE, GTK_ARG_READWRITE, CHILD_ARG_PACK_TYPE);
+  gtk_container_add_child_arg_type ("GtkBox::position", GTK_TYPE_LONG, GTK_ARG_READWRITE, CHILD_ARG_POSITION);
 
-  object_class->destroy = gtk_box_destroy;
+  object_class->set_arg = gtk_box_set_arg;
+  object_class->get_arg = gtk_box_get_arg;
 
   widget_class->map = gtk_box_map;
   widget_class->unmap = gtk_box_unmap;
@@ -99,13 +133,16 @@ gtk_box_class_init (GtkBoxClass *class)
 
   container_class->add = gtk_box_add;
   container_class->remove = gtk_box_remove;
-  container_class->foreach = gtk_box_foreach;
+  container_class->forall = gtk_box_forall;
+  container_class->child_type = gtk_box_child_type;
+  container_class->set_child_arg = gtk_box_set_child_arg;
+  container_class->get_child_arg = gtk_box_get_child_arg;
 }
 
 static void
 gtk_box_init (GtkBox *box)
 {
-  GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW | GTK_BASIC);
+  GTK_WIDGET_SET_FLAGS (box, GTK_NO_WINDOW);
 
   box->children = NULL;
   box->spacing = 0;
@@ -113,10 +150,14 @@ gtk_box_init (GtkBox *box)
 }
 
 static void
-gtk_box_set_arg (GtkBox       *box,
+gtk_box_set_arg (GtkObject    *object,
                 GtkArg       *arg,
                 guint         arg_id)
 {
+  GtkBox *box;
+
+  box = GTK_BOX (object);
+
   switch (arg_id)
     {
     case ARG_SPACING:
@@ -125,14 +166,20 @@ gtk_box_set_arg (GtkBox       *box,
     case ARG_HOMOGENEOUS:
       gtk_box_set_homogeneous (box, GTK_VALUE_BOOL (*arg));
       break;
+    default:
+      break;
     }
 }
 
 static void
-gtk_box_get_arg (GtkBox       *box,
+gtk_box_get_arg (GtkObject    *object,
                 GtkArg       *arg,
                 guint         arg_id)
 {
+  GtkBox *box;
+
+  box = GTK_BOX (object);
+
   switch (arg_id)
     {
     case ARG_SPACING:
@@ -147,18 +194,142 @@ gtk_box_get_arg (GtkBox       *box,
     }
 }
 
+static GtkType
+gtk_box_child_type     (GtkContainer   *container)
+{
+  return GTK_TYPE_WIDGET;
+}
+
+static void
+gtk_box_set_child_arg (GtkContainer   *container,
+                      GtkWidget      *child,
+                      GtkArg         *arg,
+                      guint           arg_id)
+{
+  gboolean expand = 0;
+  gboolean fill = 0;
+  guint padding = 0;
+  GtkPackType pack_type = 0;
+
+  if (arg_id != CHILD_ARG_POSITION)
+    gtk_box_query_child_packing (GTK_BOX (container),
+                                child,
+                                &expand,
+                                &fill,
+                                &padding,
+                                &pack_type);
+  
+  switch (arg_id)
+    {
+    case CHILD_ARG_EXPAND:
+      gtk_box_set_child_packing (GTK_BOX (container),
+                                child,
+                                GTK_VALUE_BOOL (*arg),
+                                fill,
+                                padding,
+                                pack_type);
+      break;
+    case CHILD_ARG_FILL:
+      gtk_box_set_child_packing (GTK_BOX (container),
+                                child,
+                                expand,
+                                GTK_VALUE_BOOL (*arg),
+                                padding,
+                                pack_type);
+      break;
+    case CHILD_ARG_PADDING:
+      gtk_box_set_child_packing (GTK_BOX (container),
+                                child,
+                                expand,
+                                fill,
+                                GTK_VALUE_ULONG (*arg),
+                                pack_type);
+      break;
+    case CHILD_ARG_PACK_TYPE:
+      gtk_box_set_child_packing (GTK_BOX (container),
+                                child,
+                                expand,
+                                fill,
+                                padding,
+                                GTK_VALUE_ENUM (*arg));
+      break;
+    case CHILD_ARG_POSITION:
+      gtk_box_reorder_child (GTK_BOX (container),
+                            child,
+                            GTK_VALUE_LONG (*arg));
+      break;
+    default:
+      break;
+    }
+}
+
+static void
+gtk_box_get_child_arg (GtkContainer   *container,
+                      GtkWidget      *child,
+                      GtkArg         *arg,
+                      guint           arg_id)
+{
+  gboolean expand = 0;
+  gboolean fill = 0;
+  guint padding = 0;
+  GtkPackType pack_type = 0;
+  GList *list;
+
+  if (arg_id != CHILD_ARG_POSITION)
+    gtk_box_query_child_packing (GTK_BOX (container),
+                                child,
+                                &expand,
+                                &fill,
+                                &padding,
+                                &pack_type);
+  
+  switch (arg_id)
+    {
+    case CHILD_ARG_EXPAND:
+      GTK_VALUE_BOOL (*arg) = expand;
+      break;
+    case CHILD_ARG_FILL:
+      GTK_VALUE_BOOL (*arg) = fill;
+      break;
+    case CHILD_ARG_PADDING:
+      GTK_VALUE_ULONG (*arg) = padding;
+      break;
+    case CHILD_ARG_PACK_TYPE:
+      GTK_VALUE_ENUM (*arg) = pack_type;
+      break;
+    case CHILD_ARG_POSITION:
+      GTK_VALUE_LONG (*arg) = 0;
+      for (list = GTK_BOX (container)->children; list; list = list->next)
+       {
+         GtkBoxChild *child_entry;
+
+         child_entry = list->data;
+         if (child_entry->widget == child)
+           break;
+         GTK_VALUE_LONG (*arg)++;
+       }
+      if (!list)
+       GTK_VALUE_LONG (*arg) = -1;
+      break;
+    default:
+      arg->type = GTK_TYPE_INVALID;
+      break;
+    }
+}
+
 void
 gtk_box_pack_start (GtkBox    *box,
                    GtkWidget *child,
-                   gint       expand,
-                   gint       fill,
-                   gint       padding)
+                   gboolean   expand,
+                   gboolean   fill,
+                   guint      padding)
 {
   GtkBoxChild *child_info;
 
   g_return_if_fail (box != NULL);
   g_return_if_fail (GTK_IS_BOX (box));
   g_return_if_fail (child != NULL);
+  g_return_if_fail (child->parent == NULL);
 
   child_info = g_new (GtkBoxChild, 1);
   child_info->widget = child;
@@ -170,34 +341,32 @@ gtk_box_pack_start (GtkBox    *box,
   box->children = g_list_append (box->children, child_info);
 
   gtk_widget_set_parent (child, GTK_WIDGET (box));
+  
+  if (GTK_WIDGET_REALIZED (box))
+    gtk_widget_realize (child);
 
-  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
+  if (GTK_WIDGET_VISIBLE (box) && GTK_WIDGET_VISIBLE (child))
     {
-      if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
-         !GTK_WIDGET_REALIZED (child))
-       gtk_widget_realize (child);
-      
-      if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
-         !GTK_WIDGET_MAPPED (child))
+      if (GTK_WIDGET_MAPPED (box))
        gtk_widget_map (child);
-    }
 
-  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
-    gtk_widget_queue_resize (child);
+      gtk_widget_queue_resize (child);
+    }
 }
 
 void
 gtk_box_pack_end (GtkBox    *box,
                  GtkWidget *child,
-                 gint       expand,
-                 gint       fill,
-                 gint       padding)
+                 gboolean   expand,
+                 gboolean   fill,
+                 guint      padding)
 {
   GtkBoxChild *child_info;
 
   g_return_if_fail (box != NULL);
   g_return_if_fail (GTK_IS_BOX (box));
   g_return_if_fail (child != NULL);
+  g_return_if_fail (child->parent == NULL);
 
   child_info = g_new (GtkBoxChild, 1);
   child_info->widget = child;
@@ -210,19 +379,16 @@ gtk_box_pack_end (GtkBox    *box,
 
   gtk_widget_set_parent (child, GTK_WIDGET (box));
 
-  if (GTK_WIDGET_VISIBLE (GTK_WIDGET (box)))
+  if (GTK_WIDGET_REALIZED (box))
+    gtk_widget_realize (child);
+
+  if (GTK_WIDGET_VISIBLE (box) && GTK_WIDGET_VISIBLE (child))
     {
-      if (GTK_WIDGET_REALIZED (GTK_WIDGET (box)) &&
-         !GTK_WIDGET_REALIZED (child))
-       gtk_widget_realize (child);
-      
-      if (GTK_WIDGET_MAPPED (GTK_WIDGET (box)) &&
-         !GTK_WIDGET_MAPPED (child))
+      if (GTK_WIDGET_MAPPED (box))
        gtk_widget_map (child);
+
+      gtk_widget_queue_resize (child);
     }
-  
-  if (GTK_WIDGET_VISIBLE (child) && GTK_WIDGET_VISIBLE (box))
-    gtk_widget_queue_resize (child);
 }
 
 void
@@ -248,8 +414,8 @@ gtk_box_pack_end_defaults (GtkBox    *box,
 }
 
 void
-gtk_box_set_homogeneous (GtkBox *box,
-                        gint    homogeneous)
+gtk_box_set_homogeneous (GtkBox  *box,
+                        gboolean homogeneous)
 {
   g_return_if_fail (box != NULL);
   g_return_if_fail (GTK_IS_BOX (box));
@@ -278,7 +444,7 @@ gtk_box_set_spacing (GtkBox *box,
 void
 gtk_box_reorder_child (GtkBox                   *box,
                       GtkWidget                *child,
-                      guint                    pos)
+                      gint                      position)
 {
   GList *list;
 
@@ -310,13 +476,13 @@ gtk_box_reorder_child (GtkBox                   *box,
        box->children = list->next;
 
       tmp_list = box->children;
-      while (pos && tmp_list->next)
+      while (position && tmp_list->next)
        {
-         pos--;
+         position--;
          tmp_list = tmp_list->next;
        }
 
-      if (pos)
+      if (position)
        {
          tmp_list->next = list;
          list->prev = tmp_list;
@@ -341,13 +507,13 @@ gtk_box_reorder_child (GtkBox                   *box,
 void
 gtk_box_query_child_packing (GtkBox             *box,
                             GtkWidget          *child,
-                            gint               *expand,
-                            gint               *fill,
-                            gint               *padding,
+                            gboolean           *expand,
+                            gboolean           *fill,
+                            guint              *padding,
                             GtkPackType        *pack_type)
 {
   GList *list;
-  GtkBoxChild *child_info;
+  GtkBoxChild *child_info = NULL;
 
   g_return_if_fail (box != NULL);
   g_return_if_fail (GTK_IS_BOX (box));
@@ -379,13 +545,13 @@ gtk_box_query_child_packing (GtkBox             *box,
 void
 gtk_box_set_child_packing (GtkBox               *box,
                           GtkWidget            *child,
-                          gint                 expand,
-                          gint                 fill,
-                          gint                 padding,
-                          GtkPackType          pack_type)
+                          gboolean              expand,
+                          gboolean              fill,
+                          guint                 padding,
+                          GtkPackType           pack_type)
 {
   GList *list;
-  GtkBoxChild *child_info;
+  GtkBoxChild *child_info = NULL;
 
   g_return_if_fail (box != NULL);
   g_return_if_fail (GTK_IS_BOX (box));
@@ -416,37 +582,6 @@ gtk_box_set_child_packing (GtkBox               *box,
     }
 }
 
-
-static void
-gtk_box_destroy (GtkObject *object)
-{
-  GtkBox *box;
-  GtkBoxChild *child;
-  GList *children;
-
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_BOX (object));
-
-  box = GTK_BOX (object);
-
-  children = box->children;
-  while (children)
-    {
-      child = children->data;
-      children = children->next;
-
-      child->widget->parent = NULL;
-      gtk_object_unref (GTK_OBJECT (child->widget));
-      gtk_widget_destroy (child->widget);
-      g_free (child);
-    }
-
-  g_list_free (box->children);
-
-  if (GTK_OBJECT_CLASS (parent_class)->destroy)
-    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
-
 static void
 gtk_box_map (GtkWidget *widget)
 {
@@ -505,21 +640,22 @@ gtk_box_draw (GtkWidget    *widget,
   GtkBoxChild *child;
   GdkRectangle child_area;
   GList *children;
-
+  
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_BOX (widget));
-
+   
   if (GTK_WIDGET_DRAWABLE (widget))
     {
       box = GTK_BOX (widget);
-
+       
       children = box->children;
       while (children)
        {
          child = children->data;
          children = children->next;
-
-         if (gtk_widget_intersect (child->widget, area, &child_area))
+            
+         if (GTK_WIDGET_DRAWABLE (child->widget) &&
+             gtk_widget_intersect (child->widget, area, &child_area))
            gtk_widget_draw (child->widget, &child_area);
        }
     }
@@ -550,7 +686,8 @@ gtk_box_expose (GtkWidget      *widget,
          child = children->data;
          children = children->next;
 
-         if (GTK_WIDGET_NO_WINDOW (child->widget) &&
+         if (GTK_WIDGET_DRAWABLE (child->widget) &&
+             GTK_WIDGET_NO_WINDOW (child->widget) &&
              gtk_widget_intersect (child->widget, &event->area, &child_event.area))
            gtk_widget_event (child->widget, (GdkEvent*) &child_event);
        }
@@ -591,13 +728,19 @@ gtk_box_remove (GtkContainer *container,
 
       if (child->widget == widget)
        {
+         gboolean was_visible;
+
+         was_visible = GTK_WIDGET_VISIBLE (widget);
          gtk_widget_unparent (widget);
 
          box->children = g_list_remove_link (box->children, children);
          g_list_free (children);
          g_free (child);
 
-         if (GTK_WIDGET_VISIBLE (widget) && GTK_WIDGET_VISIBLE (container))
+         /* queue resize regardless of GTK_WIDGET_VISIBLE (container),
+          * since that's what is needed by toplevels.
+          */
+         if (was_visible)
            gtk_widget_queue_resize (GTK_WIDGET (container));
 
          break;
@@ -608,9 +751,10 @@ gtk_box_remove (GtkContainer *container,
 }
 
 static void
-gtk_box_foreach (GtkContainer *container,
-                GtkCallback   callback,
-                gpointer      callback_data)
+gtk_box_forall (GtkContainer *container,
+               gboolean      include_internals,
+               GtkCallback   callback,
+               gpointer      callback_data)
 {
   GtkBox *box;
   GtkBoxChild *child;