1 /* gtkplotcanvas - gtkplot canvas widget for gtk+
2 * Copyright 1999-2001 Adrian E. Feiguin <feiguin@ifir.edu.ar>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Library General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library 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 GNU
12 * Library General Public License for more details.
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
18 */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <math.h>
24 #include <gtk/gtk.h>
25 #include "gtkplot.h"
26 #include "gtkplotcanvas.h"
27 #include "gtkplotcanvasellipse.h"
28 #include "gtkplotgdk.h"
29 #include "gtkplotps.h"
30
31 #define DEFAULT_MARKER_SIZE 6
32 #define P_(string) string
33
34 enum {
35 ARG_0,
36 ARG_LINE,
37 ARG_FILLED,
38 ARG_BG
39 };
40
41 static void gtk_plot_canvas_ellipse_init (GtkPlotCanvasEllipse *ellipse);
42 static void gtk_plot_canvas_ellipse_class_init (GtkPlotCanvasChildClass *klass);
43 static void gtk_plot_canvas_ellipse_draw (GtkPlotCanvas *canvas,
44 GtkPlotCanvasChild *child);
45 static void gtk_plot_canvas_ellipse_select (GtkPlotCanvas *canvas,
46 GtkPlotCanvasChild *child,
47 GtkAllocation area);
48 static void gtk_plot_canvas_ellipse_move (GtkPlotCanvas *canvas,
49 GtkPlotCanvasChild *child,
50 gdouble x, gdouble y);
51 static void gtk_plot_canvas_ellipse_resize (GtkPlotCanvas *canvas,
52 GtkPlotCanvasChild *child,
53 gdouble x1, gdouble y1,
54 gdouble x2, gdouble y2);
55 static void gtk_plot_canvas_ellipse_get_property(GObject *object,
56 guint prop_id,
57 GValue *value,
58 GParamSpec *pspec);
59 static void gtk_plot_canvas_ellipse_set_property(GObject *object,
60 guint prop_id,
61 const GValue *value,
62 GParamSpec *pspec);
63
64
65 extern gint roundint (gdouble x);
66 static GtkPlotCanvasChildClass *parent_class = NULL;
67
68 GtkType
gtk_plot_canvas_ellipse_get_type(void)69 gtk_plot_canvas_ellipse_get_type (void)
70 {
71 static GtkType plot_canvas_ellipse_type = 0;
72
73 if (!plot_canvas_ellipse_type)
74 {
75 GtkTypeInfo plot_canvas_ellipse_info =
76 {
77 "GtkPlotCanvasEllipse",
78 sizeof (GtkPlotCanvasEllipse),
79 sizeof (GtkPlotCanvasEllipseClass),
80 (GtkClassInitFunc) gtk_plot_canvas_ellipse_class_init,
81 (GtkObjectInitFunc) gtk_plot_canvas_ellipse_init,
82 /* reserved 1*/ NULL,
83 /* reserved 2 */ NULL,
84 (GtkClassInitFunc) NULL,
85 };
86
87 plot_canvas_ellipse_type = gtk_type_unique (gtk_plot_canvas_child_get_type(), &plot_canvas_ellipse_info);
88 }
89 return plot_canvas_ellipse_type;
90 }
91
92 GtkPlotCanvasChild*
gtk_plot_canvas_ellipse_new(GtkPlotLineStyle style,gfloat width,const GdkColor * fg,const GdkColor * bg,gboolean fill)93 gtk_plot_canvas_ellipse_new (GtkPlotLineStyle style,
94 gfloat width,
95 const GdkColor *fg,
96 const GdkColor *bg,
97 gboolean fill)
98 {
99 GtkPlotCanvasEllipse *ellipse;
100
101 ellipse = gtk_type_new (gtk_plot_canvas_ellipse_get_type ());
102
103 ellipse->line.line_width = width;
104 if(fg) ellipse->line.color = *fg;
105 if(bg) ellipse->bg = *bg;
106 ellipse->filled = fill;
107
108 return GTK_PLOT_CANVAS_CHILD (ellipse);
109 }
110
111 static void
gtk_plot_canvas_ellipse_init(GtkPlotCanvasEllipse * ellipse)112 gtk_plot_canvas_ellipse_init (GtkPlotCanvasEllipse *ellipse)
113 {
114 gdk_color_black(gdk_colormap_get_system(), &ellipse->line.color);
115 gdk_color_white(gdk_colormap_get_system(), &ellipse->bg);
116
117 ellipse->line.line_style = GTK_PLOT_LINE_SOLID;
118 ellipse->line.line_width = 0;
119 ellipse->filled = TRUE;
120 }
121
122 static void
gtk_plot_canvas_ellipse_class_init(GtkPlotCanvasChildClass * klass)123 gtk_plot_canvas_ellipse_class_init (GtkPlotCanvasChildClass *klass)
124 {
125 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
126
127 parent_class = gtk_type_class (gtk_plot_canvas_child_get_type ());
128
129 klass->draw = gtk_plot_canvas_ellipse_draw;
130 klass->move = gtk_plot_canvas_ellipse_move;
131 klass->move_resize = gtk_plot_canvas_ellipse_resize;
132 klass->draw_selection = gtk_plot_canvas_ellipse_select;
133
134 gobject_class->get_property = gtk_plot_canvas_ellipse_get_property;
135 gobject_class->set_property = gtk_plot_canvas_ellipse_set_property;
136
137 g_object_class_install_property (gobject_class,
138 ARG_LINE,
139 g_param_spec_pointer ("line",
140 P_("Line"),
141 P_("Line Attributes"),
142 G_PARAM_READABLE|G_PARAM_WRITABLE));
143 g_object_class_install_property (gobject_class,
144 ARG_FILLED,
145 g_param_spec_boolean ("filled",
146 P_("Filled"),
147 P_("Fill Figure"),
148 FALSE,
149 G_PARAM_READABLE|G_PARAM_WRITABLE));
150 g_object_class_install_property (gobject_class,
151 ARG_BG,
152 g_param_spec_pointer ("color_bg",
153 P_("Filling Color"),
154 P_("Filling Color"),
155 G_PARAM_READABLE|G_PARAM_WRITABLE));
156
157 }
158
159 static void
gtk_plot_canvas_ellipse_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)160 gtk_plot_canvas_ellipse_get_property (GObject *object,
161 guint prop_id,
162 GValue *value,
163 GParamSpec *pspec)
164 {
165 GtkPlotCanvasEllipse *ellipse = GTK_PLOT_CANVAS_ELLIPSE (object);
166
167 switch(prop_id){
168 case ARG_LINE:
169 g_value_set_pointer(value, &ellipse->line);
170 break;
171 case ARG_FILLED:
172 g_value_set_boolean(value, ellipse->filled);
173 break;
174 case ARG_BG:
175 g_value_set_pointer(value, &ellipse->bg);
176 break;
177 }
178 }
179
180 static void
gtk_plot_canvas_ellipse_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)181 gtk_plot_canvas_ellipse_set_property (GObject *object,
182 guint prop_id,
183 const GValue *value,
184 GParamSpec *pspec)
185 {
186 GtkPlotCanvasEllipse *ellipse = GTK_PLOT_CANVAS_ELLIPSE (object);
187
188 switch(prop_id){
189 case ARG_LINE:
190 ellipse->line = *((GtkPlotLine *)g_value_get_pointer(value));
191 break;
192 case ARG_FILLED:
193 ellipse->filled = g_value_get_boolean(value);
194 break;
195 case ARG_BG:
196 ellipse->bg = *((GdkColor *)g_value_get_pointer(value));
197 break;
198 }
199 }
200
201 static void
gtk_plot_canvas_ellipse_draw(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)202 gtk_plot_canvas_ellipse_draw (GtkPlotCanvas *canvas,
203 GtkPlotCanvasChild *child)
204 {
205 GtkPlotCanvasEllipse *ellipse = GTK_PLOT_CANVAS_ELLIPSE(child);
206 gint width = child->allocation.width;
207 gint height = child->allocation.height;
208
209 if(width == 0 && height == 0) return;
210
211 if(ellipse->filled){
212 gtk_plot_pc_set_color(canvas->pc, &ellipse->bg);
213 gtk_plot_pc_draw_ellipse(canvas->pc, TRUE,
214 child->allocation.x, child->allocation.y,
215 width, height);
216 }
217 gtk_plot_canvas_set_line_attributes(canvas, ellipse->line);
218 if(ellipse->line.line_style != GTK_PLOT_LINE_NONE)
219 gtk_plot_pc_draw_ellipse(canvas->pc, FALSE,
220 child->allocation.x, child->allocation.y,
221 width, height);
222
223 }
224
225 static void
draw_marker(GtkPlotCanvas * canvas,GdkGC * gc,gint x,gint y)226 draw_marker(GtkPlotCanvas *canvas, GdkGC *gc, gint x, gint y)
227 {
228 GdkDrawable *darea;
229
230 darea = GTK_WIDGET(canvas)->window;
231
232 gdk_draw_rectangle(darea, gc, TRUE,
233 x - DEFAULT_MARKER_SIZE / 2, y - DEFAULT_MARKER_SIZE / 2,
234 DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
235 }
236
237 static void
gtk_plot_canvas_ellipse_select(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,GtkAllocation area)238 gtk_plot_canvas_ellipse_select(GtkPlotCanvas *canvas, GtkPlotCanvasChild *child, GtkAllocation area)
239 {
240 GdkGC *xor_gc = NULL;
241 GdkGCValues values;
242
243 gdk_gc_get_values(GTK_WIDGET(canvas)->style->fg_gc[0], &values);
244 values.function = GDK_INVERT;
245 values.foreground = GTK_WIDGET(canvas)->style->white;
246 values.subwindow_mode = GDK_INCLUDE_INFERIORS;
247 xor_gc = gdk_gc_new_with_values(GTK_WIDGET(canvas)->window,
248 &values,
249 GDK_GC_FOREGROUND |
250 GDK_GC_FUNCTION |
251 GDK_GC_SUBWINDOW);
252
253 gdk_draw_rectangle (GTK_WIDGET(canvas)->window,
254 xor_gc,
255 FALSE,
256 area.x, area.y,
257 area.width, area.height);
258 draw_marker(canvas, xor_gc, area.x, area.y);
259 draw_marker(canvas, xor_gc, area.x, area.y + area.height);
260 draw_marker(canvas, xor_gc, area.x + area.width, area.y);
261 draw_marker(canvas, xor_gc, area.x + area.width, area.y + area.height);
262 if(area.height > DEFAULT_MARKER_SIZE * 2){
263 draw_marker(canvas, xor_gc, area.x, area.y + area.height / 2);
264 draw_marker(canvas, xor_gc, area.x + area.width,
265 area.y + area.height / 2);
266 }
267 if(area.width > DEFAULT_MARKER_SIZE * 2){
268 draw_marker(canvas, xor_gc, area.x + area.width / 2, area.y);
269 draw_marker(canvas, xor_gc, area.x + area.width / 2,
270 area.y + area.height);
271 }
272
273 gdk_gc_set_line_attributes(xor_gc, 1, 1, 0, 0);
274 gdk_draw_arc (GTK_WIDGET(canvas)->window, xor_gc,
275 FALSE,
276 roundint(area.x), roundint(area.y),
277 roundint(area.width), roundint(area.height), 0, 25000);
278
279 if(xor_gc) gdk_gc_unref(xor_gc);
280 }
281
282
283 static void
gtk_plot_canvas_ellipse_move(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x,gdouble y)284 gtk_plot_canvas_ellipse_move (GtkPlotCanvas *canvas,
285 GtkPlotCanvasChild *child,
286 gdouble x, gdouble y)
287 {
288 return;
289 }
290
291 static void
gtk_plot_canvas_ellipse_resize(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x1,gdouble y1,gdouble x2,gdouble y2)292 gtk_plot_canvas_ellipse_resize (GtkPlotCanvas *canvas,
293 GtkPlotCanvasChild *child,
294 gdouble x1, gdouble y1,
295 gdouble x2, gdouble y2)
296 {
297 return;
298 }
299
300 void
gtk_plot_canvas_ellipse_set_attributes(GtkPlotCanvasEllipse * ellipse,GtkPlotLineStyle style,gdouble width,const GdkColor * fg,const GdkColor * bg,gboolean fill)301 gtk_plot_canvas_ellipse_set_attributes (GtkPlotCanvasEllipse *ellipse,
302 GtkPlotLineStyle style,
303 gdouble width,
304 const GdkColor *fg,
305 const GdkColor *bg,
306 gboolean fill)
307 {
308 if(fg) ellipse->line.color = *fg;
309 if(bg) ellipse->bg = *bg;
310 ellipse->line.line_width = width;
311 ellipse->line.line_style = style;
312 ellipse->filled = fill;
313 }
314
315