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 "gtkplotcanvasrectangle.h"
28 #include "gtkplotgdk.h"
29 #include "gtkplotps.h"
30 
31 #define P_(string) string
32 
33 enum {
34   ARG_0,
35   ARG_LINE,
36   ARG_FILLED,
37   ARG_BORDER,
38   ARG_SHADOW_WIDTH,
39   ARG_BG
40 };
41 
42 
43 static void gtk_plot_canvas_rectangle_init	(GtkPlotCanvasRectangle *rectangle);
44 static void gtk_plot_canvas_rectangle_class_init(GtkPlotCanvasChildClass *klass);
45 static void gtk_plot_canvas_rectangle_draw 	(GtkPlotCanvas *canvas,
46 						 GtkPlotCanvasChild *child);
47 static void gtk_plot_canvas_rectangle_move	(GtkPlotCanvas *canvas,
48 						 GtkPlotCanvasChild *child,
49 						 gdouble x, gdouble y);
50 static void gtk_plot_canvas_rectangle_resize	(GtkPlotCanvas *canvas,
51 						 GtkPlotCanvasChild *child,
52 						 gdouble x1, gdouble y1,
53 						 gdouble x2, gdouble y2);
54 static void gtk_plot_canvas_rectangle_get_property(GObject      *object,
55                                                  guint            prop_id,
56                                                  GValue          *value,
57                                                  GParamSpec      *pspec);
58 static void gtk_plot_canvas_rectangle_set_property(GObject      *object,
59                                                  guint            prop_id,
60                                                  const GValue          *value,
61                                                  GParamSpec      *pspec);
62 
63 extern gint roundint                     (gdouble x);
64 static GtkPlotCanvasChildClass *parent_class = NULL;
65 
66 GtkType
gtk_plot_canvas_rectangle_get_type(void)67 gtk_plot_canvas_rectangle_get_type (void)
68 {
69   static GtkType plot_canvas_rectangle_type = 0;
70 
71   if (!plot_canvas_rectangle_type)
72     {
73       GtkTypeInfo plot_canvas_rectangle_info =
74       {
75 	"GtkPlotCanvasRectangle",
76 	sizeof (GtkPlotCanvasRectangle),
77 	sizeof (GtkPlotCanvasRectangleClass),
78 	(GtkClassInitFunc) gtk_plot_canvas_rectangle_class_init,
79 	(GtkObjectInitFunc) gtk_plot_canvas_rectangle_init,
80 	/* reserved 1*/ NULL,
81         /* reserved 2 */ NULL,
82         (GtkClassInitFunc) NULL,
83       };
84 
85       plot_canvas_rectangle_type = gtk_type_unique (gtk_plot_canvas_child_get_type(), &plot_canvas_rectangle_info);
86     }
87   return plot_canvas_rectangle_type;
88 }
89 
90 static void
gtk_plot_canvas_rectangle_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)91 gtk_plot_canvas_rectangle_get_property (GObject      *object,
92                                     guint            prop_id,
93                                     GValue          *value,
94                                     GParamSpec      *pspec)
95 {
96   GtkPlotCanvasRectangle *rectangle = GTK_PLOT_CANVAS_RECTANGLE (object);
97 
98   switch(prop_id){
99     case ARG_LINE:
100       g_value_set_pointer(value, &rectangle->line);
101       break;
102     case ARG_FILLED:
103       g_value_set_boolean(value, rectangle->filled);
104       break;
105     case ARG_BORDER:
106       g_value_set_int(value, rectangle->border);
107       break;
108     case ARG_SHADOW_WIDTH:
109       g_value_set_int(value, rectangle->shadow_width);
110       break;
111     case ARG_BG:
112       g_value_set_pointer(value, &rectangle->bg);
113       break;
114   }
115 }
116 
117 static void
gtk_plot_canvas_rectangle_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)118 gtk_plot_canvas_rectangle_set_property (GObject      *object,
119                                     guint            prop_id,
120                                     const GValue          *value,
121                                     GParamSpec      *pspec)
122 {
123   GtkPlotCanvasRectangle *rectangle = GTK_PLOT_CANVAS_RECTANGLE (object);
124 
125   switch(prop_id){
126     case ARG_LINE:
127       rectangle->line = *((GtkPlotLine *)g_value_get_pointer(value));
128       break;
129     case ARG_FILLED:
130       rectangle->filled = g_value_get_boolean(value);
131       break;
132     case ARG_BORDER:
133       rectangle->border = g_value_get_int(value);
134       break;
135     case ARG_SHADOW_WIDTH:
136       rectangle->shadow_width = g_value_get_int(value);
137       break;
138     case ARG_BG:
139       rectangle->bg = *((GdkColor *)g_value_get_pointer(value));
140       break;
141   }
142 }
143 
144 GtkPlotCanvasChild*
gtk_plot_canvas_rectangle_new(GtkPlotLineStyle style,gfloat width,const GdkColor * fg,const GdkColor * bg,GtkPlotBorderStyle border,gboolean fill)145 gtk_plot_canvas_rectangle_new (GtkPlotLineStyle style,
146                           gfloat width,
147                           const GdkColor *fg,
148                           const GdkColor *bg,
149 			  GtkPlotBorderStyle border,
150                           gboolean fill)
151 {
152   GtkPlotCanvasRectangle *rectangle;
153 
154   rectangle = gtk_type_new (gtk_plot_canvas_rectangle_get_type ());
155 
156   rectangle->line.line_width = width;
157   if(fg) rectangle->line.color = *fg;
158   if(bg) rectangle->bg = *bg;
159   rectangle->border = border;
160   rectangle->filled = fill;
161 
162   return GTK_PLOT_CANVAS_CHILD (rectangle);
163 }
164 
165 static void
gtk_plot_canvas_rectangle_init(GtkPlotCanvasRectangle * rectangle)166 gtk_plot_canvas_rectangle_init (GtkPlotCanvasRectangle *rectangle)
167 {
168   gdk_color_black(gdk_colormap_get_system(), &rectangle->line.color);
169   gdk_color_white(gdk_colormap_get_system(), &rectangle->bg);
170 
171   rectangle->line.line_style = GTK_PLOT_LINE_SOLID;
172   rectangle->line.line_width = 0;
173   rectangle->shadow_width = 3;
174   rectangle->border = GTK_PLOT_BORDER_LINE;
175   rectangle->filled = TRUE;
176 }
177 
178 static void
gtk_plot_canvas_rectangle_class_init(GtkPlotCanvasChildClass * klass)179 gtk_plot_canvas_rectangle_class_init (GtkPlotCanvasChildClass *klass)
180 {
181   GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
182 
183   parent_class = gtk_type_class (gtk_plot_canvas_child_get_type ());
184 
185   klass->draw = gtk_plot_canvas_rectangle_draw;
186   klass->move = gtk_plot_canvas_rectangle_move;
187   klass->move_resize = gtk_plot_canvas_rectangle_resize;
188 
189   gobject_class->get_property = gtk_plot_canvas_rectangle_get_property;
190   gobject_class->set_property = gtk_plot_canvas_rectangle_set_property;
191 
192   g_object_class_install_property (gobject_class,
193                            ARG_LINE,
194   g_param_spec_pointer ("line",
195                            P_("Line Attributes"),
196                            P_("Line Attributes"),
197                            G_PARAM_READABLE|G_PARAM_WRITABLE));
198   g_object_class_install_property (gobject_class,
199                            ARG_FILLED,
200   g_param_spec_boolean ("filled",
201                            P_("Filled"),
202                            P_("Fill Figure"),
203                            FALSE,
204                            G_PARAM_READABLE|G_PARAM_WRITABLE));
205   g_object_class_install_property (gobject_class,
206                            ARG_BORDER,
207   g_param_spec_int ("border",
208                            P_("Border"),
209                            P_("Border Width"),
210                            0,G_MAXINT,0,
211                            G_PARAM_READABLE|G_PARAM_WRITABLE));
212   g_object_class_install_property (gobject_class,
213                            ARG_SHADOW_WIDTH,
214   g_param_spec_int ("shadow_width",
215                            P_("Shadow Width"),
216                            P_("Shadow Width"),
217                            0,G_MAXINT,0,
218                            G_PARAM_READABLE|G_PARAM_WRITABLE));
219   g_object_class_install_property (gobject_class,
220                            ARG_BG,
221   g_param_spec_pointer ("color_bg",
222                            P_("Filling Color"),
223                            P_("Filling Color"),
224                            G_PARAM_READABLE|G_PARAM_WRITABLE));
225 }
226 
227 static void
gtk_plot_canvas_rectangle_draw(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)228 gtk_plot_canvas_rectangle_draw 		(GtkPlotCanvas *canvas,
229 					 GtkPlotCanvasChild *child)
230 {
231   GtkPlotCanvasRectangle *rectangle = GTK_PLOT_CANVAS_RECTANGLE(child);
232   gint width = child->allocation.width;
233   gint height = child->allocation.height;
234   gdouble m = canvas->magnification;
235 
236   if(width == 0 && height == 0) return;
237 
238   if(rectangle->filled){
239      gtk_plot_pc_set_color(canvas->pc, &rectangle->bg);
240      gtk_plot_pc_draw_rectangle(canvas->pc, TRUE,
241                                 child->allocation.x, child->allocation.y,
242 				width, height);
243   }
244   if(rectangle->line.line_style != GTK_PLOT_LINE_NONE &&
245      rectangle->border != GTK_PLOT_BORDER_NONE){
246 
247       gtk_plot_canvas_set_line_attributes(canvas, rectangle->line);
248       gtk_plot_pc_draw_rectangle(canvas->pc, FALSE,
249                                  child->allocation.x, child->allocation.y,
250                                  width, height);
251       if(rectangle->border == GTK_PLOT_BORDER_SHADOW){
252         gtk_plot_pc_draw_rectangle(canvas->pc,
253                            TRUE,
254                            child->allocation.x + roundint(rectangle->shadow_width * m),
255                            child->allocation.y + height,
256                            width, roundint(rectangle->shadow_width * m));
257         gtk_plot_pc_draw_rectangle(canvas->pc,
258                            TRUE,
259                            child->allocation.x + width,
260                            child->allocation.y + roundint(rectangle->shadow_width * m),
261                            roundint(rectangle->shadow_width * m), height);            }
262   }
263 }
264 
265 static void
gtk_plot_canvas_rectangle_move(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x,gdouble y)266 gtk_plot_canvas_rectangle_move		(GtkPlotCanvas *canvas,
267 					 GtkPlotCanvasChild *child,
268 					 gdouble x, gdouble y)
269 {
270   return;
271 }
272 
273 static void
gtk_plot_canvas_rectangle_resize(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x1,gdouble y1,gdouble x2,gdouble y2)274 gtk_plot_canvas_rectangle_resize	(GtkPlotCanvas *canvas,
275 					 GtkPlotCanvasChild *child,
276 					 gdouble x1, gdouble y1,
277 					 gdouble x2, gdouble y2)
278 {
279   return;
280 }
281 
282 void
gtk_plot_canvas_rectangle_set_attributes(GtkPlotCanvasRectangle * rectangle,GtkPlotLineStyle style,gfloat width,const GdkColor * fg,const GdkColor * bg,GtkPlotBorderStyle border,gboolean fill)283 gtk_plot_canvas_rectangle_set_attributes(GtkPlotCanvasRectangle *rectangle,
284                                     	 GtkPlotLineStyle style,
285                                      	 gfloat width,
286                                          const GdkColor *fg,
287                                          const GdkColor *bg,
288                                          GtkPlotBorderStyle border,
289 					 gboolean fill)
290 {
291   if(fg) rectangle->line.color = *fg;
292   if(bg) rectangle->bg = *bg;
293   rectangle->line.line_width = width;
294   rectangle->line.line_style = style;
295   rectangle->border = border;
296   rectangle->filled = fill;
297 }
298 
299 
300