/*
- Copyright (C) 2006, 2008 Free Software Foundation
+ Copyright (C) 2006, 2008, 2009 Free Software Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include "psppire-sheet.h"
#include <ui/gui/psppire-marshal.h>
#include <ui/gui/sheet/psppire-sheetmodel.h>
+#include <ui/gui/sheet/psppire-axis.h>
#include <libpspp/misc.h>
+
#include <math.h>
/* sheet flags */
#include <language/syntax-string-source.h>
#include "psppire-data-store.h"
-#include <ui/gui/sheet/psppire-axis-impl.h>
+#include <ui/gui/sheet/psppire-axis.h>
#include "helper.h"
#include <gtk-contrib/gtkxpaned.h>
for (i = 0; i < 2; ++i)
{
- psppire_axis_impl_clear (de->vaxis[i]);
- psppire_axis_impl_append_n (de->vaxis[i], n_cases, DEFAULT_ROW_HEIGHT);
+ psppire_axis_clear (de->vaxis[i]);
+ psppire_axis_append_n (de->vaxis[i], n_cases, DEFAULT_ROW_HEIGHT);
}
}
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
for (i = 0; i < 2; ++i)
- psppire_axis_impl_insert (de->vaxis[i], before, DEFAULT_ROW_HEIGHT);
+ psppire_axis_insert (de->vaxis[i], before, DEFAULT_ROW_HEIGHT);
}
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
for (i = 0; i < 2; ++i)
- psppire_axis_impl_delete (de->vaxis[0], first, n_cases);
+ psppire_axis_delete (de->vaxis[0], first, n_cases);
}
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
gint m_width = width_of_m (GTK_WIDGET (de));
- PsppireAxisImpl *vaxis;
+ PsppireAxis *vaxis;
g_object_get (de->var_sheet, "vertical-axis", &vaxis, NULL);
- psppire_axis_impl_clear (vaxis);
- psppire_axis_impl_append_n (vaxis, 1 + psppire_dict_get_var_cnt (dict), DEFAULT_ROW_HEIGHT);
+ psppire_axis_clear (vaxis);
+ psppire_axis_append_n (vaxis, 1 + psppire_dict_get_var_cnt (dict), DEFAULT_ROW_HEIGHT);
g_signal_connect_swapped (de->haxis, "resize-unit",
G_CALLBACK (rewidth_variable), de);
- psppire_axis_impl_clear (de->haxis);
+ psppire_axis_clear (de->haxis);
for (v = 0 ; v < psppire_dict_get_var_cnt (dict); ++v)
{
const struct variable *var = psppire_dict_get_variable (dict, v);
- psppire_axis_impl_append (de->haxis, m_width * var_get_display_width (var));
+ psppire_axis_append (de->haxis, m_width * var_get_display_width (var));
}
}
gint m_width = width_of_m (GTK_WIDGET (de));
- PsppireAxisImpl *var_vaxis;
+ PsppireAxis *var_vaxis;
const struct variable *var = psppire_dict_get_variable (dict, x);
g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
- psppire_axis_impl_insert (var_vaxis, x, DEFAULT_ROW_HEIGHT);
+ psppire_axis_insert (var_vaxis, x, DEFAULT_ROW_HEIGHT);
- psppire_axis_impl_insert (de->haxis, x, m_width * var_get_display_width (var));
+ psppire_axis_insert (de->haxis, x, m_width * var_get_display_width (var));
}
{
PsppireDataEditor *de = PSPPIRE_DATA_EDITOR (data);
- PsppireAxisImpl *var_vaxis;
+ PsppireAxis *var_vaxis;
g_object_get (de->var_sheet, "vertical-axis", &var_vaxis, NULL);
- psppire_axis_impl_delete (var_vaxis, posn, 1);
+ psppire_axis_delete (var_vaxis, posn, 1);
- psppire_axis_impl_delete (de->haxis, posn, 1);
+ psppire_axis_delete (de->haxis, posn, 1);
}
if ( var_width < 1 )
var_width = 1;
- psppire_axis_impl_resize (de->haxis, posn, m_width * var_width);
+ psppire_axis_resize (de->haxis, posn, m_width * var_width);
}
static void
init_sheet (PsppireDataEditor *de, int i,
GtkAdjustment *hadj, GtkAdjustment *vadj,
- PsppireAxisImpl *vaxis,
- PsppireAxisImpl *haxis
+ PsppireAxis *vaxis,
+ PsppireAxis *haxis
)
{
de->sheet_bin[i] = gtk_scrolled_window_new (hadj, vadj);
GtkAdjustment *vadj1, *hadj1;
GtkWidget *sheet ;
- de->vaxis[0] = psppire_axis_impl_new ();
- de->vaxis[1] = psppire_axis_impl_new ();
+ de->vaxis[0] = psppire_axis_new ();
+ de->vaxis[1] = psppire_axis_new ();
/* There's only one horizontal axis, since the
column widths are parameters of the variables */
- de->haxis = psppire_axis_impl_new ();
+ de->haxis = psppire_axis_new ();
de->split = TRUE;
de->paned = gtk_xpaned_new ();
#include <glib-object.h>
#include <gtk/gtknotebook.h>
-#include <ui/gui/sheet/psppire-axis-impl.h>
+#include <ui/gui/sheet/psppire-axis.h>
#include "psppire-var-store.h"
#include "psppire-data-store.h"
GtkWidget *paned;
gboolean split;
- PsppireAxisImpl *vaxis[2];
+ PsppireAxis *vaxis[2];
/* There's only one horizontal axis, since the
column widths are parameters of the variables */
- PsppireAxisImpl *haxis;
+ PsppireAxis *haxis;
};
#include <config.h>
#include "psppire-var-sheet.h"
-#include <ui/gui/sheet/psppire-axis-impl.h>
+#include <ui/gui/sheet/psppire-axis.h>
#include "helper.h"
psppire_var_sheet_new (void)
{
gint i;
- PsppireAxisImpl *ha = psppire_axis_impl_new ();
- PsppireAxisImpl *va = psppire_axis_impl_new ();
+ PsppireAxis *ha = psppire_axis_new ();
+ PsppireAxis *va = psppire_axis_new ();
GtkWidget *w = g_object_new (psppire_var_sheet_get_type (), NULL);
for (i = 0 ; i < 10 ; ++i)
- psppire_axis_impl_append (ha, column_def[i].width);
+ psppire_axis_append (ha, column_def[i].width);
g_object_set (va,
"default-size", 25,
src_ui_gui_sheet_libsheet_la_SOURCES = \
src/ui/gui/sheet/psppire-axis.c \
src/ui/gui/sheet/psppire-axis.h \
- src/ui/gui/sheet/psppire-axis-impl.c \
- src/ui/gui/sheet/psppire-axis-impl.h \
src/ui/gui/sheet/psppire-sheetmodel.c \
src/ui/gui/sheet/psppire-sheetmodel.h
+++ /dev/null
-/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2008 Free Software Foundation
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-#include <config.h>
-#include <string.h>
-#include <stdlib.h>
-
-#include <libpspp/tower.h>
-#include <libpspp/pool.h>
-#include "psppire-axis-impl.h"
-#include <math.h>
-
-
-/* --- prototypes --- */
-static void psppire_axis_impl_class_init (PsppireAxisImplClass *class);
-static void psppire_axis_impl_init (PsppireAxisImpl *axis);
-static void psppire_axis_impl_finalize (GObject *object);
-
-
-/* --- variables --- */
-static GObjectClass *parent_class = NULL;
-
-
-struct axis_node
-{
- struct tower_node pixel_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 / (gdouble) n->size);
-
- n = tower_next (&a->unit_tower, n);
- }
- g_debug ("\n");
-}
-
-static gint
-unit_at_pixel (const PsppireAxis *axis, glong pixel)
-{
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
-
- unsigned long int start;
- struct tower_node *n;
- struct axis_node *an;
- gdouble fraction;
-
- g_return_val_if_fail (pixel >= 0, -1);
-
- n = tower_lookup (&a->pixel_tower, pixel, &start);
- an = tower_data (n, struct axis_node, pixel_node);
-
- fraction = (pixel - start) / (gdouble) tower_node_get_size (&an->pixel_node);
-
- return tower_node_get_level (&an->unit_node)
- + fraction * tower_node_get_size (&an->unit_node);
-}
-
-
-static gint
-unit_count (const PsppireAxis *axis)
-{
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
-
- return tower_height (&a->unit_tower);
-}
-
-
-/* Returns the pixel at the start of UNIT */
-static glong
-start_pixel (const PsppireAxis *axis, gint unit)
-{
- gdouble fraction;
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
- struct tower_node *n ;
- struct axis_node *an;
-
- unsigned long int start;
-
- if ( unit < 0)
- return -1;
-
- if ( unit >= unit_count (axis))
- return -1;
-
- n = tower_lookup (&a->unit_tower, unit, &start);
-
- an = tower_data (n, struct axis_node, unit_node);
-
- fraction = (unit - start) / (gdouble) tower_node_get_size (&an->unit_node);
-
- return tower_node_get_level (&an->pixel_node) +
- nearbyint (fraction * tower_node_get_size (&an->pixel_node));
-}
-
-
-static gint
-unit_size (const PsppireAxis *axis, gint unit)
-{
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
- struct tower_node *n ;
- struct axis_node *an;
-
- unsigned long int start;
-
- if ( unit < 0)
- return 0;
-
- if ( unit >= unit_count (axis))
- return 0;
-
- n = tower_lookup (&a->unit_tower, unit, &start);
-
- an = tower_data (n, struct axis_node, unit_node);
-
- return nearbyint (tower_node_get_size (&an->pixel_node)
- / (gdouble) tower_node_get_size (&an->unit_node));
-}
-
-
-static glong
-total_size (const PsppireAxis *axis)
-{
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (axis);
-
- return tower_height (&a->pixel_tower);
-}
-
-
-static void resize (PsppireAxis *axis, gint posn, glong size);
-
-
-
-static void
-psppire_impl_iface_init (PsppireAxisIface *iface)
-{
- iface->unit_size = unit_size;
- iface->unit_count = unit_count;
- iface->start_pixel = start_pixel;
- iface->unit_at_pixel = unit_at_pixel;
- iface->total_size = total_size;
- iface->resize = resize;
-}
-
-/* --- functions --- */
-/**
- * psppire_axis_impl_get_type:
- * @returns: the type ID for accelerator groups.
- */
-GType
-psppire_axis_impl_get_type (void)
-{
- static GType object_type = 0;
-
- if (!object_type)
- {
- static const GTypeInfo object_info = {
- sizeof (PsppireAxisImplClass),
- (GBaseInitFunc) NULL,
- (GBaseFinalizeFunc) NULL,
- (GClassInitFunc) psppire_axis_impl_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (PsppireAxisImpl),
- 0, /* n_preallocs */
- (GInstanceInitFunc) psppire_axis_impl_init,
- };
-
- static const GInterfaceInfo interface_info =
- {
- (GInterfaceInitFunc) psppire_impl_iface_init,
- NULL,
- 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);
- }
-
- return object_type;
-}
-
-static void
-psppire_axis_impl_class_init (PsppireAxisImplClass *class)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (class);
- parent_class = g_type_class_peek_parent (class);
-
- object_class->finalize = psppire_axis_impl_finalize;
-}
-
-
-static void
-psppire_axis_impl_init (PsppireAxisImpl *axis)
-{
- tower_init (&axis->pixel_tower);
- tower_init (&axis->unit_tower);
-
- axis->pool = pool_create ();
-}
-
-
-static void
-psppire_axis_impl_finalize (GObject *object)
-{
- PsppireAxisImpl *a = PSPPIRE_AXIS_IMPL (object);
- pool_destroy (a->pool);
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-/**
- * psppire_axis_impl_new:
- * @returns: a new #PsppireAxisImpl object
- *
- * Creates a new #PsppireAxisImpl.
- */
-PsppireAxisImpl*
-psppire_axis_impl_new (void)
-{
- return g_object_new (G_TYPE_PSPPIRE_AXIS_IMPL, NULL);
-}
-
-
-\f
-
-void
-psppire_axis_impl_append (PsppireAxisImpl *a, gint size)
-{
- psppire_axis_impl_append_n (a, 1, size);
-}
-
-
-void
-psppire_axis_impl_append_n (PsppireAxisImpl *a, gint n_units, gint size)
-{
- struct axis_node *node;
-
- if (n_units == 0)
- return;
-
- 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);
-}
-
-
-/* Split the node of both towers at POSN */
-static void
-split (PsppireAxisImpl *a, gint posn)
-{
- unsigned long int existing_unit_size;
- unsigned long int existing_pixel_size;
- unsigned long int start;
- gdouble fraction;
- struct axis_node *new_node ;
- struct tower_node *n;
- struct axis_node *existing_node;
-
- g_return_if_fail (posn <= tower_height (&a->unit_tower));
-
- /* 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)
- return;
-
- existing_unit_size = tower_node_get_size (&existing_node->unit_node);
- existing_pixel_size = tower_node_get_size (&existing_node->pixel_node);
-
- fraction = (posn - start) / (gdouble) existing_unit_size;
-
- new_node = pool_malloc (a->pool, sizeof (*new_node));
-
- tower_resize (&a->unit_tower, &existing_node->unit_node, posn - start);
-
- tower_resize (&a->pixel_tower, &existing_node->pixel_node,
- nearbyintf (fraction * existing_pixel_size));
-
- tower_insert (&a->unit_tower,
- existing_unit_size - (posn - start),
- &new_node->unit_node,
- tower_next (&a->unit_tower, &existing_node->unit_node));
-
-
- tower_insert (&a->pixel_tower,
- nearbyintf (existing_pixel_size * (1 - fraction)),
- &new_node->pixel_node,
- tower_next (&a->pixel_tower, &existing_node->pixel_node));
-}
-
-
-/* Insert a new unit of size SIZE before POSN */
-void
-psppire_axis_impl_insert (PsppireAxisImpl *a, gint posn, gint size)
-{
- struct axis_node *before = NULL;
- struct axis_node *new_node;
-
- g_return_if_fail ( posn >= 0);
- g_return_if_fail ( posn <= tower_height (&a->unit_tower));
-
- if ( posn < tower_height (&a->unit_tower))
- {
- unsigned long int start = 0;
- struct tower_node *n;
-
- split (a, posn);
-
- 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 ? &before->unit_node : NULL);
-
- tower_insert (&a->pixel_tower,
- size,
- &new_node->pixel_node,
- before ? &before->pixel_node : NULL);
-}
-
-
-/* Make the element at POSN singular.
- Return a pointer to the node for this element */
-static struct axis_node *
-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))
- {
- split (a, posn + 1);
- n = tower_lookup (&a->unit_tower, posn, &start);
-
- if ( 1 != tower_node_get_size (n))
- {
- split (a, posn);
- n = tower_lookup (&a->unit_tower, posn, &start);
- }
- }
-
- g_assert (1 == tower_node_get_size (n));
-
- return tower_data (n, struct axis_node, unit_node);
-}
-
-
-static void
-resize (PsppireAxis *axis, gint posn, glong size)
-{
- 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)
-{
- pool_destroy (a->pool);
- a->pool = pool_create ();
-
- tower_init (&a->pixel_tower);
- tower_init (&a->unit_tower);
-}
-
-
-
-void
-psppire_axis_impl_delete (PsppireAxisImpl *a, gint first, gint n_units)
-{
- 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);
-
- unit_node = tower_lookup (&a->unit_tower, first, &start);
- g_assert (start == first);
-
- while (units_to_delete > 0)
- {
- 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;
-
- 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;
- }
-}
+++ /dev/null
-/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2008 Free Software Foundation
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-
-#ifndef PSPPIRE_AXIS_IMPL_H__
-#define PSPPIRE_AXIS_IMPL_H__
-
-
-#include <glib-object.h>
-#include <glib.h>
-
-#include "psppire-axis.h"
-#include <libpspp/tower.h>
-
-G_BEGIN_DECLS
-
-
-/* --- type macros --- */
-#define G_TYPE_PSPPIRE_AXIS_IMPL (psppire_axis_impl_get_type ())
-#define PSPPIRE_AXIS_IMPL(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS_IMPL, PsppireAxisImpl))
-#define PSPPIRE_AXIS_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), G_TYPE_PSPPIRE_AXIS_IMPL, PsppireAxisImplClass))
-#define PSPPIRE_IS_AXIS_IMPL(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), G_TYPE_PSPPIRE_AXIS_IMPL))
-#define PSPPIRE_IS_AXIS_IMPL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), G_TYPE_PSPPIRE_AXIS_IMPL))
-#define PSPPIRE_AXIS_IMPL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS_IMPL, PsppireAxisImplClass))
-
-
-
-/* --- typedefs & structures --- */
-typedef struct _PsppireAxisImpl PsppireAxisImpl;
-typedef struct _PsppireAxisImplClass PsppireAxisImplClass;
-
-struct pool;
-
-struct _PsppireAxisImpl
-{
- PsppireAxis parent;
-
- struct tower pixel_tower;
- struct tower unit_tower;
-
- struct pool *pool;
-};
-
-struct _PsppireAxisImplClass
-{
- PsppireAxisClass parent_class;
-};
-
-GType psppire_axis_impl_get_type (void);
-
-PsppireAxisImpl* psppire_axis_impl_new (void);
-
-\f
-/* Interface between axis and model */
-
-
-
-void psppire_axis_impl_insert (PsppireAxisImpl *a, gint posn, gint size);
-
-void psppire_axis_impl_append (PsppireAxisImpl *a, gint size);
-
-
-void psppire_axis_impl_append_n (PsppireAxisImpl *a, gint n_units, gint size);
-
-void psppire_axis_impl_resize (PsppireAxisImpl *a, gint posn, gint size);
-
-void psppire_axis_impl_clear (PsppireAxisImpl *);
-
-
-void psppire_axis_impl_delete (PsppireAxisImpl *, gint first, gint n_cases);
-
-
-
-G_END_DECLS
-
-#endif /* PSPPIRE_AXIS_IMPL_H__ */
/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2008 Free Software Foundation
+ Copyright (C) 2008, 2009 Free Software Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <string.h>
#include <stdlib.h>
+#include <ui/gui/psppire-marshal.h>
#include <libpspp/tower.h>
#include <libpspp/pool.h>
-#include <libpspp/misc.h>
#include "psppire-axis.h"
-#include <ui/gui/psppire-marshal.h>
-#include <gtk/gtk.h>
-
+#include <math.h>
+#include <libpspp/misc.h>
/* Signals */
static guint signals[n_signals] ;
+/* --- prototypes --- */
+static void psppire_axis_class_init (PsppireAxisClass *class);
+static void psppire_axis_init (PsppireAxis *axis);
+static void psppire_axis_finalize (GObject *object);
-#define PSPPIRE_AXIS_GET_IFACE(obj) \
- (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PSPPIRE_TYPE_AXIS_IFACE, PsppireAxisIface))
-GType
-psppire_axis_iface_get_type (void)
+/* --- variables --- */
+static GObjectClass *parent_class = NULL;
+
+
+struct axis_node
+{
+ struct tower_node pixel_node;
+ struct tower_node unit_node;
+};
+
+void
+psppire_axis_dump (const PsppireAxis *a)
{
- static GType psppire_axis_iface_type = 0;
+ struct tower_node *n = tower_first (&a->unit_tower);
- if (! psppire_axis_iface_type)
+ g_debug ("Axis %p", a);
+ while (n)
{
- static const GTypeInfo psppire_axis_iface_info =
- {
- sizeof (PsppireAxisIface), /* class_size */
- NULL, /* base init */
- NULL, /* base_finalize */
- NULL,
- NULL, /* class_finalize */
- NULL, /* class_data */
- 0,
- 0, /* n_preallocs */
- NULL
- };
+ 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 / (gdouble) n->size);
+
+ n = tower_next (&a->unit_tower, n);
+ }
+ g_debug ("\n");
+}
+
+/* Return the unit covered by PIXEL */
+gint
+psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel)
+{
+ unsigned long int start;
+ struct tower_node *n;
+ struct axis_node *an;
+ gdouble fraction;
+
+ glong size = tower_height (&a->pixel_tower);
+
+ g_return_val_if_fail (pixel >= 0, -1);
- psppire_axis_iface_type =
- g_type_register_static (G_TYPE_INTERFACE, "PsppireAxisIface",
- &psppire_axis_iface_info, 0);
+ if (pixel >= size)
+ {
+ gint n_items = tower_height (&a->unit_tower);
+ glong extra = pixel - size;
+
+ return n_items - 1 + DIV_RND_UP (extra, a->default_size);
}
- return psppire_axis_iface_type;
+
+ n = tower_lookup (&a->pixel_tower, pixel, &start);
+ an = tower_data (n, struct axis_node, pixel_node);
+
+ fraction = (pixel - start) / (gdouble) tower_node_get_size (&an->pixel_node);
+
+ return tower_node_get_level (&an->unit_node)
+ + fraction * tower_node_get_size (&an->unit_node);
}
-G_DEFINE_ABSTRACT_TYPE(PsppireAxis, psppire_axis, G_TYPE_OBJECT);
+gint
+psppire_axis_unit_count (const PsppireAxis *a)
+{
+ glong padding = 0;
+ glong actual_size;
+ actual_size = tower_height (&a->pixel_tower);
-/* --- prototypes --- */
-static void psppire_axis_class_init (PsppireAxisClass *class);
-static void psppire_axis_init (PsppireAxis *axis);
-static void psppire_axis_finalize (GObject *object);
+ if ( actual_size < a->min_extent )
+ padding = DIV_RND_UP (a->min_extent - actual_size, a->default_size);
+ return tower_height (&a->unit_tower) + padding;
+}
-/* --- variables --- */
-static GObjectClass *parent_class = NULL;
+/* Return the starting pixel of UNIT */
+glong
+psppire_axis_start_pixel (const PsppireAxis *a, gint unit)
+{
+ gdouble fraction;
+ struct tower_node *n ;
+ struct axis_node *an;
+
+ unsigned long int start;
+
+ gint the_count, size ;
+
+ the_count = tower_height (&a->unit_tower);
+ size = tower_height (&a->pixel_tower);
+
+ if ( unit >= the_count)
+ {
+ return size + (unit - the_count) * a->default_size;
+ }
+
+ if ( unit < 0)
+ return -1;
+
+ if ( unit >= tower_height (&a->unit_tower))
+ return -1;
+
+ n = tower_lookup (&a->unit_tower, unit, &start);
+
+ an = tower_data (n, struct axis_node, unit_node);
+
+ fraction = (unit - start) / (gdouble) tower_node_get_size (&an->unit_node);
+
+ return tower_node_get_level (&an->pixel_node) +
+ nearbyint (fraction * tower_node_get_size (&an->pixel_node));
+}
+
+gint
+psppire_axis_unit_size (const PsppireAxis *axis, gint unit)
+{
+ struct tower_node *n ;
+ struct axis_node *an;
+
+ unsigned long int start;
+
+ if (unit >= tower_height (&axis->unit_tower))
+ return axis->default_size;
+
+ if ( unit < 0)
+ return 0;
+
+ if ( unit >= tower_height (&axis->unit_tower))
+ return 0;
+
+ n = tower_lookup (&axis->unit_tower, unit, &start);
+
+ an = tower_data (n, struct axis_node, unit_node);
+
+ return nearbyint (tower_node_get_size (&an->pixel_node)
+ / (gdouble) tower_node_get_size (&an->unit_node));
+}
+
+
+
+/* --- functions --- */
+/**
+ * psppire_axis_get_type:
+ * @returns: the type ID for accelerator groups.
+ */
+GType
+psppire_axis_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (!object_type)
+ {
+ static const GTypeInfo object_info = {
+ sizeof (PsppireAxisClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) psppire_axis_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PsppireAxis),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) psppire_axis_init,
+ };
+
+ object_type = g_type_register_static (G_TYPE_OBJECT,
+ "PsppireAxis",
+ &object_info, 0);
+
+ }
+ return object_type;
+}
enum
{
};
}
+
static void
psppire_axis_class_init (PsppireAxisClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+
GParamSpec *min_extent_spec;
GParamSpec *default_size_spec;
+ parent_class = g_type_class_peek_parent (class);
+
object_class->set_property = psppire_axis_set_property;
object_class->get_property = psppire_axis_get_property;
+
min_extent_spec =
g_param_spec_long ("minimum-extent",
"Minimum Extent",
PROP_DEFAULT_SIZE,
default_size_spec);
- parent_class = g_type_class_peek_parent (class);
-
- object_class->finalize = psppire_axis_finalize;
-
signals[RESIZE_UNIT] =
g_signal_new ("resize-unit",
G_TYPE_INT,
G_TYPE_LONG
);
+
+
+ object_class->finalize = psppire_axis_finalize;
}
static void
psppire_axis_init (PsppireAxis *axis)
{
+ tower_init (&axis->pixel_tower);
+ tower_init (&axis->unit_tower);
+
+ axis->pool = pool_create ();
}
static void
psppire_axis_finalize (GObject *object)
{
+ PsppireAxis *a = PSPPIRE_AXIS (object);
+ pool_destroy (a->pool);
+
G_OBJECT_CLASS (parent_class)->finalize (object);
}
-gint
-psppire_axis_unit_size (const PsppireAxis *a, gint unit)
+/**
+ * psppire_axis_new:
+ * @returns: a new #PsppireAxis object
+ *
+ * Creates a new #PsppireAxis.
+ */
+PsppireAxis*
+psppire_axis_new (void)
+{
+ return g_object_new (G_TYPE_PSPPIRE_AXIS, NULL);
+}
+
+
+\f
+
+void
+psppire_axis_append (PsppireAxis *a, gint size)
{
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
+ psppire_axis_append_n (a, 1, size);
+}
+
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_size, -1);
+void
+psppire_axis_append_n (PsppireAxis *a, gint n_units, gint size)
+{
+ struct axis_node *node;
+ if (n_units == 0)
+ return;
- if (unit >= PSPPIRE_AXIS_GET_IFACE (a)->unit_count(a))
- return a->default_size;
+ node = pool_malloc (a->pool, sizeof *node);
- return PSPPIRE_AXIS_GET_IFACE (a)->unit_size (a, unit);
+ tower_insert (&a->unit_tower, n_units, &node->unit_node, NULL);
+ tower_insert (&a->pixel_tower, size * n_units, &node->pixel_node, NULL);
}
-gint
-psppire_axis_unit_count (const PsppireAxis *a)
+
+/* Split the node of both towers at POSN */
+static void
+split (PsppireAxis *a, gint posn)
{
- glong padding = 0;
- glong actual_size;
+ unsigned long int existing_unit_size;
+ unsigned long int existing_pixel_size;
+ unsigned long int start;
+ gdouble fraction;
+ struct axis_node *new_node ;
+ struct tower_node *n;
+ struct axis_node *existing_node;
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_count, -1);
+ g_return_if_fail (posn <= tower_height (&a->unit_tower));
- actual_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
+ /* 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)
+ return;
+
+ existing_unit_size = tower_node_get_size (&existing_node->unit_node);
+ existing_pixel_size = tower_node_get_size (&existing_node->pixel_node);
+
+ fraction = (posn - start) / (gdouble) existing_unit_size;
+
+ new_node = pool_malloc (a->pool, sizeof (*new_node));
+
+ tower_resize (&a->unit_tower, &existing_node->unit_node, posn - start);
+
+ tower_resize (&a->pixel_tower, &existing_node->pixel_node,
+ nearbyintf (fraction * existing_pixel_size));
+
+ tower_insert (&a->unit_tower,
+ existing_unit_size - (posn - start),
+ &new_node->unit_node,
+ tower_next (&a->unit_tower, &existing_node->unit_node));
- if ( actual_size < a->min_extent )
- padding = DIV_RND_UP (a->min_extent - actual_size, a->default_size);
- return PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a) + padding;
+ tower_insert (&a->pixel_tower,
+ nearbyintf (existing_pixel_size * (1 - fraction)),
+ &new_node->pixel_node,
+ tower_next (&a->pixel_tower, &existing_node->pixel_node));
}
-/* Return the starting pixel of UNIT */
-glong
-psppire_axis_start_pixel (const PsppireAxis *a, gint unit)
+/* Insert a new unit of size SIZE before POSN */
+void
+psppire_axis_insert (PsppireAxis *a, gint posn, gint size)
{
- gint the_count, total_size ;
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
+ struct axis_node *before = NULL;
+ struct axis_node *new_node;
- the_count = PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a);
- total_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
+ g_return_if_fail ( posn >= 0);
+ g_return_if_fail ( posn <= tower_height (&a->unit_tower));
- if ( unit >= the_count)
+ if ( posn < tower_height (&a->unit_tower))
{
- return total_size + (unit - the_count) * a->default_size;
+ unsigned long int start = 0;
+ struct tower_node *n;
+
+ split (a, posn);
+
+ n = tower_lookup (&a->unit_tower, posn, &start);
+ g_assert (posn == start);
+
+ before = tower_data (n, struct axis_node, unit_node);
}
- return PSPPIRE_AXIS_GET_IFACE (a)->start_pixel (a, unit);
-}
+ new_node = pool_malloc (a->pool, sizeof (*new_node));
+ tower_insert (&a->unit_tower,
+ 1,
+ &new_node->unit_node,
+ before ? &before->unit_node : NULL);
-/* Return the unit covered by PIXEL */
-gint
-psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel)
-{
- glong total_size;
+ tower_insert (&a->pixel_tower,
+ size,
+ &new_node->pixel_node,
+ before ? &before->pixel_node : NULL);
+}
- g_return_val_if_fail (PSPPIRE_IS_AXIS (a), -1);
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a), -1);
+/* Make the element at POSN singular.
+ Return a pointer to the node for this element */
+static struct axis_node *
+make_single (PsppireAxis *a, gint posn)
+{
+ unsigned long int start;
+ struct tower_node *n;
- g_return_val_if_fail (PSPPIRE_AXIS_GET_IFACE (a)->unit_at_pixel, -1);
+ g_return_val_if_fail (posn < tower_height (&a->unit_tower), NULL);
- total_size = PSPPIRE_AXIS_GET_IFACE (a)->total_size (a);
+ n = tower_lookup (&a->unit_tower, posn, &start);
- if (pixel >= total_size)
+ if ( 1 != tower_node_get_size (n))
{
- gint n_items = PSPPIRE_AXIS_GET_IFACE (a)->unit_count (a);
- glong extra = pixel - total_size;
-
- return n_items - 1 + DIV_RND_UP (extra, a->default_size);
+ split (a, posn + 1);
+ n = tower_lookup (&a->unit_tower, posn, &start);
+
+ if ( 1 != tower_node_get_size (n))
+ {
+ split (a, posn);
+ n = tower_lookup (&a->unit_tower, posn, &start);
+ }
}
- return PSPPIRE_AXIS_GET_IFACE (a)->unit_at_pixel (a, pixel);
+ g_assert (1 == tower_node_get_size (n));
+
+ return tower_data (n, struct axis_node, unit_node);
}
-/* Set UNIT to size SIZE */
void
-psppire_axis_resize (PsppireAxis *a, gint unit, glong size)
+psppire_axis_resize (PsppireAxis *axis, gint posn, glong size)
{
- g_return_if_fail (PSPPIRE_IS_AXIS (a));
+ 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 (&axis->unit_tower))
+ return ;
+
+ an = make_single (axis, posn);
+
+ tower_resize (&axis->pixel_tower, &an->pixel_node, size);
+
+ g_signal_emit (axis, signals[RESIZE_UNIT], 0, posn, size);
+}
- g_return_if_fail (PSPPIRE_AXIS_GET_IFACE (a));
- g_return_if_fail (size > 0);
- if (PSPPIRE_AXIS_GET_IFACE (a)->resize)
- PSPPIRE_AXIS_GET_IFACE (a)->resize (a, unit, size);
- g_signal_emit (a, signals [RESIZE_UNIT], 0, unit, size);
+
+void
+psppire_axis_clear (PsppireAxis *a)
+{
+ pool_destroy (a->pool);
+ a->pool = pool_create ();
+
+ tower_init (&a->pixel_tower);
+ tower_init (&a->unit_tower);
}
+
+void
+psppire_axis_delete (PsppireAxis *a, gint first, gint n_units)
+{
+ 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);
+
+ unit_node = tower_lookup (&a->unit_tower, first, &start);
+ g_assert (start == first);
+
+ while (units_to_delete > 0)
+ {
+ 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;
+
+ 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;
+ }
+}
/* PSPPIRE - a graphical user interface for PSPP.
- Copyright (C) 2008 Free Software Foundation
+ Copyright (C) 2008, 2009 Free Software Foundation
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <glib-object.h>
#include <glib.h>
+#include <libpspp/tower.h>
G_BEGIN_DECLS
-
/* --- type macros --- */
#define G_TYPE_PSPPIRE_AXIS (psppire_axis_get_type ())
#define PSPPIRE_AXIS(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), G_TYPE_PSPPIRE_AXIS, PsppireAxis))
#define PSPPIRE_AXIS_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), G_TYPE_PSPPIRE_AXIS, PsppireAxisClass))
+
/* --- typedefs & structures --- */
typedef struct _PsppireAxis PsppireAxis;
typedef struct _PsppireAxisClass PsppireAxisClass;
+struct pool;
+
struct _PsppireAxis
{
- GObject parent;
+ GObject parent;
+
+ struct tower pixel_tower;
+ struct tower unit_tower;
+
+ struct pool *pool;
glong min_extent;
gint default_size;
GObjectClass parent_class;
};
-
GType psppire_axis_get_type (void);
+PsppireAxis* psppire_axis_new (void);
\f
+/* Interface between axis and model */
-GType psppire_axis_iface_get_type (void);
-
-#define PSPPIRE_TYPE_AXIS_IFACE (psppire_axis_iface_get_type ())
-
-typedef struct _PsppireAxisIface PsppireAxisIface;
-
-struct _PsppireAxisIface
-{
- GTypeInterface g_iface;
-
+void psppire_axis_insert (PsppireAxis *a, gint posn, gint size);
- /* Virtual Table */
+void psppire_axis_append (PsppireAxis *a, gint size);
- gint (*unit_size) (const PsppireAxis *a, gint unit);
- gint (*unit_count) (const PsppireAxis *a);
+void psppire_axis_append_n (PsppireAxis *a, gint n_units, gint size);
- glong (*start_pixel) (const PsppireAxis *a, gint unit);
+void psppire_axis_resize (PsppireAxis *a, gint posn, glong size);
- gint (*unit_at_pixel) (const PsppireAxis *a, glong pixel);
+void psppire_axis_clear (PsppireAxis *);
- glong (*total_size) (const PsppireAxis *a);
+void psppire_axis_delete (PsppireAxis *, gint first, gint n_cases);
+\f
- void (*resize) (PsppireAxis *a, gint unit, glong pixels);
-};
-
-
-/* Interface between sheet and axis */
-
-gint psppire_axis_unit_size (const PsppireAxis *a, gint unit);
-
-gint psppire_axis_unit_count (const PsppireAxis *a);
-
+gint psppire_axis_unit_count (const PsppireAxis *);
glong psppire_axis_start_pixel (const PsppireAxis *a, gint unit);
-
-gint psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel);
-
-
-void psppire_axis_resize (PsppireAxis *a, gint unit, glong size);
+gint psppire_axis_unit_size (const PsppireAxis *a, gint unit);
+gint psppire_axis_unit_at_pixel (const PsppireAxis *a, glong pixel);
G_END_DECLS