PROP_0,
PROP_VAXIS,
PROP_HAXIS,
+ PROP_CELL_PADDING,
PROP_MODEL
};
g_object_ref (sheet->vaxis);
}
+static const GtkBorder default_cell_padding = { 3, 3, 2, 2 };
static void
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));
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;
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);
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",
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);
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);
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;
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)))
{
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)) )
{
/* 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;
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)
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;
}
{
PROP_0,
PROP_MIN_EXTENT,
- PROP_DEFAULT_SIZE
+ PROP_DEFAULT_SIZE,
+ PROP_PADDING
};
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;
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;
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
-
+ GParamSpec *padding_spec;
GParamSpec *min_extent_spec;
GParamSpec *default_size_spec;
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",
tower_init (&axis->unit_tower);
axis->pool = pool_create ();
+ axis->padding = 0;
}
}
+/* 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)
{
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);
}
}
-/* 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)
{
before ? &before->unit_node : NULL);
tower_insert (&a->pixel_tower,
- size,
+ size + a->padding,
&new_node->pixel_node,
before ? &before->pixel_node : NULL);
}
}
+/*
+ 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)
{
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);
}
glong min_extent;
gint default_size;
+ gint padding;
};
struct _PsppireAxisClass
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);