]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtktable.c
Estonian translation update by Ivar Smolin.
[~andy/gtk] / gtk / gtktable.c
index e85f122d4a709c904db76ffef912cfebd9b98b01..9002ad3c6c983eac6fe418b315149150efd508c0 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <config.h>
 #include "gtktable.h"
+#include "gtkprivate.h"
 #include "gtkintl.h"
+#include "gtkalias.h"
 
 enum
 {
@@ -51,8 +54,6 @@ enum
 };
   
 
-static void gtk_table_class_init    (GtkTableClass  *klass);
-static void gtk_table_init         (GtkTable       *table);
 static void gtk_table_finalize     (GObject        *object);
 static void gtk_table_size_request  (GtkWidget     *widget,
                                     GtkRequisition *requisition);
@@ -84,7 +85,7 @@ static void gtk_table_get_child_property (GtkContainer    *container,
                                          guint            property_id,
                                          GValue          *value,
                                          GParamSpec      *pspec);
-static GtkType gtk_table_child_type (GtkContainer   *container);
+static GType gtk_table_child_type   (GtkContainer   *container);
 
 
 static void gtk_table_size_request_init         (GtkTable *table);
@@ -97,33 +98,7 @@ static void gtk_table_size_allocate_pass1 (GtkTable *table);
 static void gtk_table_size_allocate_pass2 (GtkTable *table);
 
 
-static GtkContainerClass *parent_class = NULL;
-
-
-GtkType
-gtk_table_get_type (void)
-{
-  static GtkType table_type = 0;
-  
-  if (!table_type)
-    {
-      static const GtkTypeInfo table_info =
-      {
-       "GtkTable",
-       sizeof (GtkTable),
-       sizeof (GtkTableClass),
-       (GtkClassInitFunc) gtk_table_class_init,
-       (GtkObjectInitFunc) gtk_table_init,
-        /* reserved_1 */ NULL,
-       /* reserved_2 */ NULL,
-       (GtkClassInitFunc) NULL,
-      };
-      
-      table_type = gtk_type_unique (gtk_container_get_type (), &table_info);
-    }
-  
-  return table_type;
-}
+G_DEFINE_TYPE (GtkTable, gtk_table, GTK_TYPE_CONTAINER)
 
 static void
 gtk_table_class_init (GtkTableClass *class)
@@ -132,8 +107,6 @@ gtk_table_class_init (GtkTableClass *class)
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (class);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (class);
   
-  parent_class = g_type_class_peek_parent (class);
-
   gobject_class->finalize = gtk_table_finalize;
 
   gobject_class->get_property = gtk_table_get_property;
