1 /* $Id: gtkdatabox_graph.c 4 2008-06-22 09:19:11Z rbock $ */
2 /* GtkDatabox - An extension to the gtk+ library
3 * Copyright (C) 1998 - 2008 Dr. Roland Bock
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public License
7 * as published by the Free Software Foundation; either version 2.1
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #include <gtkdatabox_graph.h>
21 #include <gtk/gtk.h>
22
23 G_DEFINE_TYPE(GtkDataboxGraph, gtk_databox_graph,
24 G_TYPE_OBJECT)
25
26 static void gtk_databox_graph_real_draw (GtkDataboxGraph * graph,
27 GtkDatabox * draw);
28 static gint gtk_databox_graph_real_calculate_extrema (GtkDataboxGraph * graph,
29 gfloat * min_x,
30 gfloat * max_x,
31 gfloat * min_y,
32 gfloat * max_y);
33
34 /* IDs of properties */
35 enum
36 {
37 GRAPH_COLOR = 1,
38 GRAPH_SIZE,
39 GRAPH_HIDE,
40 };
41
42 /**
43 * GtkDataboxGraphPrivate
44 *
45 * A private data structure used by the #GtkDataboxGraph. It shields all internal things
46 * from developers who are just using the object.
47 *
48 **/
49 typedef struct _GtkDataboxGraphPrivate GtkDataboxGraphPrivate;
50
51 struct _GtkDataboxGraphPrivate
52 {
53 GdkRGBA color;
54 gint size;
55 gboolean hide;
56 GdkRGBA rgba;
57 };
58
59 static void
gtk_databox_graph_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)60 gtk_databox_graph_set_property (GObject * object,
61 guint property_id,
62 const GValue * value, GParamSpec * pspec)
63 {
64 GtkDataboxGraph *graph = GTK_DATABOX_GRAPH (object);
65
66 switch (property_id)
67 {
68 case GRAPH_COLOR:
69 {
70 gtk_databox_graph_set_color (graph,
71 (GdkRGBA *)
72 g_value_get_pointer (value));
73 }
74 break;
75 case GRAPH_SIZE:
76 {
77 gtk_databox_graph_set_size (graph, g_value_get_int (value));
78 }
79 break;
80 case GRAPH_HIDE:
81 {
82 gtk_databox_graph_set_hide (graph, g_value_get_boolean (value));
83 }
84 break;
85 default:
86 /* We don't have any other property... */
87 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
88 break;
89 }
90 }
91
92 static void
gtk_databox_graph_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)93 gtk_databox_graph_get_property (GObject * object,
94 guint property_id,
95 GValue * value, GParamSpec * pspec)
96 {
97 GtkDataboxGraph *graph = GTK_DATABOX_GRAPH (object);
98
99 switch (property_id)
100 {
101 case GRAPH_COLOR:
102 {
103 g_value_set_pointer (value, gtk_databox_graph_get_color (graph));
104 }
105 break;
106 case GRAPH_SIZE:
107 {
108 g_value_set_int (value, gtk_databox_graph_get_size (graph));
109 }
110 break;
111 case GRAPH_HIDE:
112 {
113 g_value_set_boolean (value, gtk_databox_graph_get_hide (graph));
114 }
115 break;
116 default:
117 /* We don't have any other property... */
118 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
119 break;
120 }
121 }
122
123 /**
124 * gtk_databox_graph_create_gc:
125 * @graph: A #GtkDataboxGraph object
126 * @box: A #GtkDatabox object
127 *
128 * Virtual function which creates a graphics context for the @graph.
129 *
130 * Typically called by derived graph objects when the graphics context is needed for the first time.
131 *
132 * Return value: The new graphics context.
133 */
134 cairo_t*
gtk_databox_graph_create_gc(GtkDataboxGraph * graph,GtkDatabox * box)135 gtk_databox_graph_create_gc (GtkDataboxGraph * graph,
136 GtkDatabox* box)
137 {
138 return GTK_DATABOX_GRAPH_GET_CLASS (graph)->create_gc (graph, box);
139 }
140
141 static cairo_t *
gtk_databox_graph_real_create_gc(GtkDataboxGraph * graph,GtkDatabox * box)142 gtk_databox_graph_real_create_gc (GtkDataboxGraph * graph,
143 GtkDatabox* box)
144 {
145 GtkDataboxGraphPrivate *priv = GTK_DATABOX_GRAPH_GET_PRIVATE(graph);
146 cairo_t *cr;
147
148 g_return_val_if_fail (GTK_DATABOX_IS_GRAPH (graph), NULL);
149
150 cr = cairo_create (gtk_databox_get_backing_surface (box));
151 gdk_cairo_set_source_rgba (cr, &priv->color);
152 cairo_set_line_width (cr, (priv->size > 1) ? priv->size : 1);
153
154 return cr;
155 }
156
157 static void
gtk_databox_graph_class_init(GtkDataboxGraphClass * klass)158 gtk_databox_graph_class_init (GtkDataboxGraphClass *klass)
159 {
160 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
161 GParamSpec *graph_param_spec;
162
163 gobject_class->set_property = gtk_databox_graph_set_property;
164 gobject_class->get_property = gtk_databox_graph_get_property;
165
166 graph_param_spec = g_param_spec_pointer ("color",
167 "Graph color",
168 "Color of graph",
169 G_PARAM_READWRITE);
170
171 g_object_class_install_property (gobject_class,
172 GRAPH_COLOR, graph_param_spec);
173
174 graph_param_spec = g_param_spec_int ("size", "Graph size", "Size of displayed items", G_MININT, G_MAXINT, 0, /* default value */
175 G_PARAM_READWRITE);
176
177 g_object_class_install_property (gobject_class,
178 GRAPH_SIZE, graph_param_spec);
179
180 graph_param_spec = g_param_spec_boolean ("hide", "Graph hidden", "Determine if graph is hidden or not", FALSE, /* default value */
181 G_PARAM_READWRITE);
182
183 g_object_class_install_property (gobject_class,
184 GRAPH_HIDE, graph_param_spec);
185
186 klass->draw = gtk_databox_graph_real_draw;
187 klass->calculate_extrema = gtk_databox_graph_real_calculate_extrema;
188 klass->create_gc = gtk_databox_graph_real_create_gc;
189
190 g_type_class_add_private (klass, sizeof (GtkDataboxGraphPrivate));
191 }
192
gtk_databox_graph_init(GtkDataboxGraph * graph)193 static void gtk_databox_graph_init (GtkDataboxGraph *graph) { graph = graph;}
194
195 /**
196 * gtk_databox_graph_draw:
197 * @graph: A #GtkDataboxGraph object
198 * @box: A #GtkDatabox object
199 *
200 * Virtual function which draws the #GtkDataboxGraph on the drawing area of the GtkDatabox object.
201 *
202 * Typically this function is called by #GtkDatabox objects.
203 *
204 */
205 void
gtk_databox_graph_draw(GtkDataboxGraph * graph,GtkDatabox * box)206 gtk_databox_graph_draw (GtkDataboxGraph * graph, GtkDatabox* box)
207 {
208 if (!GTK_DATABOX_GRAPH_GET_PRIVATE(graph)->hide)
209 GTK_DATABOX_GRAPH_GET_CLASS (graph)->draw (graph, box);
210 }
211
212 /**
213 * gtk_databox_graph_calculate_extrema:
214 * @graph: A #GtkDataboxGraph object
215 * @min_x: Will be filled with the lowest x value of the dataset
216 * @max_x: Will be filled with the highest x value of the dataset
217 * @min_y: Will be filled with the lowest y value of the dataset
218 * @max_y: Will be filled with the highest y value of the dataset
219 *
220 * Virtual function which determines the minimum and maximum x and y values of the values of this
221 * #GtkDataboxGraph object if applicable (there are graphs which do
222 * not contain data).
223 *
224 * Return value: 0 on success,
225 * -1 if no data is available,
226 *
227 */
228 gint
gtk_databox_graph_calculate_extrema(GtkDataboxGraph * graph,gfloat * min_x,gfloat * max_x,gfloat * min_y,gfloat * max_y)229 gtk_databox_graph_calculate_extrema (GtkDataboxGraph * graph,
230 gfloat * min_x, gfloat * max_x,
231 gfloat * min_y, gfloat * max_y)
232 {
233 return
234 GTK_DATABOX_GRAPH_GET_CLASS (graph)->calculate_extrema (graph, min_x,
235 max_x, min_y,
236 max_y);
237 }
238
239 static void
gtk_databox_graph_real_draw(GtkDataboxGraph * graph,GtkDatabox * box)240 gtk_databox_graph_real_draw (GtkDataboxGraph * graph,
241 GtkDatabox* box)
242 {
243 g_return_if_fail (graph);
244 g_return_if_fail (box);
245
246 /* We have no data... */
247 return;
248 }
249
250
251 static gint
gtk_databox_graph_real_calculate_extrema(GtkDataboxGraph * graph,gfloat * min_x,gfloat * max_x,gfloat * min_y,gfloat * max_y)252 gtk_databox_graph_real_calculate_extrema (GtkDataboxGraph * graph,
253 gfloat * min_x, gfloat * max_x,
254 gfloat * min_y, gfloat * max_y)
255 {
256 g_return_val_if_fail (graph, -1);
257 g_return_val_if_fail (min_x, -1);
258 g_return_val_if_fail (max_x, -1);
259 g_return_val_if_fail (min_y, -1);
260 g_return_val_if_fail (max_y, -1);
261
262 /* We have no data... */
263 return -1;
264 }
265
266 /**
267 * gtk_databox_graph_set_color:
268 * @graph: A #GtkDataboxGraph object
269 * @color: Color which is to be used by the graph object
270 *
271 * Sets the color which the #GtkDataboxGraph object is supposed to be using when drawing itself.
272 *
273 */
274 void
gtk_databox_graph_set_color(GtkDataboxGraph * graph,GdkRGBA * color)275 gtk_databox_graph_set_color (GtkDataboxGraph * graph, GdkRGBA * color)
276 {
277 GtkDataboxGraphPrivate *priv = GTK_DATABOX_GRAPH_GET_PRIVATE(graph);
278
279 g_return_if_fail (GTK_DATABOX_IS_GRAPH (graph));
280
281 priv->color = *color;
282
283 g_object_notify (G_OBJECT (graph), "color");
284 }
285
286 /**
287 * gtk_databox_graph_get_color:
288 * @graph: A #GtkDataboxGraph object
289 *
290 * Gets the current color of the graph elements (e.g. points).
291 *
292 * Return value: The color of the graph.
293 *
294 */
295 GdkRGBA *
gtk_databox_graph_get_color(GtkDataboxGraph * graph)296 gtk_databox_graph_get_color (GtkDataboxGraph * graph)
297 {
298 return >K_DATABOX_GRAPH_GET_PRIVATE(graph)->color;
299 }
300
301 /**
302 * gtk_databox_graph_set_size:
303 * @graph: A #GtkDataboxGraph object
304 * @size: Size of graph elements for the graph object
305 *
306 * Sets the size (e.g. line width) which the #GtkDataboxGraph object is supposed to be using when drawing itself.
307 *
308 */
309 void
gtk_databox_graph_set_size(GtkDataboxGraph * graph,gint size)310 gtk_databox_graph_set_size (GtkDataboxGraph * graph, gint size)
311 {
312 g_return_if_fail (GTK_DATABOX_IS_GRAPH (graph));
313
314 GTK_DATABOX_GRAPH_GET_PRIVATE(graph)->size = MAX (1, size);;
315
316 g_object_notify (G_OBJECT (graph), "size");
317 }
318
319 /**
320 * gtk_databox_graph_get_size:
321 * @graph: A #GtkDataboxGraph object
322 *
323 * Gets the size of the graph elements (e.g. the line width).
324 *
325 * Return value: size of the graph elements
326 *
327 */
328 gint
gtk_databox_graph_get_size(GtkDataboxGraph * graph)329 gtk_databox_graph_get_size (GtkDataboxGraph * graph)
330 {
331 g_return_val_if_fail (GTK_DATABOX_IS_GRAPH (graph), -1);
332
333 return GTK_DATABOX_GRAPH_GET_PRIVATE(graph)->size;
334 }
335
336 /**
337 * gtk_databox_graph_set_hide:
338 * @graph: A #GtkDataboxGraph object
339 * @hide: Declares whether should be hidden (true) or not (false).
340 *
341 * Hidden graphs are not shown, when the #GtkDatabox containing them is redrawn.
342 *
343 */
344 void
gtk_databox_graph_set_hide(GtkDataboxGraph * graph,gboolean hide)345 gtk_databox_graph_set_hide (GtkDataboxGraph * graph, gboolean hide)
346 {
347 g_return_if_fail (GTK_DATABOX_IS_GRAPH (graph));
348
349 GTK_DATABOX_GRAPH_GET_PRIVATE(graph)->hide = hide;
350
351 g_object_notify (G_OBJECT (graph), "hide");
352 }
353
354 /**
355 * gtk_databox_graph_get_hide:
356 * @graph: A #GtkDataboxGraph object
357 *
358 * Gets the current "hide" status.
359 *
360 * Return value: Whether the graph is hidden (true) or not (false).
361 *
362 */
363 gboolean
gtk_databox_graph_get_hide(GtkDataboxGraph * graph)364 gtk_databox_graph_get_hide (GtkDataboxGraph * graph)
365 {
366 g_return_val_if_fail (GTK_DATABOX_IS_GRAPH (graph), -1);
367
368 return GTK_DATABOX_GRAPH_GET_PRIVATE(graph)->hide;
369 }
370