Merge branch 'rewrite-sheet' of ssh://jmd@git.sv.gnu.org/srv/git/pspp into rewrite...
[pspp-builds.git] / lib / gtksheet / psppire-axis.c
1 /* PSPPIRE - a graphical user interface for PSPP.
2    Copyright (C) 2008  Free Software Foundation
3
4    This program is free software: you can redistribute it and/or modify
5    it under the terms of the GNU General Public License as published by
6    the Free Software Foundation, either version 3 of the License, or
7    (at your option) any later version.
8
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12    GNU General Public License for more details.
13
14    You should have received a copy of the GNU General Public License
15    along with this program.  If not, see <http://www.gnu.org/licenses/>. */
16
17 #include <config.h>
18 #include <string.h>
19 #include <stdlib.h>
20
21 #include <libpspp/tower.h>
22 #include <libpspp/pool.h>
23 #include "psppire-axis.h"
24 #include <gtk/gtk.h>
25
26
27 /* --- prototypes --- */
28 static void psppire_axis_class_init (PsppireAxisClass   *class);
29 static void psppire_axis_init   (PsppireAxis            *axis);
30 static void psppire_axis_finalize   (GObject            *object);
31
32
33 /* --- variables --- */
34 static GObjectClass     *parent_class = NULL;
35
36 /* --- functions --- */
37 /**
38  * psppire_axis_get_type:
39  * @returns: the type ID for accelerator groups.
40  */
41 GType
42 psppire_axis_get_type (void)
43 {
44   static GType object_type = 0;
45
46   if (!object_type)
47     {
48       static const GTypeInfo object_info = {
49         sizeof (PsppireAxisClass),
50         (GBaseInitFunc) NULL,
51         (GBaseFinalizeFunc) NULL,
52         (GClassInitFunc) psppire_axis_class_init,
53         NULL,   /* class_finalize */
54         NULL,   /* class_data */
55         sizeof (PsppireAxis),
56         0,      /* n_preallocs */
57         (GInstanceInitFunc) psppire_axis_init,
58       };
59
60       object_type = g_type_register_static (G_TYPE_OBJECT,
61                                             "PsppireAxis",
62                                             &object_info, 0);
63     }
64
65   return object_type;
66 }
67
68
69 static void
70 psppire_axis_class_init (PsppireAxisClass *class)
71 {
72   GObjectClass *object_class = G_OBJECT_CLASS (class);
73
74   parent_class = g_type_class_peek_parent (class);
75
76   object_class->finalize = psppire_axis_finalize;
77 }
78
79 static void
80 psppire_axis_init (PsppireAxis *axis)
81 {
82   axis->pool = NULL;
83   psppire_axis_clear (axis);
84 }
85
86
87 static void
88 psppire_axis_finalize (GObject *object)
89 {
90   PsppireAxis *a = PSPPIRE_AXIS (object);
91   pool_destroy (a->pool);
92   G_OBJECT_CLASS (parent_class)->finalize (object);
93 }
94
95 /**
96  * psppire_axis_new:
97  * @returns: a new #PsppireAxis object
98  *
99  * Creates a new #PsppireAxis.
100  */
101 PsppireAxis*
102 psppire_axis_new (void)
103 {
104   return g_object_new (G_TYPE_PSPPIRE_AXIS, NULL);
105 }
106
107
108 gint
109 psppire_axis_unit_size (PsppireAxis *a, gint unit)
110 {
111   const struct tower_node *node;
112   if  (unit >= tower_count (&a->tower))
113     return 0;
114
115   node = tower_get (&a->tower, unit);
116
117   return tower_node_get_size (node);
118 }
119
120 gint
121 psppire_axis_unit_count (PsppireAxis *a)
122 {
123   return tower_count (&a->tower);
124 }
125
126 glong
127 psppire_axis_pixel_start (PsppireAxis *a, gint unit)
128 {
129   const struct tower_node *node;
130
131   if ( unit >= tower_count (&a->tower))
132     return tower_height (&a->tower);
133
134   node = tower_get (&a->tower, unit);
135
136   return  tower_node_get_level (node);
137 }
138
139 gint
140 psppire_axis_get_unit_at_pixel (PsppireAxis *a, glong pixel)
141 {
142   const struct tower_node *node;
143   unsigned long int node_start;
144
145   if (pixel >= tower_height (&a->tower))
146     return tower_count (&a->tower);
147
148   node = tower_lookup (&a->tower, pixel, &node_start);
149
150   return tower_node_get_index (node);
151 }
152
153 void
154 psppire_axis_append (PsppireAxis *a, gint size)
155 {
156   struct tower_node *new = pool_malloc (a->pool, sizeof *new);
157
158   tower_insert (&a->tower, size, new, NULL);
159 }
160
161
162
163 /* Insert a new unit of size SIZE before position POSN */
164 void
165 psppire_axis_insert (PsppireAxis *a, gint size, gint posn)
166 {
167   struct tower_node *new = pool_malloc (a->pool, sizeof *new);
168
169   struct tower_node *before = tower_get (&a->tower, posn);
170
171   tower_insert (&a->tower, size, new, before);
172 }
173
174
175 void
176 psppire_axis_remove (PsppireAxis *a, gint posn)
177 {
178   struct tower_node *node = tower_get (&a->tower, posn);
179
180   tower_delete (&a->tower, node);
181
182   pool_free (a->pool, node);
183 }
184
185
186 void
187 psppire_axis_resize_unit (PsppireAxis *a, gint size, gint posn)
188 {
189   struct tower_node *node = tower_get (&a->tower, posn);
190
191   tower_resize (&a->tower, node, size);
192 }
193
194
195
196 void
197 psppire_axis_clear (PsppireAxis *a)
198 {
199   pool_destroy (a->pool);
200   a->pool = pool_create ();
201   tower_init (&a->tower);
202 }
203
204