X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fgtksheet%2Fpsppire-axis-impl.c;h=1fb00d2d8435df76be0b9b1e3d8c4b5fdbfc8147;hb=8a6cded0d3a48627d4209c6334191e483700f528;hp=58e2871660254de1fd4db6406a0736e08ce1210a;hpb=83c403ce2b64c20ace3e52b591f23ff4ac8e2b7a;p=pspp diff --git a/lib/gtksheet/psppire-axis-impl.c b/lib/gtksheet/psppire-axis-impl.c index 58e2871660..1fb00d2d84 100644 --- a/lib/gtksheet/psppire-axis-impl.c +++ b/lib/gtksheet/psppire-axis-impl.c @@ -40,6 +40,24 @@ struct axis_node struct tower_node unit_node; }; +void +psppire_axis_impl_dump (const PsppireAxisImpl *a) +{ + struct tower_node *n = tower_first (&a->unit_tower); + + g_debug ("Axis %p", a); + while (n) + { + const struct axis_node *an = tower_data (n, struct axis_node, unit_node); + const struct tower_node *pn = &an->pixel_node; + g_debug ("%ld units of height %g", + n->size, pn->size / (float) n->size); + + n = tower_next (&a->unit_tower, n); + } + g_debug ("\n"); +} + static gint unit_at_pixel (const PsppireAxis *axis, glong pixel) { @@ -132,6 +150,8 @@ total_size (const PsppireAxis *axis) } +static void resize (PsppireAxis *axis, gint posn, glong size); + static void @@ -142,6 +162,7 @@ psppire_impl_iface_init (PsppireAxisIface *iface) iface->start_pixel = start_pixel; iface->unit_at_pixel = unit_at_pixel; iface->total_size = total_size; + iface->resize = resize; } /* --- functions --- */ @@ -175,12 +196,10 @@ psppire_axis_impl_get_type (void) NULL }; - object_type = g_type_register_static (G_TYPE_PSPPIRE_AXIS, "PsppireAxisImpl", &object_info, 0); - g_type_add_interface_static (object_type, PSPPIRE_TYPE_AXIS_IFACE, &interface_info); @@ -243,8 +262,11 @@ psppire_axis_impl_append (PsppireAxisImpl *a, gint size) void psppire_axis_impl_append_n (PsppireAxisImpl *a, gint n_units, gint size) { - struct axis_node *node = pool_alloc (a->pool, sizeof *node); + struct axis_node *node; + g_return_if_fail (n_units > 0); + + 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); @@ -260,10 +282,18 @@ split (PsppireAxisImpl *a, gint posn) unsigned long int start; gfloat fraction; struct axis_node *new_node ; - struct tower_node *n = tower_lookup (&a->unit_tower, posn, &start); + struct tower_node *n; + struct axis_node *existing_node; + + g_return_if_fail (posn <= tower_height (&a->unit_tower)); - struct axis_node *existing_node = - tower_data (n, struct axis_node, unit_node); + /* Nothing needs to be done */ + if ( posn == 0 || posn == tower_height (&a->unit_tower)) + return; + + n = tower_lookup (&a->unit_tower, posn, &start); + + existing_node = tower_data (n, struct axis_node, unit_node); /* Nothing needs to be done, if the range element is already split here */ if ( posn - start == 0) @@ -274,7 +304,7 @@ split (PsppireAxisImpl *a, gint posn) fraction = (posn - start) / (gfloat) existing_unit_size; - new_node = pool_alloc (a->pool, sizeof (*new_node)); + new_node = pool_malloc (a->pool, sizeof (*new_node)); tower_resize (&a->unit_tower, &existing_node->unit_node, posn - start); @@ -298,28 +328,36 @@ split (PsppireAxisImpl *a, gint posn) void psppire_axis_impl_insert (PsppireAxisImpl *a, gint posn, gint size) { - struct tower_node *n; - unsigned long int start; - struct axis_node *before; - struct axis_node *new_node = pool_alloc (a->pool, sizeof (*new_node)); + struct axis_node *before = NULL; + struct axis_node *new_node; - split (a, posn); + g_return_if_fail ( posn >= 0); + g_return_if_fail ( posn <= tower_height (&a->unit_tower)); - n = tower_lookup (&a->unit_tower, posn, &start); - g_assert (posn == start); + if ( posn < tower_height (&a->unit_tower)) + { + unsigned long int start = 0; + struct tower_node *n; + + split (a, posn); - before = tower_data (n, struct axis_node, unit_node); + n = tower_lookup (&a->unit_tower, posn, &start); + g_assert (posn == start); + + before = tower_data (n, struct axis_node, unit_node); + } + + new_node = pool_malloc (a->pool, sizeof (*new_node)); tower_insert (&a->unit_tower, 1, &new_node->unit_node, - &before->unit_node); - + before ? &before->unit_node : NULL); tower_insert (&a->pixel_tower, size, &new_node->pixel_node, - &before->pixel_node); + before ? &before->pixel_node : NULL); } @@ -330,6 +368,9 @@ make_single (PsppireAxisImpl *a, gint posn) { unsigned long int start; struct tower_node *n; + + g_return_val_if_fail (posn < tower_height (&a->unit_tower), NULL); + n = tower_lookup (&a->unit_tower, posn, &start); if ( 1 != tower_node_get_size (n)) @@ -346,19 +387,38 @@ make_single (PsppireAxisImpl *a, gint posn) g_assert (1 == tower_node_get_size (n)); - return tower_data (n, struct axis_node, unit_node); } -void -psppire_axis_impl_resize (PsppireAxisImpl *a, gint posn, gint size) + +static void +resize (PsppireAxis *axis, gint posn, glong size) { - struct axis_node *an = make_single (a, posn); + PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis); + + struct axis_node *an; + g_return_if_fail (posn >= 0); + g_return_if_fail (size > 0); + + /* Silently ignore this request if the position is greater than the number of + units in the axis */ + if (posn >= tower_height (&a->unit_tower)) + return ; + + an = make_single (a, posn); tower_resize (&a->pixel_tower, &an->pixel_node, size); } +void +psppire_axis_impl_resize (PsppireAxisImpl *a, gint posn, gint size) +{ + resize (PSPPIRE_AXIS (a), posn, size); +} + + + void psppire_axis_impl_clear (PsppireAxisImpl *a) @@ -373,16 +433,37 @@ psppire_axis_impl_clear (PsppireAxisImpl *a) void -psppire_axis_impl_delete (PsppireAxisImpl *a, gint first, gint n_cases) +psppire_axis_impl_delete (PsppireAxisImpl *a, gint first, gint n_units) { - gint i; - g_warning ("%s FIXME: This is an inefficient implementation", __FUNCTION__); + gint units_to_delete = n_units; + unsigned long int start; + struct tower_node *unit_node ; + g_return_if_fail (first + n_units < tower_height (&a->unit_tower)); + + split (a, first); + split (a, first + n_units); - for (i = first; i < first + n_cases; ++i) + unit_node = tower_lookup (&a->unit_tower, first, &start); + g_assert (start == first); + + while (units_to_delete > 0) { - struct axis_node *an = make_single (a, i); + struct tower_node *next_unit_node; + struct axis_node *an = tower_data (unit_node, + struct axis_node, unit_node); + + g_assert (unit_node == &an->unit_node); + g_assert (unit_node->size <= n_units); + + units_to_delete -= unit_node->size; - tower_delete (&a->unit_tower, &an->unit_node); + next_unit_node = tower_next (&a->unit_tower, unit_node); + + tower_delete (&a->unit_tower, unit_node); tower_delete (&a->pixel_tower, &an->pixel_node); + + pool_free (a->pool, an); + + unit_node = next_unit_node; } }