@@ -152,91 +125,107 @@ gtk_table_class_init (GtkTableClass *class)
 
   g_object_class_install_property (gobject_class,
                                    PROP_N_ROWS,
-                                   g_param_spec_uint ("n_rows",
-                                                    _("Rows"),
-                                                    _("The number of rows in the table"),
+                                   g_param_spec_uint ("n-rows",
+                                                    P_("Rows"),
+                                                    P_("The number of rows in the table"),
                                                     0,
                                                     G_MAXUINT,
                                                     0,
-                                                    G_PARAM_READWRITE));
+                                                    GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                    PROP_N_COLUMNS,
-                                   g_param_spec_uint ("n_columns",
-                                                    _("Columns"),
-                                                    _("The number of columns in the table"),
+                                   g_param_spec_uint ("n-columns",
+                                                    P_("Columns"),
+                                                    P_("The number of columns in the table"),
                                                     0,
                                                     G_MAXUINT,
                                                     0,
-                                                    G_PARAM_READWRITE));
+                                                    GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                    PROP_ROW_SPACING,
-                                   g_param_spec_uint ("row_spacing",
-                                                    _("Row spacing"),
-                                                    _("The amount of space between two consecutive rows"),
+                                   g_param_spec_uint ("row-spacing",
+                                                    P_("Row spacing"),
+                                                    P_("The amount of space between two consecutive rows"),
                                                     0,
                                                     G_MAXUINT,
                                                     0,
-                                                    G_PARAM_READWRITE));
+                                                    GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                    PROP_COLUMN_SPACING,
-                                   g_param_spec_uint ("column_spacing",
-                                                    _("Column spacing"),
-                                                    _("The amount of space between two consecutive columns"),
+                                   g_param_spec_uint ("column-spacing",
+                                                    P_("Column spacing"),
+                                                    P_("The amount of space between two consecutive columns"),
                                                     0,
                                                     G_MAXUINT,
                                                     0,
-                                                    G_PARAM_READWRITE));
+                                                    GTK_PARAM_READWRITE));
   g_object_class_install_property (gobject_class,
                                    PROP_HOMOGENEOUS,
                                    g_param_spec_boolean ("homogeneous",
-                                                        _("Homogenous"),
-                                                        _("If TRUE this means the table cells are all the same width/height"),
+                                                        P_("Homogeneous"),
+                                                        P_("If TRUE, the table cells are all the same width/height"),
                                                         FALSE,
-                                                        G_PARAM_READWRITE));
+                                                        GTK_PARAM_READWRITE));
 
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_LEFT_ATTACH,
-                                             g_param_spec_uint ("left_attach", NULL, NULL,
+                                             g_param_spec_uint ("left-attach", 
+                                                                P_("Left attachment"), 
+                                                                P_("The column number to attach the left side of the child to"),
                                                                 0, 65535, 0,
-                                                                G_PARAM_READWRITE));
+                                                                GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_RIGHT_ATTACH,
-                                             g_param_spec_uint ("right_attach", NULL, NULL,
+                                             g_param_spec_uint ("right-attach", 
+                                                                P_("Right attachment"), 
+                                                                P_("The column number to attach the right side of a child widget to"),
                                                                 1, 65535, 1,
-                                                                G_PARAM_READWRITE));
+                                                                GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_TOP_ATTACH,
-                                             g_param_spec_uint ("top_attach", NULL, NULL,
+                                             g_param_spec_uint ("top-attach", 
+                                                                P_("Top attachment"), 
+                                                                P_("The row number to attach the top of a child widget to"),
                                                                 0, 65535, 0,
-                                                                G_PARAM_READWRITE));
+                                                                GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_BOTTOM_ATTACH,
-                                             g_param_spec_uint ("bottom_attach", NULL, NULL,
+                                             g_param_spec_uint ("bottom-attach",
+                                                                P_("Bottom attachment"), 
+                                                                P_("The row number to attach the bottom of the child to"),
                                                                 1, 65535, 1,
-                                                                G_PARAM_READWRITE));
+                                                                GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_X_OPTIONS,
-                                             g_param_spec_flags ("x_options", NULL, NULL,
+                                             g_param_spec_flags ("x-options", 
+                                                                 P_("Horizontal options"), 
+                                                                 P_("Options specifying the horizontal behaviour of the child"),
                                                                  GTK_TYPE_ATTACH_OPTIONS, GTK_EXPAND | GTK_FILL,
-                                                                 G_PARAM_READWRITE));
+                                                                 GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_Y_OPTIONS,
-                                             g_param_spec_flags ("y_options", NULL, NULL,
+                                             g_param_spec_flags ("y-options", 
+                                                                 P_("Vertical options"), 
+                                                                 P_("Options specifying the vertical behaviour of the child"),
                                                                  GTK_TYPE_ATTACH_OPTIONS, GTK_EXPAND | GTK_FILL,
-                                                                 G_PARAM_READWRITE));
+                                                                 GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_X_PADDING,
-                                             g_param_spec_uint ("x_padding", NULL, NULL,
+                                             g_param_spec_uint ("x-padding", 
+                                                                P_("Horizontal padding"), 
+                                                                P_("Extra space to put between the child and its left and right neighbors, in pixels"),
                                                                 0, 65535, 0,
-                                                                G_PARAM_READWRITE));
+                                                                GTK_PARAM_READWRITE));
   gtk_container_class_install_child_property (container_class,
                                              CHILD_PROP_Y_PADDING,
-                                             g_param_spec_uint ("y_padding", NULL, NULL,
+                                             g_param_spec_uint ("y-padding", 
+                                                                P_("Vertical padding"), 
+                                                                P_("Extra space to put between the child and its upper and lower neighbors, in pixels"),
                                                                 0, 65535, 0,
-                                                                G_PARAM_READWRITE));
+                                                                GTK_PARAM_READWRITE));
 }
 
