Added a cell-padding parameter to the sheet.
authorJohn Darrington <john@darrington.wattle.id.au>
Mon, 6 Apr 2009 11:07:30 +0000 (19:07 +0800)
committerJohn Darrington <john@darrington.wattle.id.au>
Mon, 6 Apr 2009 11:07:30 +0000 (19:07 +0800)
Added a cell-padding paramter of type GtkBorder which specifies the
space between a cell's contents and the border.  The text is no
longer squashed right up against the left hand edge.

lib/gtk-contrib/psppire-sheet.c
lib/gtk-contrib/psppire-sheet.h
src/ui/gui/sheet/psppire-axis.c
src/ui/gui/sheet/psppire-axis.h

index 4119037d9c0ef02ed74e4cf69bb8c35ccdc9f609..33e7b47a0cce90cf7121ab275a78c965d3b66d0a 100644 (file)
@@ -699,6 +699,7 @@ enum
     PROP_0,
     PROP_VAXIS,
     PROP_HAXIS,
+    PROP_CELL_PADDING,
     PROP_MODEL
   };
 
@@ -758,6 +759,7 @@ psppire_sheet_set_vertical_axis (PsppireSheet *sheet, PsppireAxis *a)
     g_object_ref (sheet->vaxis);
 }
 
+static const GtkBorder default_cell_padding = { 3, 3, 2, 2 };
 
 static void
 psppire_sheet_set_property (GObject         *object,
@@ -770,11 +772,37 @@ psppire_sheet_set_property (GObject         *object,
 
   switch (prop_id)
     {
+    case PROP_CELL_PADDING:
+      if ( sheet->cell_padding)
+       g_boxed_free (GTK_TYPE_BORDER, sheet->cell_padding);
+
+      sheet->cell_padding = g_value_dup_boxed (value);
+
+     if (NULL == sheet->cell_padding)
+       sheet->cell_padding = g_boxed_copy (GTK_TYPE_BORDER,
+                                          &default_cell_padding);
+
+     if (sheet->vaxis)
+       g_object_set (sheet->vaxis, "padding",
+                    sheet->cell_padding->top + sheet->cell_padding->bottom,
+                    NULL);
+
+     if (sheet->haxis)
+       g_object_set (sheet->haxis, "padding",
+                    sheet->cell_padding->left + sheet->cell_padding->right,
+                    NULL);
+      break;
     case PROP_VAXIS:
       psppire_sheet_set_vertical_axis (sheet, g_value_get_pointer (value));
+      g_object_set (sheet->vaxis, "padding",
+                   sheet->cell_padding->top + sheet->cell_padding->bottom,
+                   NULL);
       break;
     case PROP_HAXIS:
       psppire_sheet_set_horizontal_axis (sheet, g_value_get_pointer (value));
+      g_object_set (sheet->haxis, "padding",
+                   sheet->cell_padding->left + sheet->cell_padding->right,
+                   NULL);
       break;
     case PROP_MODEL:
       psppire_sheet_set_model (sheet, g_value_get_pointer (value));
@@ -795,6 +823,9 @@ psppire_sheet_get_property (GObject         *object,
 
   switch (prop_id)
     {
+    case PROP_CELL_PADDING:
+      g_value_set_boxed (value, sheet->cell_padding);
+      break;
     case PROP_VAXIS:
       g_value_set_pointer (value, sheet->vaxis);
       break;
@@ -819,6 +850,7 @@ psppire_sheet_class_init (PsppireSheetClass *klass)
   GParamSpec *haxis_spec ;
   GParamSpec *vaxis_spec ;
   GParamSpec *model_spec ;
+  GParamSpec *cell_padding_spec ;
 
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
   GtkContainerClass *container_class = GTK_CONTAINER_CLASS (klass);
@@ -1020,6 +1052,12 @@ psppire_sheet_class_init (PsppireSheetClass *klass)
   object_class->dispose = psppire_sheet_dispose;
   object_class->finalize = psppire_sheet_finalize;
 
+  cell_padding_spec =
+    g_param_spec_boxed ("cell-padding",
+                       "Cell Padding",
+                       "The space between a cell's contents and its border",
+                       GTK_TYPE_BORDER,
+                       G_PARAM_CONSTRUCT | G_PARAM_READABLE | G_PARAM_WRITABLE);
 
   vaxis_spec =
     g_param_spec_pointer ("vertical-axis",
@@ -1051,6 +1089,10 @@ psppire_sheet_class_init (PsppireSheetClass *klass)
                                    PROP_HAXIS,
                                    haxis_spec);
 
+  g_object_class_install_property (object_class,
+                                   PROP_CELL_PADDING,
+                                   cell_padding_spec);
+
   g_object_class_install_property (object_class,
                                    PROP_MODEL,
                                    model_spec);
@@ -1754,6 +1796,9 @@ psppire_sheet_dispose  (GObject *object)
 
   sheet->dispose_has_run = TRUE;
 
+  if ( sheet->cell_padding)
+    g_boxed_free (GTK_TYPE_BORDER, sheet->cell_padding);
+
   if (sheet->model) g_object_unref (sheet->model);
   if (sheet->vaxis) g_object_unref (sheet->vaxis);
   if (sheet->haxis) g_object_unref (sheet->haxis);
@@ -2175,6 +2220,19 @@ psppire_sheet_cell_draw (PsppireSheet *sheet, gint row, gint col)
   if ( !pango_font_description_get_size_is_absolute (font_desc))
     font_height /= PANGO_SCALE;
 
+
+  if ( sheet->cell_padding )
+    {
+      area.x += sheet->cell_padding->left;
+      area.width -= sheet->cell_padding->right
+       + sheet->cell_padding->left;
+
+      area.y += sheet->cell_padding->top;
+      area.height -= sheet->cell_padding->bottom
+       +
+       sheet->cell_padding->top;
+    }
+
   /* Centre the text vertically */
   area.y += (area.height - font_height) / 2.0;
 
@@ -5221,7 +5279,9 @@ set_column_width (PsppireSheet *sheet,
   if ( width <= 0)
     return;
 
-  psppire_axis_resize (sheet->haxis, column, width);
+  psppire_axis_resize (sheet->haxis, column,
+                      width - sheet->cell_padding->left -
+                      sheet->cell_padding->right);
 
   if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)))
     {
@@ -5246,7 +5306,9 @@ set_row_height (PsppireSheet *sheet,
   if (height <= 0)
     return;
 
-  psppire_axis_resize (sheet->vaxis, row, height);
+  psppire_axis_resize (sheet->vaxis, row,
+                      height - sheet->cell_padding->top -
+                      sheet->cell_padding->bottom);
 
   if (GTK_WIDGET_REALIZED (GTK_WIDGET (sheet)) )
     {
index 8e83765cbcfb63494a429978d64162f10f45870c..27c2ed549b2d993cebc916c7573fe7896be3d2b2 100644 (file)
@@ -139,6 +139,9 @@ struct _PsppireSheet
   /* selected range */
   PsppireSheetRange range;
 
+  /* The space between a cell's contents and its border */
+  GtkBorder *cell_padding;
+
   /* the scrolling window and its height and width to
    * make things a little speedier */
   GdkWindow *sheet_window;
index 5ae84d00425089e8441321f287396ad77dbd1d2c..e229c9489f265fc84f2323084d7f1d8e6d260010 100644 (file)
@@ -69,6 +69,29 @@ psppire_axis_dump (const PsppireAxis *a)
   g_debug ("\n");
 }
 
+/* Increment the size of every unit by INC.
+   Note that INC is signed. So if INC is negative,
+   then size will end up smaller.
+*/
+static void
+axis_increment (PsppireAxis *axis, gint inc)
+{
+  struct tower_node *n = tower_first (&axis->pixel_tower);
+
+  while (n)
+    {
+      struct axis_node *an = tower_data (n, struct axis_node, pixel_node);
+      struct tower_node *pn = &an->pixel_node;
+      const gint existing_size = tower_node_get_size (pn);
+
+      tower_resize (&axis->pixel_tower, pn, existing_size + inc *
+                   tower_node_get_size (&an->unit_node));
+
+      n = tower_next (&axis->pixel_tower, n);
+    }
+}
+
+
 /* Return the unit covered by PIXEL */
 gint
 psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel)
@@ -104,15 +127,15 @@ psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel)
 gint
 psppire_axis_unit_count (const PsppireAxis *a)
 {
-  glong padding = 0;
+  glong filler = 0;
   glong actual_size;
 
   actual_size = tower_height (&a->pixel_tower);
 
   if ( actual_size < a->min_extent )
-    padding = DIV_RND_UP (a->min_extent - actual_size, a->default_size);
+    filler = DIV_RND_UP (a->min_extent - actual_size, a->default_size);
 
-  return tower_height (&a->unit_tower) + padding;
+  return tower_height (&a->unit_tower) + filler;
 }
 
 
@@ -216,7 +239,8 @@ enum
   {
     PROP_0,
     PROP_MIN_EXTENT,
-    PROP_DEFAULT_SIZE
+    PROP_DEFAULT_SIZE,
+    PROP_PADDING
   };
 
 
@@ -230,6 +254,9 @@ psppire_axis_get_property (GObject         *object,
 
   switch (prop_id)
     {
+    case PROP_PADDING:
+      g_value_set_int (value, axis->padding);
+      break;
     case PROP_MIN_EXTENT:
       g_value_set_long (value, axis->min_extent);
       break;
@@ -253,6 +280,13 @@ psppire_axis_set_property (GObject         *object,
 
   switch (prop_id)
     {
+    case PROP_PADDING:
+      {
+       const gint old_value = axis->padding;
+       axis->padding = g_value_get_int (value);
+       axis_increment (axis, axis->padding - old_value);
+      }
+      break;
     case PROP_MIN_EXTENT:
       axis->min_extent = g_value_get_long (value);
       break;
@@ -271,7 +305,7 @@ psppire_axis_class_init (PsppireAxisClass *class)
 {
   GObjectClass *object_class = G_OBJECT_CLASS (class);
 
-
+  GParamSpec *padding_spec;
   GParamSpec *min_extent_spec;
   GParamSpec *default_size_spec;
 
@@ -307,6 +341,20 @@ psppire_axis_class_init (PsppireAxisClass *class)
                                    PROP_DEFAULT_SIZE,
                                    default_size_spec);
 
+  padding_spec =
+    g_param_spec_int ("padding",
+                     "Padding",
+                     "Extra space implicitly added to each unit",
+                     0, G_MAXINT,
+                     0,
+                     G_PARAM_CONSTRUCT | G_PARAM_WRITABLE | G_PARAM_READABLE );
+
+
+  g_object_class_install_property (object_class,
+                                   PROP_PADDING,
+                                   padding_spec);
+
+
 
   signals[RESIZE_UNIT] =
     g_signal_new ("resize-unit",
@@ -333,6 +381,7 @@ psppire_axis_init (PsppireAxis *axis)
   tower_init (&axis->unit_tower);
 
   axis->pool = pool_create ();
+  axis->padding = 0;
 }
 
 
@@ -367,6 +416,10 @@ psppire_axis_append (PsppireAxis *a, gint size)
 }
 
 
+/* Append N_UNITS of size SIZE to A.
+   The value of the "padding" property will be added to SIZE
+   unit before appending.
+*/
 void
 psppire_axis_append_n (PsppireAxis *a, gint n_units, gint size)
 {
@@ -378,7 +431,8 @@ psppire_axis_append_n (PsppireAxis *a, gint n_units, gint size)
   node = pool_malloc (a->pool, sizeof *node);
 
   tower_insert (&a->unit_tower, n_units, &node->unit_node, NULL);
-  tower_insert (&a->pixel_tower, size * n_units, &node->pixel_node, NULL);
+  tower_insert (&a->pixel_tower, (size + a->padding) * n_units,
+    &node->pixel_node, NULL);
 }
 
 
@@ -433,7 +487,10 @@ split (PsppireAxis *a, gint posn)
 }
 
 
-/* Insert a new unit of size SIZE before POSN */
+/* Insert a new unit of size SIZE before POSN.
+   The value of the "padding" property will be added to SIZE before
+   the unit is inserted.
+ */
 void
 psppire_axis_insert (PsppireAxis *a, gint posn, gint size)
 {
@@ -464,7 +521,7 @@ psppire_axis_insert (PsppireAxis *a, gint posn, gint size)
                before ? &before->unit_node : NULL);
 
   tower_insert (&a->pixel_tower,
-               size,
+               size + a->padding,
                &new_node->pixel_node,
                before ? &before->pixel_node : NULL);
 }
@@ -500,6 +557,10 @@ make_single (PsppireAxis *a, gint posn)
 }
 
 
+/*
+  Set the size of the unit at POSN to be SIZE plus the
+  current value of "padding"
+ */
 void
 psppire_axis_resize (PsppireAxis *axis, gint posn, glong size)
 {
@@ -514,9 +575,9 @@ psppire_axis_resize (PsppireAxis *axis, gint posn, glong size)
 
   an = make_single (axis, posn);
 
-  tower_resize (&axis->pixel_tower, &an->pixel_node, size);
+  tower_resize (&axis->pixel_tower, &an->pixel_node, size + axis->padding);
 
-  g_signal_emit (axis, signals[RESIZE_UNIT], 0, posn, size);
+  g_signal_emit (axis, signals[RESIZE_UNIT], 0, posn, size + axis->padding);
 }
 
 
index cfba37b23014328ef838a87a6ca2e302ab6fc7ab..50a6a39dc2e7687f3fb6740d4a5b768c2c9d4a7d 100644 (file)
@@ -53,6 +53,7 @@ struct _PsppireAxis
 
   glong min_extent;
   gint default_size;
+  gint padding;
 };
 
 struct _PsppireAxisClass
@@ -71,7 +72,6 @@ void psppire_axis_insert (PsppireAxis *a, gint posn, gint size);
 
 void psppire_axis_append (PsppireAxis *a, gint size);
 
-
 void psppire_axis_append_n (PsppireAxis *a, gint n_units, gint size);
 
 void psppire_axis_resize (PsppireAxis *a, gint posn, glong size);