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 
21 #include <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <math.h>
25 #include <gtk/gtk.h>
26 #include "gtkplot.h"
27 #include "gtkplotcanvas.h"
28 #include "gtkplotcanvasline.h"
29 #include "gtkplotgdk.h"
30 #include "gtkplotps.h"
31 
32 /**
33  * SECTION: gtkplotcanvasline
34  * @short_description:
35  *
36  * FIXME:: need long description
37  */
38 
39 
40 #define DEFAULT_MARKER_SIZE 6
41 #define P(string) string
42 
43 enum{
44   ARG_0,
45   ARG_LINE,
46   ARG_X1,
47   ARG_Y1,
48   ARG_X2,
49   ARG_Y2,
50   ARG_POS,
51   ARG_ARROW_MASK,
52   ARG_ARROW_LENGTH,
53   ARG_ARROW_WIDTH,
54   ARG_ARROW_STYLE
55 };
56 
57 static void gtk_plot_canvas_line_init		(GtkPlotCanvasLine *line);
58 static void gtk_plot_canvas_line_class_init	(GtkPlotCanvasChildClass *klass);
59 static void gtk_plot_canvas_line_draw_selection (GtkPlotCanvas *canvas,
60 						 GtkPlotCanvasChild *child,
61 					 	 GtkAllocation area);
62 static void gtk_plot_canvas_line_draw 		(GtkPlotCanvas *canvas,
63 						 GtkPlotCanvasChild *child);
64 static void gtk_plot_canvas_line_move		(GtkPlotCanvas *canvas,
65 						 GtkPlotCanvasChild *child,
66 						 gdouble x, gdouble y);
67 static void gtk_plot_canvas_line_resize		(GtkPlotCanvas *canvas,
68 						 GtkPlotCanvasChild *child,
69 						 gdouble x1, gdouble y1,
70 						 gdouble x2, gdouble y2);
71 static GtkPlotCanvasPos gtk_plot_canvas_line_button_press
72 						(GtkPlotCanvas *canvas,
73 						 GtkPlotCanvasChild *child,
74 						 gint x, gint y);
75 static void gtk_plot_canvas_line_button_release (GtkPlotCanvas *canvas,
76                                                  GtkPlotCanvasChild *child);
77 static void gtk_plot_canvas_line_size_allocate  (GtkPlotCanvas *canvas,
78 						 GtkPlotCanvasChild *child);
79 static void gtk_plot_canvas_line_get_property(GObject      *object,
80                                                  guint            prop_id,
81                                                  GValue          *value,
82                                                  GParamSpec      *pspec);
83 static void gtk_plot_canvas_line_set_property(GObject      *object,
84                                                  guint            prop_id,
85                                                  const GValue          *value,
86                                                  GParamSpec      *pspec);
87 
88 
89 static GtkPlotCanvasChildClass *parent_class = NULL;
90 
91 GType
gtk_plot_canvas_line_get_type(void)92 gtk_plot_canvas_line_get_type (void)
93 {
94   static GType plot_canvas_line_type = 0;
95 
96   if (!plot_canvas_line_type)
97     {
98       plot_canvas_line_type = g_type_register_static_simple (
99 		gtk_plot_canvas_child_get_type(),
100 		"GtkPlotCanvasLine",
101 		sizeof (GtkPlotCanvasLineClass),
102 		(GClassInitFunc) gtk_plot_canvas_line_class_init,
103 		sizeof (GtkPlotCanvasLine),
104 		(GInstanceInitFunc) gtk_plot_canvas_line_init,
105 		0);
106     }
107   return plot_canvas_line_type;
108 }
109 
110 GtkPlotCanvasChild*
gtk_plot_canvas_line_new(GtkPlotLineStyle style,gfloat width,const GdkColor * color,GtkPlotCanvasArrow arrow_mask)111 gtk_plot_canvas_line_new (GtkPlotLineStyle style,
112                           gfloat width,
113                           const GdkColor *color,
114                           GtkPlotCanvasArrow arrow_mask)
115 {
116   GtkPlotCanvasLine *line;
117 
118   line = g_object_new (gtk_plot_canvas_line_get_type (), NULL);
119 
120   line->line.line_width = width;
121   if(color) line->line.color = *color;
122   line->arrow_mask = arrow_mask;
123 
124   return GTK_PLOT_CANVAS_CHILD (line);
125 }
126 
127 static void
gtk_plot_canvas_line_init(GtkPlotCanvasLine * line)128 gtk_plot_canvas_line_init (GtkPlotCanvasLine *line)
129 {
130   gdk_color_black(gdk_colormap_get_system(), &line->line.color);
131 
132   line->line.line_style = GTK_PLOT_LINE_SOLID;
133   line->line.line_width = 0;
134   line->arrow_length = 8;
135   line->arrow_width = 8;
136   line->arrow_style = GTK_PLOT_SYMBOL_FILLED;
137   line->pos = GTK_PLOT_CANVAS_OUT;
138   line->x1 = line->y1 = 0;
139   line->x2 = line->y2 = 0;
140 }
141 
142 static void
gtk_plot_canvas_line_class_init(GtkPlotCanvasChildClass * klass)143 gtk_plot_canvas_line_class_init (GtkPlotCanvasChildClass *klass)
144 {
145   GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
146 
147   parent_class = g_type_class_ref (gtk_plot_canvas_child_get_type ());
148 
149   klass->draw = gtk_plot_canvas_line_draw;
150   klass->draw_selection = gtk_plot_canvas_line_draw_selection;
151   klass->move = gtk_plot_canvas_line_move;
152   klass->move_resize = gtk_plot_canvas_line_resize;
153   klass->size_allocate = gtk_plot_canvas_line_size_allocate;
154   klass->button_press = gtk_plot_canvas_line_button_press;
155   klass->button_release = gtk_plot_canvas_line_button_release;
156 
157   gobject_class->get_property = gtk_plot_canvas_line_get_property;
158   gobject_class->set_property = gtk_plot_canvas_line_set_property;
159 
160 
161   /**
162    * GtkPlotCanvasLine:line:
163    *
164    *
165    **/
166   g_object_class_install_property (gobject_class,
167                            ARG_LINE,
168   g_param_spec_pointer ("line",
169                            P("Line Attributes"),
170                            P("Line Attributes"),
171                            G_PARAM_READABLE|G_PARAM_WRITABLE));
172 
173   /**
174    * GtkPlotCanvasLine:x1:
175    *
176    *
177    **/
178   g_object_class_install_property (gobject_class,
179                            ARG_X1,
180   g_param_spec_double ("x1",
181                            P("Origin X"),
182                            P("Coordinate X of the first point"),
183                            -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
184                            G_PARAM_READABLE|G_PARAM_WRITABLE));
185 
186   /**
187    * GtkPlotCanvasLine:y1:
188    *
189    *
190    **/
191   g_object_class_install_property (gobject_class,
192                            ARG_Y1,
193   g_param_spec_double ("y1",
194                            P("Origin Y"),
195                            P("Coordinate Y of the first point"),
196                            -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
197                            G_PARAM_READABLE|G_PARAM_WRITABLE));
198 
199   /**
200    * GtkPlotCanvasLine:x2:
201    *
202    *
203    **/
204   g_object_class_install_property (gobject_class,
205                            ARG_X2,
206   g_param_spec_double ("x2",
207                            P("End X"),
208                            P("Coordinate X of the second point"),
209                            -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
210                            G_PARAM_READABLE|G_PARAM_WRITABLE));
211 
212   /**
213    * GtkPlotCanvasLine:y2:
214    *
215    *
216    **/
217   g_object_class_install_property (gobject_class,
218                            ARG_Y2,
219   g_param_spec_double ("y2",
220                            P("End Y"),
221                            P("Coordinate Y of the second point"),
222                            -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
223                            G_PARAM_READABLE|G_PARAM_WRITABLE));
224 
225   /**
226    * GtkPlotCanvasLine:pos:
227    *
228    *
229    **/
230   g_object_class_install_property (gobject_class,
231                            ARG_POS,
232   g_param_spec_int ("pos",
233                            P(""),
234                            P(""),
235                            0,G_MAXINT,0,
236                            G_PARAM_READABLE|G_PARAM_WRITABLE));
237 
238   /**
239    * GtkPlotCanvasLine:arrow_mask:
240    *
241    *
242    **/
243   g_object_class_install_property (gobject_class,
244                            ARG_ARROW_MASK,
245   g_param_spec_int ("arrow_mask",
246                            P("Arrow Mask"),
247                            P("Arrow Mask"),
248                            0,G_MAXINT,0,
249                            G_PARAM_READABLE|G_PARAM_WRITABLE));
250 
251   /**
252    * GtkPlotCanvasLine:arrow_width:
253    *
254    *
255    **/
256   g_object_class_install_property (gobject_class,
257                            ARG_ARROW_WIDTH,
258   g_param_spec_int ("arrow_width",
259                            P("Arrow Width"),
260                            P("Arrow Width"),
261                            0,G_MAXINT,0,
262                            G_PARAM_READABLE|G_PARAM_WRITABLE));
263 
264   /**
265    * GtkPlotCanvasLine:arrow_length:
266    *
267    *
268    **/
269   g_object_class_install_property (gobject_class,
270                            ARG_ARROW_LENGTH,
271   g_param_spec_int ("arrow_length",
272                            P("Arrow Length"),
273                            P("Arrow Length"),
274                            0,G_MAXINT,0,
275                            G_PARAM_READABLE|G_PARAM_WRITABLE));
276 
277   /**
278    * GtkPlotCanvasLine:arrow_style:
279    *
280    *
281    **/
282   g_object_class_install_property (gobject_class,
283                            ARG_ARROW_STYLE,
284   g_param_spec_int ("arrow_style",
285                            P("Arrow Style"),
286                            P("Arrow Style"),
287                            0,G_MAXINT,0,
288                            G_PARAM_READABLE|G_PARAM_WRITABLE));
289 }
290 
291 static void
gtk_plot_canvas_line_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)292 gtk_plot_canvas_line_set_property (GObject      *object,
293                                     guint            prop_id,
294                                     const GValue          *value,
295                                     GParamSpec      *pspec)
296 {
297   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE (object);
298 
299   switch(prop_id){
300     case ARG_LINE:
301       line->line = *((GtkPlotLine *)g_value_get_pointer(value));
302       break;
303     case ARG_X1:
304       line->x1 = g_value_get_double(value);
305       break;
306     case ARG_Y1:
307       line->y1 = g_value_get_double(value);
308       break;
309     case ARG_X2:
310       line->x2 = g_value_get_double(value);
311       break;
312     case ARG_Y2:
313       line->y2 = g_value_get_double(value);
314       break;
315     case ARG_POS:
316       line->pos = g_value_get_int(value);
317       break;
318     case ARG_ARROW_MASK:
319       line->arrow_mask = g_value_get_int(value);
320       break;
321     case ARG_ARROW_LENGTH:
322       line->arrow_length = g_value_get_int(value);
323       break;
324     case ARG_ARROW_WIDTH:
325       line->arrow_width = g_value_get_int(value);
326       break;
327     case ARG_ARROW_STYLE:
328       line->arrow_style = g_value_get_int(value);
329       break;
330   }
331 }
332 
333 static void
gtk_plot_canvas_line_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)334 gtk_plot_canvas_line_get_property (GObject      *object,
335                                     guint            prop_id,
336                                     GValue          *value,
337                                     GParamSpec      *pspec)
338 {
339   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE (object);
340 
341   switch(prop_id){
342     case ARG_LINE:
343       g_value_set_pointer(value, &line->line);
344       break;
345     case ARG_X1:
346       g_value_set_double(value, line->x1);
347       break;
348     case ARG_Y1:
349       g_value_set_double(value, line->y1);
350       break;
351     case ARG_X2:
352       g_value_set_double(value, line->x2);
353       break;
354     case ARG_Y2:
355       g_value_set_double(value, line->y2);
356       break;
357     case ARG_POS:
358       g_value_set_int(value, line->pos);
359       break;
360     case ARG_ARROW_MASK:
361       g_value_set_int(value, line->arrow_mask);
362       break;
363     case ARG_ARROW_LENGTH:
364       g_value_set_int(value, line->arrow_length);
365       break;
366     case ARG_ARROW_WIDTH:
367       g_value_set_int(value, line->arrow_width);
368       break;
369     case ARG_ARROW_STYLE:
370       g_value_set_int(value, line->arrow_style);
371       break;
372   }
373 }
374 
375 static void
gtk_plot_canvas_line_draw(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)376 gtk_plot_canvas_line_draw 		(GtkPlotCanvas *canvas,
377 					 GtkPlotCanvasChild *child)
378 {
379   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE(child);
380   gdouble angle = 0;
381   gint width = child->allocation.width;
382   gint height = child->allocation.height;
383   gint rx1, rx2, ry1, ry2;
384   GtkPlotPoint arrow[3];
385   gdouble xm, ym;
386   gdouble m = canvas->magnification;
387 
388   gtk_plot_canvas_get_pixel(canvas, line->x1, line->y1, &rx1, &ry1);
389   gtk_plot_canvas_get_pixel(canvas, line->x2, line->y2, &rx2, &ry2);
390 
391   if(width == 0 && height == 0) return;
392 
393   if(width != 0)
394       angle = atan2((gdouble)(ry2 - ry1), (gdouble)(rx2 - rx1));
395   else
396       angle = asin((ry2 - ry1)/height);
397 
398   gtk_plot_canvas_set_line_attributes(canvas, line->line);
399   gtk_plot_pc_draw_line(canvas->pc, rx1, ry1, rx2, ry2);
400   gtk_plot_pc_set_lineattr(canvas->pc, line->line.line_width, 0, 0, 0);
401   if(line->arrow_mask & GTK_PLOT_CANVAS_ARROW_END){
402      arrow[1].x = rx2;
403      arrow[1].y = ry2;
404      xm = rx2 - cos(angle) * line->arrow_length * m;
405      ym = ry2 - sin(angle) * line->arrow_length * m;
406      arrow[0].x = xm - sin(angle)* line->arrow_width * m / 2.0;
407      arrow[0].y = ym + cos(angle)* line->arrow_width * m / 2.0;
408      arrow[2].x = xm + sin(angle)* line->arrow_width * m / 2.0;
409      arrow[2].y = ym - cos(angle)* line->arrow_width * m / 2.0;
410      switch(line->arrow_style){
411        case GTK_PLOT_SYMBOL_EMPTY:
412          gtk_plot_pc_draw_lines (canvas->pc, arrow, 3);
413          break;
414        case GTK_PLOT_SYMBOL_OPAQUE:
415          gtk_plot_pc_set_color(canvas->pc, &canvas->background);
416          gtk_plot_pc_draw_polygon (canvas->pc, TRUE, arrow, 3);
417          gtk_plot_pc_set_color(canvas->pc, &line->line.color);
418          gtk_plot_pc_draw_polygon (canvas->pc, FALSE, arrow, 3);
419          break;
420        case GTK_PLOT_SYMBOL_FILLED:
421          gtk_plot_pc_draw_polygon (canvas->pc, TRUE, arrow, 3);
422      }
423   }
424   if(line->arrow_mask & GTK_PLOT_CANVAS_ARROW_ORIGIN){
425      arrow[1].x = rx1;
426      arrow[1].y = ry1;
427      xm = rx1 + cos(angle) * line->arrow_length * m;
428      ym = ry1 + sin(angle) * line->arrow_length * m;
429      arrow[0].x = xm + sin(angle)* line->arrow_width * m / 2.0;
430      arrow[0].y = ym - cos(angle)* line->arrow_width * m / 2.0;
431      arrow[2].x = xm - sin(angle)* line->arrow_width * m / 2.0;
432      arrow[2].y = ym + cos(angle)* line->arrow_width * m / 2.0;
433      switch(line->arrow_style){
434        case GTK_PLOT_SYMBOL_EMPTY:
435          gtk_plot_pc_draw_lines (canvas->pc, arrow, 3);
436          break;
437        case GTK_PLOT_SYMBOL_OPAQUE:
438          gtk_plot_pc_set_color(canvas->pc, &canvas->background);
439          gtk_plot_pc_draw_polygon (canvas->pc, TRUE, arrow, 3);
440          gtk_plot_pc_set_color(canvas->pc, &line->line.color);
441          gtk_plot_pc_draw_polygon (canvas->pc, FALSE, arrow, 3);
442          break;
443        case GTK_PLOT_SYMBOL_FILLED:
444          gtk_plot_pc_draw_polygon (canvas->pc, TRUE, arrow, 3);
445      }
446   }
447 }
448 
449 static void
gtk_plot_canvas_line_draw_selection(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,GtkAllocation area)450 gtk_plot_canvas_line_draw_selection 	(GtkPlotCanvas *canvas,
451 					 GtkPlotCanvasChild *child,
452 					 GtkAllocation area)
453 {
454   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE(child);
455   GdkGC *xor_gc = NULL;
456   GdkGCValues values;
457   gint x1, y1;
458   gint x2, y2;
459   gint dx, dy;
460 
461   dx = canvas->pointer_x - canvas->drag_x;
462   dy = canvas->pointer_y - canvas->drag_y;
463 
464   gdk_gc_get_values(gtk_widget_get_style(GTK_WIDGET(canvas))->fg_gc[0], &values);
465   values.function = GDK_INVERT;
466   values.foreground = gtk_widget_get_style(GTK_WIDGET(canvas))->white;
467   values.subwindow_mode = GDK_INCLUDE_INFERIORS;
468   xor_gc = gdk_gc_new_with_values(gtk_widget_get_window(GTK_WIDGET(canvas)),
469                                   &values,
470                                   GDK_GC_FOREGROUND |
471                                   GDK_GC_FUNCTION |
472                                   GDK_GC_SUBWINDOW);
473 
474   gtk_plot_canvas_get_pixel(canvas, line->x1, line->y1, &x1, &y1);
475   gtk_plot_canvas_get_pixel(canvas, line->x2, line->y2, &x2, &y2);
476 
477   if(line->pos == GTK_PLOT_CANVAS_TOP_LEFT){
478     gdk_draw_rectangle(gtk_widget_get_window(GTK_WIDGET(canvas)),
479 			xor_gc, TRUE,
480                         x2 - DEFAULT_MARKER_SIZE / 2,
481                         y2 - DEFAULT_MARKER_SIZE / 2,
482                         DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
483 
484     gdk_draw_rectangle(gtk_widget_get_window(GTK_WIDGET(canvas)),
485 		       xor_gc, TRUE,
486                        x1 + dx - DEFAULT_MARKER_SIZE / 2,
487                        y1 + dy - DEFAULT_MARKER_SIZE / 2,
488                        DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
489 
490     gdk_gc_set_line_attributes(xor_gc, 1, 1, 0, 0);
491     gdk_draw_line(gtk_widget_get_window(GTK_WIDGET(canvas)),
492 			xor_gc, x2, y2, x1 + dx, y1 + dy);
493 
494   } else if(line->pos == GTK_PLOT_CANVAS_BOTTOM_RIGHT){
495     gdk_draw_rectangle(gtk_widget_get_window(GTK_WIDGET(canvas)),
496 		       xor_gc, TRUE,
497                        x1 - DEFAULT_MARKER_SIZE / 2,
498                        y1 - DEFAULT_MARKER_SIZE / 2,
499                        DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
500 
501     gdk_draw_rectangle(gtk_widget_get_window(GTK_WIDGET(canvas)),
502 		       xor_gc, TRUE,
503                        x2 + dx - DEFAULT_MARKER_SIZE / 2,
504                        y2 + dy - DEFAULT_MARKER_SIZE / 2,
505                        DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
506 
507     gdk_gc_set_line_attributes(xor_gc, 1, 1, 0, 0);
508     gdk_draw_line(gtk_widget_get_window(GTK_WIDGET(canvas)),
509 			xor_gc, x1, y1, x2 + dx, y2 + dy);
510 
511   } else {
512 
513     gdk_draw_rectangle(gtk_widget_get_window(GTK_WIDGET(canvas)),
514 		        xor_gc, TRUE,
515                        x1 + dx - DEFAULT_MARKER_SIZE / 2,
516                        y1 + dy - DEFAULT_MARKER_SIZE / 2,
517                        DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
518 
519     gdk_draw_rectangle(gtk_widget_get_window(GTK_WIDGET(canvas)),
520 		       xor_gc, TRUE,
521                        x2 + dx - DEFAULT_MARKER_SIZE / 2,
522                        y2 + dy - DEFAULT_MARKER_SIZE / 2,
523                        DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
524 
525     gdk_gc_set_line_attributes(xor_gc, 1, 1, 0, 0);
526     gdk_draw_line(gtk_widget_get_window(GTK_WIDGET(canvas)), xor_gc,
527                  x1 + dx, y1 + dy, x2 + dx, y2 + dy);
528   }
529 
530 
531   if(xor_gc) gdk_gc_unref(xor_gc);
532 }
533 
534 static GtkPlotCanvasPos
gtk_plot_canvas_line_button_press(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gint x,gint y)535 gtk_plot_canvas_line_button_press   (GtkPlotCanvas *canvas,
536 				     GtkPlotCanvasChild *child,
537 				     gint x, gint y)
538 {
539   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE(child);
540   gint x1, y1, x2, y2;
541 
542   gtk_plot_canvas_get_pixel(canvas, line->x1, line->y1, &x1, &y1);
543   gtk_plot_canvas_get_pixel(canvas, line->x2, line->y2, &x2, &y2);
544 
545   if(abs(x - x1) <= DEFAULT_MARKER_SIZE  / 2 && abs(y - y1) <= DEFAULT_MARKER_SIZE / 2) {
546     line->pos = GTK_PLOT_CANVAS_TOP_LEFT;
547     child->state = GTK_STATE_SELECTED;
548     return line->pos;
549   }
550   if(abs(x - x2) <= DEFAULT_MARKER_SIZE / 2 && abs(y - y2) <= DEFAULT_MARKER_SIZE / 2) {
551     line->pos = GTK_PLOT_CANVAS_BOTTOM_RIGHT;
552     child->state = GTK_STATE_SELECTED;
553     return line->pos;
554   }
555 
556   if(x < MAX(x1, x2) && x > MIN(x1, x2) && y < MAX(y1, y2) && y > MIN(y1, y2)){
557     gdouble dist;
558     gdouble vx, vy;
559 
560     vx = x2 - x1;
561     vy = y2 - y1;
562     dist = (x - x1) * vy - (y - y1) * vx;
563     dist /= sqrt(vx * vx + vy * vy);
564     if(fabs(dist) <= DEFAULT_MARKER_SIZE) {
565       line->pos = GTK_PLOT_CANVAS_IN;
566       child->state = GTK_STATE_SELECTED;
567       return line->pos;
568     }
569   }
570 
571   line->pos = GTK_PLOT_CANVAS_OUT;
572   child->state = GTK_STATE_NORMAL;
573   return GTK_PLOT_CANVAS_OUT;
574 }
575 
576 static void
gtk_plot_canvas_line_size_allocate(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)577 gtk_plot_canvas_line_size_allocate  (GtkPlotCanvas *canvas,
578 				     GtkPlotCanvasChild *child)
579 {
580   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE(child);
581   gint x1, x2, y1, y2;
582 
583   line->x1 = child->rx1;
584   line->y1 = child->ry1;
585   line->x2 = child->rx2;
586   line->y2 = child->ry2;
587 
588   gtk_plot_canvas_get_pixel(canvas, child->rx1, child->ry1, &x1, &y1);
589   gtk_plot_canvas_get_pixel(canvas, child->rx2, child->ry2, &x2, &y2);
590 
591   child->allocation.x = MIN(x1, x2);
592   child->allocation.y = MIN(y1, y2);
593   child->allocation.width = abs(x1 - x2);
594   child->allocation.height = abs(y1 - y2);
595 }
596 
597 static void
gtk_plot_canvas_line_move(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x,gdouble y)598 gtk_plot_canvas_line_move		(GtkPlotCanvas *canvas,
599 					 GtkPlotCanvasChild *child,
600 					 gdouble x, gdouble y)
601 {
602   return;
603 }
604 
605 static void
gtk_plot_canvas_line_resize(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x1,gdouble y1,gdouble x2,gdouble y2)606 gtk_plot_canvas_line_resize             (GtkPlotCanvas *canvas,
607                                          GtkPlotCanvasChild *child,
608                                          gdouble x1, gdouble y1,
609                                          gdouble x2, gdouble y2)
610 {
611   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE(child);
612 
613   line->x1 = x1;
614   line->y1 = y1;
615   line->x2 = x2;
616   line->y2 = y2;
617 
618   GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate(canvas, child);
619   gtk_plot_canvas_paint(canvas);
620   gtk_plot_canvas_refresh(canvas);
621 }
622 
623 static void
gtk_plot_canvas_line_button_release(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)624 gtk_plot_canvas_line_button_release     (GtkPlotCanvas *canvas,
625                                          GtkPlotCanvasChild *child)
626 {
627   GtkPlotCanvasLine *line = GTK_PLOT_CANVAS_LINE(child);
628   gdouble px, py, dx, dy;
629 
630   gtk_plot_canvas_get_position(canvas, canvas->pointer_x, canvas->pointer_y, &px, &py);
631   gtk_plot_canvas_get_position(canvas, canvas->drag_x, canvas->drag_y, &dx, &dy);
632 
633   if(line->pos == GTK_PLOT_CANVAS_TOP_LEFT){
634     line->x1 += (px - dx);
635     line->y1 += (py - dy);
636   } else if(line->pos == GTK_PLOT_CANVAS_BOTTOM_RIGHT) {
637     line->x2 += (px - dx);
638     line->y2 += (py - dy);
639   } else if(line->pos == GTK_PLOT_CANVAS_IN) {
640     line->x1 += (px - dx);
641     line->y1 += (py - dy);
642     line->x2 += (px - dx);
643     line->y2 += (py - dy);
644   }
645 
646   child->rx1 = line->x1;
647   child->ry1 = line->y1;
648   child->rx2 = line->x2;
649   child->ry2 = line->y2;
650 
651   GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate(canvas, child);
652   gtk_plot_canvas_paint(canvas);
653   gtk_plot_canvas_refresh(canvas);
654 }
655 
656 /**
657  * gtk_plot_canvas_line_set_attributes:
658  * @line: a #GtkPlotCanvasLine widget.
659  * @style:
660  * @width:
661  * @color:
662  *
663  *
664  */
665 void
gtk_plot_canvas_line_set_attributes(GtkPlotCanvasLine * line,GtkPlotLineStyle style,gfloat width,const GdkColor * color)666 gtk_plot_canvas_line_set_attributes(GtkPlotCanvasLine *line,
667                                     GtkPlotLineStyle style,
668                                     gfloat width,
669                                     const GdkColor *color)
670 {
671   if(color) line->line.color = *color;
672   line->line.line_width = width;
673   line->line.line_style = style;
674 }
675 
676 /**
677  * gtk_plot_canvas_line_set_arrow:
678  * @line: a #GtkPlotCanvasLine widget.
679  * @style:
680  * @width:
681  * @length:
682  * @mask:
683  *
684  *
685  */
686 void
gtk_plot_canvas_line_set_arrow(GtkPlotCanvasLine * line,GtkPlotSymbolStyle style,gfloat width,gfloat length,GtkPlotCanvasArrow mask)687 gtk_plot_canvas_line_set_arrow(GtkPlotCanvasLine *line,
688                                GtkPlotSymbolStyle style,
689                                gfloat width, gfloat length,
690                                GtkPlotCanvasArrow mask)
691 {
692   line->arrow_width = width;
693   line->arrow_length = length;
694   line->arrow_style = style;
695   line->arrow_mask = mask;
696 }
697 
698 
699