-static GtkType
+static GType
 gtk_table_child_type (GtkContainer   *container)
 {
   return GTK_TYPE_WIDGET;
@@ -340,14 +329,14 @@ gtk_table_set_child_property (GtkContainer    *container,
       if (table_child->right_attach <= table_child->left_attach)
        table_child->right_attach = table_child->left_attach + 1;
       if (table_child->right_attach >= table->ncols)
-       gtk_table_resize (table, table->ncols, table_child->right_attach);
+       gtk_table_resize (table, table->nrows, table_child->right_attach);
       break;
     case CHILD_PROP_RIGHT_ATTACH:
       table_child->right_attach = g_value_get_uint (value);
       if (table_child->right_attach <= table_child->left_attach)
        table_child->left_attach = table_child->right_attach - 1;
       if (table_child->right_attach >= table->ncols)
-       gtk_table_resize (table, table->ncols, table_child->right_attach);
+       gtk_table_resize (table, table->nrows, table_child->right_attach);
       break;
     case CHILD_PROP_TOP_ATTACH:
       table_child->top_attach = g_value_get_uint (value);
@@ -452,6 +441,7 @@ static void
 gtk_table_init (GtkTable *table)
 {
   GTK_WIDGET_SET_FLAGS (table, GTK_NO_WINDOW);
+  gtk_widget_set_redraw_on_allocate (GTK_WIDGET (table), FALSE);
   
   table->children = NULL;
   table->rows = NULL;
@@ -473,11 +463,11 @@ gtk_table_new (guint      rows,
   GtkTable *table;
 
   if (rows == 0)
-         rows = 1;
+    rows = 1;
   if (columns == 0)
-         columns = 1;
+    columns = 1;
   
-  table = gtk_type_new (gtk_table_get_type ());
+  table = g_object_new (GTK_TYPE_TABLE, NULL);
   
   table->homogeneous = (homogeneous ? TRUE : FALSE);
 
@@ -493,7 +483,7 @@ gtk_table_resize (GtkTable *table,
 {
   g_return_if_fail (GTK_IS_TABLE (table));
   g_return_if_fail (n_rows > 0 && n_rows < 65536);
-  g_return_if_fail (n_rows > 0 && n_cols < 65536);
+  g_return_if_fail (n_cols > 0 && n_cols < 65536);
 
   n_rows = MAX (n_rows, 1);
   n_cols = MAX (n_cols, 1);
@@ -532,7 +522,7 @@ gtk_table_resize (GtkTable *table,
              table->rows[i].shrink = 0;
            }
 
-         g_object_notify (G_OBJECT (table), "n_rows");
+         g_object_notify (G_OBJECT (table), "n-rows");
        }
 
       if (n_cols != table->ncols)
@@ -554,7 +544,7 @@ gtk_table_resize (GtkTable *table,
              table->cols[i].shrink = 0;
            }
 
-         g_object_notify (G_OBJECT (table), "n_columns");
+         g_object_notify (G_OBJECT (table), "n-columns");
        }
     }
 }
@@ -639,8 +629,6 @@ gtk_table_set_row_spacing (GtkTable *table,
       if (GTK_WIDGET_VISIBLE (table))
        gtk_widget_queue_resize (GTK_WIDGET (table));
     }
-
-  g_object_notify (G_OBJECT (table), "row_spacing");
 }
 
 /**
@@ -678,14 +666,12 @@ gtk_table_set_col_spacing (GtkTable *table,
       if (GTK_WIDGET_VISIBLE (table))
        gtk_widget_queue_resize (GTK_WIDGET (table));
     }
-
-  g_object_notify (G_OBJECT (table), "column_spacing");
 }
 
 /**
  * gtk_table_get_col_spacing:
  * @table: a #GtkTable
- * @col: a column in the table, 0 indicates the first column
+ * @column: a column in the table, 0 indicates the first column
  *
  * Gets the amount of space between column @col, and
  * column @col + 1. See gtk_table_set_col_spacing().
@@ -716,6 +702,8 @@ gtk_table_set_row_spacings (GtkTable *table,
   
   if (GTK_WIDGET_VISIBLE (table))
     gtk_widget_queue_resize (GTK_WIDGET (table));
+
+  g_object_notify (G_OBJECT (table), "row-spacing");
 }
 
 /**
@@ -750,6 +738,8 @@ gtk_table_set_col_spacings (GtkTable *table,
   
   if (GTK_WIDGET_VISIBLE (table))
     gtk_widget_queue_resize (GTK_WIDGET (table));
+
+  g_object_notify (G_OBJECT (table), "column-spacing");
 }
 
 /**
@@ -783,6 +773,8 @@ gtk_table_set_homogeneous (GtkTable *table,
       
       if (GTK_WIDGET_VISIBLE (table))
        gtk_widget_queue_resize (GTK_WIDGET (table));
+
+      g_object_notify (G_OBJECT (table), "homogeneous");
     }
 }
 
@@ -815,7 +807,7 @@ gtk_table_finalize (GObject *object)
   g_free (table->rows);
   g_free (table->cols);
   
-  G_OBJECT_CLASS (parent_class)->finalize (object);
+  G_OBJECT_CLASS (gtk_table_parent_class)->finalize (object);
 }
 
 static void
@@ -909,7 +901,7 @@ gtk_table_remove (GtkContainer *container,
          g_free (child);
          
          if (was_visible && GTK_WIDGET_VISIBLE (container))
-           gtk_container_queue_resize (container);
+           gtk_widget_queue_resize (GTK_WIDGET (container));
          break;
        }
     }
@@ -948,9 +940,15 @@ gtk_table_size_request_init (GtkTable *table)
   gint row, col;
   
   for (row = 0; row < table->nrows; row++)
-    table->rows[row].requisition = 0;
+    {
+      table->rows[row].requisition = 0;
+      table->rows[row].expand = FALSE;
+    }
   for (col = 0; col < table->ncols; col++)
-    table->cols[col].requisition = 0;
+    {
+      table->cols[col].requisition = 0;
+      table->cols[col].expand = FALSE;
+    }
   
   children = table->children;
   while (children)
@@ -960,6 +958,12 @@ gtk_table_size_request_init (GtkTable *table)
       
       if (GTK_WIDGET_VISIBLE (child->widget))
        gtk_widget_size_request (child->widget, NULL);
+
+      if (child->left_attach == (child->right_attach - 1) && child->xexpand)
+       table->cols[child->left_attach].expand = TRUE;
+      
+      if (child->top_attach == (child->bottom_attach - 1) && child->yexpand)
+       table->rows[child->top_attach].expand = TRUE;
     }
 }
 
@@ -1062,19 +1066,34 @@ gtk_table_size_request_pass3 (GtkTable *table)
                }
              
              /* If we need to request more space for this child to fill
-              *  its requisition, then divide up the needed space evenly
-              *  amongst the columns it spans.
+              *  its requisition, then divide up the needed space amongst the
+              *  columns it spans, favoring expandable columns if any.
               */
              if (width < child_requisition.width + child->xpadding * 2)
                {
-                 width = child_requisition.width + child->xpadding * 2 - width;
+                 gint n_expand = 0;
+                 gboolean force_expand = FALSE;
                  
+                 width = child_requisition.width + child->xpadding * 2 - width;
+
                  for (col = child->left_attach; col < child->right_attach; col++)
+                   if (table->cols[col].expand)
+                     n_expand++;
+
+                 if (n_expand == 0)
                    {
-                     extra = width / (child->right_attach - col);
-                     table->cols[col].requisition += extra;
-                     width -= extra;
+                     n_expand = (child->right_attach - child->left_attach);
+                     force_expand = TRUE;
                    }
+                   
+                 for (col = child->left_attach; col < child->right_attach; col++)
+                   if (force_expand || table->cols[col].expand)
+                     {
+                       extra = width / n_expand;
+                       table->cols[col].requisition += extra;
+                       width -= extra;
+                       n_expand--;
+                     }
                }
            }
          
