aad3da71661f09113a4324a3fe2c1a3a38ed7a48
[pspp-builds.git] / lib / gtksheet / psppire-axis-hetero.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-hetero.h"
24 #include <gtk/gtk.h>
25
26
27 /* --- prototypes --- */
28 static void psppire_axis_hetero_class_init (PsppireAxisHeteroClass      *class);
29 static void psppire_axis_hetero_init    (PsppireAxisHetero              *axis);
30 static void psppire_axis_hetero_finalize   (GObject             *object);
31
32
33 /* --- variables --- */
34 static GObjectClass     *parent_class = NULL;
35
36
37 static gint
38 get_unit_at_pixel (const PsppireAxis *a, glong pixel)
39 {
40   PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
41   const struct tower_node *node;
42   unsigned long int node_start;
43
44   if (pixel >= tower_height (&ah->tower))
45     return tower_count (&ah->tower);
46
47   node = tower_lookup (&ah->tower, pixel, &node_start);
48
49   return tower_node_get_index (node);
50 }
51
52
53 static gint
54 unit_count (const PsppireAxis *a)
55 {
56   PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
57   return tower_count (&ah->tower);
58 }
59
60
61 static glong
62 pixel_start (const PsppireAxis *a, gint unit)
63 {
64   PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
65   const struct tower_node *node;
66
67   if ( unit >= tower_count (&ah->tower))
68     return tower_height (&ah->tower);
69
70   node = tower_get (&ah->tower, unit);
71
72   return  tower_node_get_level (node);
73 }
74
75
76 static gint
77 unit_size (const PsppireAxis *a, gint unit)
78 {
79   PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
80   const struct tower_node *node;
81   if  (unit >= tower_count (&ah->tower))
82     return 0;
83
84   node = tower_get (&ah->tower, unit);
85
86   return tower_node_get_size (node);
87 }
88
89
90 static glong
91 total_size (const PsppireAxis *a)
92 {
93   glong s;
94   PsppireAxisHetero *ah = PSPPIRE_AXIS_HETERO (a);
95
96   s =  tower_height (&ah->tower);
97   return s;
98 }
99
100 static void
101 psppire_hetero_iface_init (PsppireAxisIface *iface)
102 {
103   iface->unit_size = unit_size;
104   iface->unit_count = unit_count;
105   iface->pixel_start = pixel_start;
106   iface->get_unit_at_pixel = get_unit_at_pixel;
107   iface->total_size = total_size;
108 }
109
110 /* --- functions --- */
111 /**
112  * psppire_axis_hetero_get_type:
113  * @returns: the type ID for accelerator groups.
114  */
115 GType
116 psppire_axis_hetero_get_type (void)
117 {
118   static GType object_type = 0;
119
120   if (!object_type)
121     {
122       static const GTypeInfo object_info = {
123         sizeof (PsppireAxisHeteroClass),
124         (GBaseInitFunc) NULL,
125         (GBaseFinalizeFunc) NULL,
126         (GClassInitFunc) psppire_axis_hetero_class_init,
127         NULL,   /* class_finalize */
128         NULL,   /* class_data */
129         sizeof (PsppireAxisHetero),
130         0,      /* n_preallocs */
131         (GInstanceInitFunc) psppire_axis_hetero_init,
132       };
133
134
135       static const GInterfaceInfo interface_info =
136       {
137         (GInterfaceInitFunc) psppire_hetero_iface_init,
138         NULL,
139         NULL
140       };
141
142       object_type = g_type_register_static (G_TYPE_PSPPIRE_AXIS,
143                                             "PsppireAxisHetero",
144                                             &object_info, 0);
145
146       g_type_add_interface_static (object_type,
147                                    PSPPIRE_TYPE_AXIS_IFACE,
148                                    &interface_info);
149     }
150
151   return object_type;
152 }
153
154 static void
155 psppire_axis_hetero_class_init (PsppireAxisHeteroClass *class)
156 {
157   GObjectClass *object_class = G_OBJECT_CLASS (class);
158   parent_class = g_type_class_peek_parent (class);
159
160   object_class->finalize = psppire_axis_hetero_finalize;
161 }
162
163
164 static void
165 psppire_axis_hetero_init (PsppireAxisHetero *axis)
166 {
167   axis->pool = NULL;
168   psppire_axis_hetero_clear (axis);
169 }
170
171
172 static void
173 psppire_axis_hetero_finalize (GObject *object)
174 {
175   PsppireAxisHetero *a = PSPPIRE_AXIS_HETERO (object);
176   pool_destroy (a->pool);
177   G_OBJECT_CLASS (parent_class)->finalize (object);
178 }
179
180 /**
181  * psppire_axis_hetero_new:
182  * @returns: a new #PsppireAxisHetero object
183  *
184  * Creates a new #PsppireAxisHetero.
185  */
186 PsppireAxisHetero*
187 psppire_axis_hetero_new (void)
188 {
189   return g_object_new (G_TYPE_PSPPIRE_AXIS_HETERO, NULL);
190 }
191
192
193 void
194 psppire_axis_hetero_append (PsppireAxisHetero *a, gint size)
195 {
196   struct tower_node *new ;
197
198   g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
199
200   new = pool_malloc (a->pool, sizeof *new);
201
202   tower_insert (&a->tower, size, new, NULL);
203 }
204
205
206
207 /* Insert a new unit of size SIZE before position POSN */
208 void
209 psppire_axis_hetero_insert (PsppireAxisHetero *a, gint size, gint posn)
210 {
211   struct tower_node *new;
212   struct tower_node *before = NULL;
213
214   g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
215
216   new = pool_malloc (a->pool, sizeof *new);
217
218   if ( posn != tower_count (&a->tower))
219     before = tower_get (&a->tower, posn);
220
221   tower_insert (&a->tower, size, new, before);
222 }
223
224
225 void
226 psppire_axis_hetero_remove (PsppireAxisHetero *a, gint posn)
227 {
228   struct tower_node *node;
229
230   g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
231
232   node = tower_get (&a->tower, posn);
233
234   tower_delete (&a->tower, node);
235
236   pool_free (a->pool, node);
237 }
238
239
240 void
241 psppire_axis_hetero_resize_unit (PsppireAxisHetero *a, gint size, gint posn)
242 {
243   struct tower_node *node;
244
245   g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
246
247   node = tower_get (&a->tower, posn);
248
249   tower_resize (&a->tower, node, size);
250 }
251
252
253 void
254 psppire_axis_hetero_clear (PsppireAxisHetero *a)
255 {
256   g_return_if_fail (PSPPIRE_IS_AXIS_HETERO (a));
257
258   pool_destroy (a->pool);
259   a->pool = pool_create ();
260   tower_init (&a->tower);
261 }
262
263