@@ -1098,19 +1117,36 @@ gtk_table_size_request_pass3 (GtkTable *table)
                }
              
              /* If we need to request more space for this child to fill
-              *  its requisition, then divide up the needed space evenly
-              *  amongst the columns it spans.
+              *  its requisition, then divide up the needed space amongst the
+              *  rows it spans, favoring expandable rows if any.
               */
              if (height < child_requisition.height + child->ypadding * 2)
                {
+                 gint n_expand = 0;
+                 gboolean force_expand = FALSE;
+                 
                  height = child_requisition.height + child->ypadding * 2 - height;
                  
                  for (row = child->top_attach; row < child->bottom_attach; row++)
                    {
-                     extra = height / (child->bottom_attach - row);
-                     table->rows[row].requisition += extra;
-                     height -= extra;
+                     if (table->rows[row].expand)
+                       n_expand++;
+                   }
+
+                 if (n_expand == 0)
+                   {
+                     n_expand = (child->bottom_attach - child->top_attach);
+                     force_expand = TRUE;
                    }
+                   
+                 for (row = child->top_attach; row < child->bottom_attach; row++)
+                   if (force_expand || table->rows[row].expand)
+                     {
+                       extra = height / n_expand;
+                       table->rows[row].requisition += extra;
+                       height -= extra;
+                       n_expand--;
+                     }
                }
            }
        }
@@ -1332,18 +1368,21 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
   
   if (table->homogeneous)
     {
-      nexpand = 0;
-      for (col = 0; col < table->ncols; col++)
-       if (table->cols[col].expand)
-         {
-           nexpand += 1;
-           break;
-         }
-      
-      if (nexpand > 0)
+      if (!table->children)
+       nexpand = 1;
+      else
+       {
+         nexpand = 0;
+         for (col = 0; col < table->ncols; col++)
+           if (table->cols[col].expand)
+             {
+               nexpand += 1;
+               break;
+             }
+       }
+      if (nexpand)
        {
          width = real_width;
-         
          for (col = 0; col + 1 < table->ncols; col++)
            width -= table->cols[col].spacing;
          
@@ -1420,15 +1459,19 @@ gtk_table_size_allocate_pass1 (GtkTable *table)
   
   if (table->homogeneous)
     {
-      nexpand = 0;
-      for (row = 0; row < table->nrows; row++)
-       if (table->rows[row].expand)
-         {
-           nexpand += 1;
-           break;
-         }
-      
-      if (nexpand > 0)
+      if (!table->children)
+       nexpand = 1;
+      else
+       {
+         nexpand = 0;
+         for (row = 0; row < table->nrows; row++)
+           if (table->rows[row].expand)
+             {
+               nexpand += 1;
+               break;
+             }
+       }
+      if (nexpand)
        {
          height = real_height;
          
@@ -1592,3 +1635,6 @@ gtk_table_size_allocate_pass2 (GtkTable *table)
        }
     }
 }
+
+#define __GTK_TABLE_C__
+#include "gtkaliasdef.c"