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 <gdk/gdkkeysyms.h>
26 #include "gtkextra-compat.h"
27 #include "gtkplotcairo.h"
28 #include "gtkplotcanvas.h"
29 #include "gtkplotgdk.h"
30 #include "gtkplotps.h"
31 #include "gtkextra-marshal.h"
32
33 /**
34 * SECTION: gtkplotcanvas
35 * @short_description:
36 *
37 * FIXME:: need long description.
38 */
39
40
41 #define P_(string) string
42
43 #define DEFAULT_WIDTH 100
44 #define DEFAULT_HEIGHT 150
45 #define DEFAULT_MARKER_SIZE 6
46 #define SHADOW_WIDTH 3
47 #define GRAPH_MASK (GDK_EXPOSURE_MASK | \
48 GDK_POINTER_MOTION_MASK | \
49 GDK_POINTER_MOTION_HINT_MASK | \
50 GDK_BUTTON_PRESS_MASK | \
51 GDK_BUTTON_RELEASE_MASK)
52
53 #if !GTK_CHECK_VERSION(2,22,0)
54 static GdkCursorType
gdk_cursor_get_cursor_type(GdkCursor * cursor)55 gdk_cursor_get_cursor_type (GdkCursor *cursor)
56 {
57 g_return_val_if_fail (cursor != NULL, GDK_BLANK_CURSOR);
58 return cursor->type;
59 }
60 #endif
61
62 enum {
63 ARG_CANVAS_0,
64 ARG_CANVAS_FLAGS,
65 ARG_CANVAS_WIDTH,
66 ARG_CANVAS_HEIGHT,
67 ARG_CANVAS_MAGNIFICATION,
68 ARG_CANVAS_SHOW_GRID,
69 ARG_CANVAS_GRID_STEP,
70 ARG_CANVAS_LINE_GRID,
71 ARG_CANVAS_COLOR_BG,
72 ARG_CANVAS_TRANSPARENT,
73 };
74
75 enum {
76 ARG_CHILD_0,
77 ARG_CHILD_RX1,
78 ARG_CHILD_RY1,
79 ARG_CHILD_RX2,
80 ARG_CHILD_RY2,
81 ARG_CHILD_ALLOCATION,
82 ARG_CHILD_MIN_WIDTH,
83 ARG_CHILD_MIN_HEIGHT,
84 ARG_CHILD_STATE,
85 ARG_CHILD_FLAGS,
86 ARG_CHILD_SELECTION,
87 ARG_CHILD_SELECTION_MODE,
88 };
89
90 static void gtk_plot_canvas_class_init (GtkPlotCanvasClass *klass);
91 static void gtk_plot_canvas_init (GtkPlotCanvas *plot_canvas);
92 static void gtk_plot_canvas_set_property (GObject *object,
93 guint prop_id,
94 const GValue *value,
95 GParamSpec *pspec);
96 static void gtk_plot_canvas_get_property (GObject *object,
97 guint prop_id,
98 GValue *value,
99 GParamSpec *pspec);
100 static void gtk_plot_canvas_child_class_init (GtkPlotCanvasChildClass *klass);
101 static void gtk_plot_canvas_child_init (GtkPlotCanvasChild *child);
102 static void gtk_plot_canvas_child_set_property (GObject *object,
103 guint prop_id,
104 const GValue *value,
105 GParamSpec *pspec);
106 static void gtk_plot_canvas_child_get_property (GObject *object,
107 guint prop_id,
108 GValue *value,
109 GParamSpec *pspec);
110 static void gtk_plot_canvas_destroy (GtkObject *object);
111 static void gtk_plot_canvas_map (GtkWidget *widget);
112 static void gtk_plot_canvas_size_request (GtkWidget *widget,
113 GtkRequisition *requisition);
114 static gint gtk_plot_canvas_motion (GtkWidget *widget,
115 GdkEventMotion *event);
116 static gint gtk_plot_canvas_button_press (GtkWidget *widget,
117 GdkEventButton *event);
118 static gint gtk_plot_canvas_key_press (GtkWidget *widget,
119 GdkEventKey *event);
120 static gint gtk_plot_canvas_button_release (GtkWidget *widget,
121 GdkEventButton *event);
122 static gint gtk_plot_canvas_focus_in (GtkWidget *widget,
123 GdkEventFocus *event);
124 static gint gtk_plot_canvas_focus_out (GtkWidget *widget,
125 GdkEventFocus *event);
126 static void gtk_plot_canvas_child_size_allocate (GtkPlotCanvas *canvas,
127 GtkPlotCanvasChild *child);
128 static GtkPlotCanvasPos gtk_plot_canvas_child_button_press
129 (GtkPlotCanvas *canvas,
130 GtkPlotCanvasChild *child,
131 gint x, gint y);
132 static void gtk_plot_canvas_child_button_release(GtkPlotCanvas *canvas,
133 GtkPlotCanvasChild *child);
134 /* Drawing functions */
135 static gint gtk_plot_canvas_expose (GtkWidget *widget,
136 GdkEventExpose *event);
137 static void gtk_plot_canvas_create_pixmap (GtkWidget *widget,
138 gint width, gint height);
139 static void gtk_plot_canvas_child_draw (GtkPlotCanvas *canvas,
140 GtkPlotCanvasChild *child);
141 static void gtk_plot_canvas_child_draw_selection(GtkPlotCanvas *canvas,
142 GtkPlotCanvasChild *child,
143 GtkAllocation area);
144 static void draw_selection (GtkPlotCanvas *canvas,
145 GtkPlotCanvasChild *child,
146 GtkAllocation area);
147 static void draw_marker (GtkPlotCanvas *canvas,
148 GdkGC *gc, gint x, gint y);
149
150 static void gtk_plot_canvas_draw_grid (GtkPlotCanvas *canvas);
151 static void gtk_plot_canvas_child_draw (GtkPlotCanvas *canvas,
152 GtkPlotCanvasChild *child);
153 /* Auxiliary functions */
154 GtkPlotCanvasPos possible_selection (GtkAllocation area,
155 gint x, gint y);
156 extern gint roundint (gdouble x);
157
158
159 /* Signals */
160
161 extern void
162 _gtkextra_signal_emit(GtkObject *object, guint signal_id, ...);
163
164 enum {
165 SELECT_ITEM,
166 MOVE_ITEM,
167 RESIZE_ITEM,
168 DELETE_ITEM,
169 ADD_ITEM,
170 SELECT_REGION,
171 CHANGED,
172 LAST_SIGNAL
173 };
174
175 typedef gboolean (*GtkPlotCanvasSignal1) (GtkObject *object,
176 gpointer arg1,
177 gdouble arg2,
178 gdouble arg3,
179 gpointer user_data);
180
181 typedef gboolean (*GtkPlotCanvasSignal2) (GtkObject *object,
182 gpointer arg1,
183 gpointer arg2,
184 gpointer user_data);
185
186 typedef gboolean (*GtkPlotCanvasSignal3) (GtkObject *object,
187 gdouble arg1,
188 gdouble arg2,
189 gdouble arg3,
190 gdouble arg4,
191 gpointer user_data);
192
193 static GtkFixedClass *parent_class = NULL;
194 static guint canvas_signals[LAST_SIGNAL] = {0};
195
196 GType
gtk_plot_canvas_get_type(void)197 gtk_plot_canvas_get_type (void)
198 {
199 static GType plot_canvas_type = 0;
200
201 if (!plot_canvas_type)
202 {
203 plot_canvas_type = g_type_register_static_simple (
204 gtk_fixed_get_type(),
205 "GtkPlotCanvas",
206 sizeof (GtkPlotCanvasClass),
207 (GClassInitFunc) gtk_plot_canvas_class_init,
208 sizeof (GtkPlotCanvas),
209 (GInstanceInitFunc) gtk_plot_canvas_init,
210 0);
211 }
212 return plot_canvas_type;
213 }
214
215 GType
gtk_plot_canvas_child_get_type(void)216 gtk_plot_canvas_child_get_type (void)
217 {
218 static GType plot_canvas_child_type = 0;
219
220 if (!plot_canvas_child_type)
221 {
222
223 plot_canvas_child_type = g_type_register_static_simple (
224 gtk_object_get_type(),
225 "GtkPlotCanvasChild",
226 sizeof(GtkPlotCanvasChildClass),
227 (GClassInitFunc) gtk_plot_canvas_child_class_init,
228 sizeof(GtkPlotCanvasChild),
229 (GInstanceInitFunc) gtk_plot_canvas_child_init,
230 0);
231 }
232 return plot_canvas_child_type;
233 }
234
235 static void
gtk_plot_canvas_child_class_init(GtkPlotCanvasChildClass * klass)236 gtk_plot_canvas_child_class_init (GtkPlotCanvasChildClass *klass)
237 {
238 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
239
240 klass->size_allocate = gtk_plot_canvas_child_size_allocate;
241 klass->draw = NULL;
242 klass->unselect = NULL;
243 klass->move = NULL;
244 klass->move_resize = NULL;
245 klass->draw_selection = draw_selection;
246 klass->button_press = gtk_plot_canvas_child_button_press;
247 klass->button_release = gtk_plot_canvas_child_button_release;
248 klass->set_magnification = NULL;
249
250 gobject_class->get_property = gtk_plot_canvas_child_get_property;
251 gobject_class->set_property = gtk_plot_canvas_child_set_property;
252
253 /**
254 * GtkPlotCanvasChild:rx1:
255 *
256 *
257 **/
258 g_object_class_install_property (gobject_class,
259 ARG_CHILD_RX1,
260 g_param_spec_double ("rx1",
261 P_(""),
262 P_(""),
263 -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
264 G_PARAM_READABLE|G_PARAM_WRITABLE));
265
266 /**
267 * GtkPlotCanvasChild:ry1:
268 *
269 *
270 **/
271 g_object_class_install_property (gobject_class,
272 ARG_CHILD_RY1,
273 g_param_spec_double ("ry1",
274 P_(""),
275 P_(""),
276 -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
277 G_PARAM_READABLE|G_PARAM_WRITABLE));
278
279 /**
280 * GtkPlotCanvasChild:rx2:
281 *
282 *
283 **/
284 g_object_class_install_property (gobject_class,
285 ARG_CHILD_RX2,
286 g_param_spec_double ("rx2",
287 P_(""),
288 P_(""),
289 -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
290 G_PARAM_READABLE|G_PARAM_WRITABLE));
291
292 /**
293 * GtkPlotCanvasChild:ry2:
294 *
295 *
296 **/
297 g_object_class_install_property (gobject_class,
298 ARG_CHILD_RY2,
299 g_param_spec_double ("ry2",
300 P_(""),
301 P_(""),
302 -G_MAXDOUBLE,G_MAXDOUBLE,0.0,
303 G_PARAM_READABLE|G_PARAM_WRITABLE));
304
305 /**
306 * GtkPlotCanvasChild:allocation:
307 *
308 *
309 **/
310 g_object_class_install_property (gobject_class,
311 ARG_CHILD_ALLOCATION,
312 g_param_spec_pointer ("allocation",
313 P_(""),
314 P_(""),
315 G_PARAM_READABLE|G_PARAM_WRITABLE));
316
317 /**
318 * GtkPlotCanvasChild:min_width:
319 *
320 *
321 **/
322 g_object_class_install_property (gobject_class,
323 ARG_CHILD_MIN_WIDTH,
324 g_param_spec_int ("min_width",
325 P_(""),
326 P_(""),
327 -1,G_MAXINT,0,
328 G_PARAM_READABLE|G_PARAM_WRITABLE));
329
330 /**
331 * GtkPlotCanvasChild:min_height:
332 *
333 *
334 **/
335 g_object_class_install_property (gobject_class,
336 ARG_CHILD_MIN_HEIGHT,
337 g_param_spec_int ("min_height",
338 P_(""),
339 P_(""),
340 -1,G_MAXINT,0,
341 G_PARAM_READABLE|G_PARAM_WRITABLE));
342
343 /**
344 * GtkPlotCanvasChild:state:
345 *
346 *
347 **/
348 g_object_class_install_property (gobject_class,
349 ARG_CHILD_STATE,
350 g_param_spec_int ("state",
351 P_(""),
352 P_(""),
353 0,G_MAXINT,0,
354 G_PARAM_READABLE|G_PARAM_WRITABLE));
355
356 /**
357 * GtkPlotCanvasChild:flags:
358 *
359 *
360 **/
361 g_object_class_install_property (gobject_class,
362 ARG_CHILD_FLAGS,
363 g_param_spec_int ("flags",
364 P_(""),
365 P_(""),
366 0,G_MAXINT,0,
367 G_PARAM_READABLE|G_PARAM_WRITABLE));
368
369 /**
370 * GtkPlotCanvasChild:selection:
371 *
372 *
373 **/
374 g_object_class_install_property (gobject_class,
375 ARG_CHILD_SELECTION,
376 g_param_spec_int ("selection",
377 P_(""),
378 P_(""),
379 0,G_MAXINT,0,
380 G_PARAM_READABLE|G_PARAM_WRITABLE));
381
382 /**
383 * GtkPlotCanvasChild:selection_mode:
384 *
385 *
386 **/
387 g_object_class_install_property (gobject_class,
388 ARG_CHILD_SELECTION_MODE,
389 g_param_spec_int ("selection_mode",
390 P_(""),
391 P_(""),
392 0,G_MAXINT,0,
393 G_PARAM_READABLE|G_PARAM_WRITABLE));
394
395 }
396
397 static void
gtk_plot_canvas_child_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)398 gtk_plot_canvas_child_get_property (GObject *object,
399 guint prop_id,
400 GValue *value,
401 GParamSpec *pspec)
402 {
403 GtkPlotCanvasChild *child = GTK_PLOT_CANVAS_CHILD(object);
404
405 switch(prop_id){
406 case ARG_CHILD_RX1:
407 g_value_set_double(value, child->rx1);
408 break;
409 case ARG_CHILD_RY1:
410 g_value_set_double(value, child->ry1);
411 break;
412 case ARG_CHILD_RX2:
413 g_value_set_double(value, child->rx2);
414 break;
415 case ARG_CHILD_RY2:
416 g_value_set_double(value, child->ry2);
417 break;
418 case ARG_CHILD_ALLOCATION:
419 g_value_set_pointer(value, &child->allocation);
420 break;
421 case ARG_CHILD_MIN_WIDTH:
422 g_value_set_int(value, child->min_width);
423 break;
424 case ARG_CHILD_MIN_HEIGHT:
425 g_value_set_int(value, child->min_height);
426 break;
427 case ARG_CHILD_STATE:
428 g_value_set_int(value, child->state);
429 break;
430 case ARG_CHILD_FLAGS:
431 g_value_set_int(value, child->flags);
432 break;
433 case ARG_CHILD_SELECTION:
434 g_value_set_int(value, child->selection);
435 break;
436 case ARG_CHILD_SELECTION_MODE:
437 g_value_set_int(value, child->mode);
438 break;
439 }
440 }
441
442 static void
gtk_plot_canvas_child_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)443 gtk_plot_canvas_child_set_property (GObject *object,
444 guint prop_id,
445 const GValue *value,
446 GParamSpec *pspec)
447 {
448 GtkPlotCanvasChild *child = GTK_PLOT_CANVAS_CHILD(object);
449
450 switch(prop_id){
451 case ARG_CHILD_RX1:
452 child->rx1 = g_value_get_double(value);
453 break;
454 case ARG_CHILD_RY1:
455 child->ry1 = g_value_get_double(value);
456 break;
457 case ARG_CHILD_RX2:
458 child->rx2 = g_value_get_double(value);
459 break;
460 case ARG_CHILD_RY2:
461 child->ry2 = g_value_get_double(value);
462 break;
463 case ARG_CHILD_ALLOCATION:
464 child->allocation = *((GtkAllocation *)g_value_get_pointer(value));
465 break;
466 case ARG_CHILD_MIN_WIDTH:
467 child->min_width = g_value_get_int(value);
468 break;
469 case ARG_CHILD_MIN_HEIGHT:
470 child->min_height = g_value_get_int(value);
471 break;
472 case ARG_CHILD_STATE:
473 child->state = g_value_get_int(value);
474 break;
475 case ARG_CHILD_FLAGS:
476 child->flags = g_value_get_int(value);
477 break;
478 case ARG_CHILD_SELECTION:
479 child->selection = g_value_get_int(value);
480 break;
481 case ARG_CHILD_SELECTION_MODE:
482 child->mode = g_value_get_int(value);
483 break;
484 }
485 }
486
487 static void
gtk_plot_canvas_child_init(GtkPlotCanvasChild * child)488 gtk_plot_canvas_child_init(GtkPlotCanvasChild *child)
489 {
490 child->flags = GTK_PLOT_CANVAS_CHILD_CAN_MOVE |
491 GTK_PLOT_CANVAS_CHILD_CAN_RESIZE;
492
493 child->min_width = -1;
494 child->min_height = -1;
495
496 child->selection = GTK_PLOT_CANVAS_SELECT_MARKERS;
497 child->mode = GTK_PLOT_CANVAS_SELECT_CLICK_2;
498 child->parent = NULL;
499 }
500
501 static void
gtk_plot_canvas_class_init(GtkPlotCanvasClass * klass)502 gtk_plot_canvas_class_init (GtkPlotCanvasClass *klass)
503 {
504 GtkObjectClass *object_class;
505 GtkWidgetClass *widget_class;
506 GtkContainerClass *container_class;
507 GObjectClass *gobject_class = G_OBJECT_CLASS(klass);
508
509 parent_class = g_type_class_ref (gtk_fixed_get_type ());
510
511 object_class = (GtkObjectClass *) klass;
512 widget_class = (GtkWidgetClass *) klass;
513 container_class = (GtkContainerClass *) klass;
514
515
516 /**
517 * GtkPlotCanvas::select_item:
518 * @canvas:
519 * @event:
520 * @item:
521 *
522 *
523 *
524 * Return value:
525 */
526 canvas_signals[SELECT_ITEM] =
527 g_signal_new ("select_item",
528 G_TYPE_FROM_CLASS(object_class),
529 G_SIGNAL_RUN_LAST,
530 G_STRUCT_OFFSET (GtkPlotCanvasClass, select_item),
531 NULL, NULL,
532 gtkextra_BOOLEAN__BOXED_BOXED,
533 G_TYPE_BOOLEAN, 2, GDK_TYPE_EVENT,
534 G_TYPE_PLOT_CANVAS_CHILD);
535
536 /**
537 * GtkPlotCanvas::move_item:
538 * @canvas:
539 * @item:
540 * @new_x:
541 * @new_y
542 *
543 *
544 *
545 * Return value:
546 */
547 canvas_signals[MOVE_ITEM] =
548 g_signal_new ("move_item",
549 G_TYPE_FROM_CLASS(object_class),
550 G_SIGNAL_RUN_LAST,
551 G_STRUCT_OFFSET (GtkPlotCanvasClass, move_item),
552 NULL, NULL,
553 gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE,
554 G_TYPE_BOOLEAN, 3, G_TYPE_PLOT_CANVAS_CHILD,
555 G_TYPE_DOUBLE,
556 G_TYPE_DOUBLE);
557
558 /**
559 * GtkPlotCanvas::resize_item:
560 * @canvas:
561 * @item:
562 * @new_width:
563 * @new_height:
564 *
565 *
566 *
567 * Return value:
568 */
569 canvas_signals[RESIZE_ITEM] =
570 g_signal_new ("resize_item",
571 G_TYPE_FROM_CLASS(object_class),
572 G_SIGNAL_RUN_LAST,
573 G_STRUCT_OFFSET (GtkPlotCanvasClass, resize_item),
574 NULL, NULL,
575 gtkextra_BOOLEAN__BOXED_DOUBLE_DOUBLE,
576 G_TYPE_BOOLEAN, 3, G_TYPE_PLOT_CANVAS_CHILD,
577 G_TYPE_DOUBLE,
578 G_TYPE_DOUBLE);
579
580 /**
581 * GtkPlotCanvas::add_item:
582 * @canvas:
583 * @item:
584 *
585 *
586 */
587 canvas_signals[ADD_ITEM] =
588 g_signal_new ("add_item",
589 G_TYPE_FROM_CLASS(object_class),
590 G_SIGNAL_RUN_LAST,
591 G_STRUCT_OFFSET (GtkPlotCanvasClass, add_item),
592 NULL, NULL,
593 gtkextra_VOID__POINTER,
594 G_TYPE_NONE, 1,
595 G_TYPE_PLOT_CANVAS_CHILD);
596
597 /**
598 * GtkPlotCanvas::delete_item:
599 * @canvas:
600 * @item:
601 *
602 *
603 *
604 * Return value:
605 */
606 canvas_signals[DELETE_ITEM] =
607 g_signal_new ("delete_item",
608 G_TYPE_FROM_CLASS(object_class),
609 G_SIGNAL_RUN_LAST,
610 G_STRUCT_OFFSET (GtkPlotCanvasClass, delete_item),
611 NULL, NULL,
612 gtkextra_BOOL__POINTER,
613 G_TYPE_BOOLEAN, 1,
614 G_TYPE_PLOT_CANVAS_CHILD);
615
616 /**
617 * GtkPlotCanvas::select_region:
618 * @canvas:
619 * @xmin:
620 * @ymin:
621 * @xmax:
622 * @ymax:
623 *
624 *
625 */
626 canvas_signals[SELECT_REGION] =
627 g_signal_new ("select_region",
628 G_TYPE_FROM_CLASS(object_class),
629 G_SIGNAL_RUN_LAST,
630 G_STRUCT_OFFSET (GtkPlotCanvasClass, select_region),
631 NULL, NULL,
632 gtkextra_VOID__DOUBLE_DOUBLE_DOUBLE_DOUBLE,
633 G_TYPE_NONE, 4,
634 G_TYPE_DOUBLE, G_TYPE_DOUBLE,
635 G_TYPE_DOUBLE, G_TYPE_DOUBLE);
636
637 /**
638 * GtkPlotCanvas::changed:
639 * @canvas:
640 *
641 *
642 */
643 canvas_signals[CHANGED] =
644 g_signal_new("changed",
645 G_TYPE_FROM_CLASS(object_class),
646 G_SIGNAL_RUN_LAST,
647 G_STRUCT_OFFSET (GtkPlotCanvasClass, changed),
648 NULL, NULL,
649 gtkextra_VOID__VOID,
650 G_TYPE_NONE, 0);
651
652 object_class->destroy = gtk_plot_canvas_destroy;
653
654 gobject_class->get_property = gtk_plot_canvas_get_property;
655 gobject_class->set_property = gtk_plot_canvas_set_property;
656
657 widget_class->map = gtk_plot_canvas_map;
658 widget_class->expose_event = gtk_plot_canvas_expose;
659 widget_class->size_request = gtk_plot_canvas_size_request;
660 widget_class->focus_in_event = gtk_plot_canvas_focus_in;
661 widget_class->focus_out_event = gtk_plot_canvas_focus_out;
662 widget_class->motion_notify_event = gtk_plot_canvas_motion;
663 widget_class->button_press_event = gtk_plot_canvas_button_press;
664 widget_class->button_release_event = gtk_plot_canvas_button_release;
665 widget_class->key_press_event = gtk_plot_canvas_key_press;
666
667 klass->move_item = NULL;
668 klass->resize_item = NULL;
669 klass->select_item = NULL;
670 klass->delete_item = NULL;
671 klass->select_region = NULL;
672
673 GParamSpec *pspec;
674
675 /**
676 * GtkPlotCanvas:flags:
677 *
678 * PlotCanvas flags control selection and DND,
679 * see #GtkPlotCanvasFlags.
680 **/
681 pspec = g_param_spec_int ("flags", P_("Flags"),
682 P_("Canvas flags"),
683 0,G_MAXINT,0,
684 G_PARAM_READWRITE);
685 g_object_class_install_property (gobject_class, ARG_CANVAS_FLAGS, pspec);
686
687 /**
688 * GtkPlotCanvas:magnification:
689 *
690 * PlotCanvas magnification factor
691 **/
692 pspec = g_param_spec_double ("magnification", P_("Magnification"),
693 P_("Canvas magnification"),
694 0,G_MAXDOUBLE,1.0,
695 G_PARAM_READWRITE);
696 g_object_class_install_property (gobject_class, ARG_CANVAS_MAGNIFICATION, pspec
697 );
698
699 /**
700 * GtkPlotCanvas:width:
701 *
702 * PlotCanvas width in pixels.
703 **/
704 pspec = g_param_spec_int ("width", P_("Width"),
705 P_("Canvas width"),
706 0,G_MAXINT,1,
707 G_PARAM_READWRITE);
708 g_object_class_install_property (gobject_class, ARG_CANVAS_WIDTH, pspec);
709
710 /**
711 * GtkPlotCanvas:height:
712 *
713 * PlotCanvas height in pixels.
714 **/
715 pspec = g_param_spec_int ("height", P_("Height"),
716 P_("Canvas height"),
717 0,G_MAXINT,1,
718 G_PARAM_READWRITE);
719 g_object_class_install_property (gobject_class, ARG_CANVAS_HEIGHT, pspec);
720
721 /**
722 * GtkPlotCanvas:show_grid:
723 *
724 * Show grid lines.
725 **/
726 pspec = g_param_spec_boolean ("show_grid", P_("Show grid"),
727 P_("Show grid"),
728 FALSE,
729 G_PARAM_READWRITE);
730 g_object_class_install_property (gobject_class, ARG_CANVAS_SHOW_GRID, pspec);
731
732 /**
733 * GtkPlotCanvas:grid_step:
734 *
735 * Distance between grid lines.
736 **/
737 pspec = g_param_spec_double ("grid_step", P_("Grid step"),
738 P_("Distance between grid lines"),
739 0,G_MAXDOUBLE,0.0,
740 G_PARAM_READWRITE);
741 g_object_class_install_property (gobject_class, ARG_CANVAS_GRID_STEP, pspec);
742
743 /**
744 * GtkPlotCanvas:line_grid:
745 *
746 * Line grid pattern.
747 **/
748 pspec = g_param_spec_pointer ("line_grid", P_("Line Grid"),
749 P_("Canvas line grid"),
750 G_PARAM_READWRITE);
751 g_object_class_install_property (gobject_class, ARG_CANVAS_LINE_GRID, pspec);
752
753 /**
754 * GtkPlotCanvas:color_bg:
755 *
756 * Background color.
757 **/
758 pspec = g_param_spec_pointer ("color_bg", P_("Background"),
759 P_("Background color"),
760 G_PARAM_READWRITE);
761 g_object_class_install_property (gobject_class, ARG_CANVAS_COLOR_BG, pspec);
762
763 /**
764 * GtkPlotCanvas:transparent:
765 *
766 * Canvas transparency
767 **/
768 pspec = g_param_spec_boolean ("transparent", P_("Transparent"),
769 P_("Canvas transparency"),
770 TRUE,
771 G_PARAM_READWRITE);
772 g_object_class_install_property (gobject_class, ARG_CANVAS_TRANSPARENT, pspec);
773 }
774
775 static void
gtk_plot_canvas_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)776 gtk_plot_canvas_get_property (GObject *object,
777 guint prop_id,
778 GValue *value,
779 GParamSpec *pspec)
780 {
781 GtkPlotCanvas *canvas = GTK_PLOT_CANVAS(object);
782
783 switch(prop_id){
784 case ARG_CANVAS_FLAGS:
785 g_value_set_int(value, canvas->flags);
786 break;
787 case ARG_CANVAS_WIDTH:
788 g_value_set_int(value, canvas->width);
789 break;
790 case ARG_CANVAS_HEIGHT:
791 g_value_set_int(value, canvas->height);
792 break;
793 case ARG_CANVAS_MAGNIFICATION:
794 g_value_set_double(value, canvas->magnification);
795 break;
796 case ARG_CANVAS_SHOW_GRID:
797 g_value_set_boolean(value, canvas->show_grid);
798 break;
799 case ARG_CANVAS_GRID_STEP:
800 g_value_set_double(value, canvas->grid_step);
801 break;
802 case ARG_CANVAS_LINE_GRID:
803 g_value_set_pointer(value, &canvas->grid);
804 break;
805 case ARG_CANVAS_COLOR_BG:
806 g_value_set_pointer(value, &canvas->background);
807 break;
808 case ARG_CANVAS_TRANSPARENT:
809 g_value_set_boolean(value, canvas->transparent);
810 break;
811 }
812 }
813
814 static void
gtk_plot_canvas_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)815 gtk_plot_canvas_set_property (GObject *object,
816 guint prop_id,
817 const GValue *value,
818 GParamSpec *pspec)
819 {
820 GtkPlotCanvas *canvas;
821
822 canvas = GTK_PLOT_CANVAS (object);
823
824 switch(prop_id){
825 case ARG_CANVAS_FLAGS:
826 canvas->flags = g_value_get_int(value);
827 break;
828 case ARG_CANVAS_WIDTH:
829 canvas->width = g_value_get_int(value);
830 break;
831 case ARG_CANVAS_HEIGHT:
832 canvas->height = g_value_get_int(value);
833 break;
834 case ARG_CANVAS_MAGNIFICATION:
835 canvas->magnification = g_value_get_double(value);
836 break;
837 case ARG_CANVAS_SHOW_GRID:
838 canvas->show_grid = g_value_get_boolean(value);
839 break;
840 case ARG_CANVAS_GRID_STEP:
841 canvas->grid_step = g_value_get_double(value);
842 break;
843 case ARG_CANVAS_LINE_GRID:
844 canvas->grid = *((GtkPlotLine *)g_value_get_pointer(value));
845 break;
846 case ARG_CANVAS_COLOR_BG:
847 canvas->background = *((GdkColor *)g_value_get_pointer(value));
848 break;
849 case ARG_CANVAS_TRANSPARENT:
850 canvas->transparent = g_value_get_boolean(value);
851 break;
852 }
853 }
854
855 static void
gtk_plot_canvas_init(GtkPlotCanvas * plot_canvas)856 gtk_plot_canvas_init (GtkPlotCanvas *plot_canvas)
857 {
858 GtkWidget *widget;
859 GdkColor color;
860
861 widget = GTK_WIDGET(plot_canvas);
862
863 gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE);
864
865 gdk_color_black(gtk_widget_get_colormap(widget),
866 >k_widget_get_style(widget)->black);
867 gdk_color_white(gtk_widget_get_colormap(widget),
868 >k_widget_get_style(widget)->white);
869
870 gtk_widget_set_events (widget, gtk_widget_get_events(widget)|
871 GRAPH_MASK);
872
873 plot_canvas->freeze_count = 0;
874 plot_canvas->cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW);
875
876 plot_canvas->background = gtk_widget_get_style(widget)->white;
877 plot_canvas->transparent = TRUE;
878
879 plot_canvas->flags = 0;
880 plot_canvas->state = GTK_STATE_NORMAL;
881 plot_canvas->action = GTK_PLOT_CANVAS_ACTION_INACTIVE;
882 plot_canvas->magnification = 1.;
883
884 plot_canvas->show_grid = FALSE;
885 plot_canvas->grid_step = 20.;
886 plot_canvas->grid.line_style = GTK_PLOT_LINE_SOLID;
887 plot_canvas->grid.line_width = 0;
888
889 gdk_color_parse("grey90", &color);
890 gdk_color_alloc(gdk_colormap_get_system(), &color);
891 plot_canvas->grid.color = color;
892
893 plot_canvas->drag_x = plot_canvas->drag_y = 0;
894 plot_canvas->pointer_x = plot_canvas->pointer_y = 0;
895
896 plot_canvas->childs = NULL;
897
898 plot_canvas->width = DEFAULT_WIDTH;
899 plot_canvas->height = DEFAULT_HEIGHT;
900 plot_canvas->pixmap_width = DEFAULT_WIDTH;
901 plot_canvas->pixmap_height = DEFAULT_HEIGHT;
902
903 gtk_psfont_init();
904
905 plot_canvas->pc = NULL;
906 gtk_plot_canvas_set_pc(plot_canvas, NULL);
907
908 plot_canvas->pixmap = NULL;
909 }
910
gtk_plot_canvas_flags(GtkPlotCanvas * canvas)911 GtkPlotCanvasFlags gtk_plot_canvas_flags(GtkPlotCanvas *canvas)
912 {
913 g_return_val_if_fail(canvas != NULL, 0);
914 return(canvas->flags);
915 }
916
gtk_plot_canvas_set_flags(GtkPlotCanvas * canvas,GtkPlotCanvasFlags flags)917 void gtk_plot_canvas_set_flags(GtkPlotCanvas *canvas, GtkPlotCanvasFlags flags)
918 {
919 g_return_if_fail(canvas != NULL);
920 canvas->flags |= flags;
921 }
922
gtk_plot_canvas_unset_flags(GtkPlotCanvas * canvas,GtkPlotCanvasFlags flags)923 void gtk_plot_canvas_unset_flags(GtkPlotCanvas *canvas, GtkPlotCanvasFlags flags)
924 {
925 g_return_if_fail(canvas != NULL);
926 canvas->flags &= ~flags;
927 }
928
929
930 void
gtk_plot_canvas_set_pc(GtkPlotCanvas * canvas,GtkPlotPC * pc)931 gtk_plot_canvas_set_pc(GtkPlotCanvas *canvas, GtkPlotPC *pc)
932 {
933 if(canvas->pc)
934 g_object_unref(GTK_OBJECT(canvas->pc));
935
936 if(!pc){
937 canvas->pc = (GtkPlotPC *)gtk_plot_cairo_new(NULL);
938 g_object_ref(GTK_OBJECT(canvas->pc));
939 gtk_object_sink(GTK_OBJECT(canvas->pc));
940 } else {
941 canvas->pc = pc;
942 g_object_ref(GTK_OBJECT(pc));
943 gtk_object_sink(GTK_OBJECT(pc));
944 }
945
946 if(canvas->pc && GTK_IS_PLOT_GDK(canvas->pc)){
947 GTK_PLOT_GDK(canvas->pc)->drawable = canvas->pixmap;
948 }
949 gtk_plot_pc_set_viewport(canvas->pc, canvas->pixmap_width, canvas->pixmap_height);
950 }
951
952 /**
953 * gtk_plot_canvas_new:
954 * @width:
955 * @height:
956 * @magnification:
957 *
958 *
959 *
960 * Return value:
961 */
962 GtkWidget*
gtk_plot_canvas_new(gint width,gint height,gdouble magnification)963 gtk_plot_canvas_new (gint width, gint height, gdouble magnification)
964 {
965 GtkPlotCanvas *plot_canvas;
966
967 plot_canvas = g_object_new (gtk_plot_canvas_get_type (), NULL);
968
969 gtk_plot_canvas_construct(GTK_PLOT_CANVAS(plot_canvas),
970 width, height, magnification);
971
972 return GTK_WIDGET (plot_canvas);
973 }
974
975 /**
976 * gtk_plot_canvas_construct:
977 * @canvas: a #GtkPlotCanvas.
978 * @width:
979 * @height:
980 * @magnification:
981 *
982 *
983 */
984 void
gtk_plot_canvas_construct(GtkPlotCanvas * canvas,gint width,gint height,gdouble magnification)985 gtk_plot_canvas_construct(GtkPlotCanvas *canvas,
986 gint width, gint height, gdouble magnification)
987 {
988 gdouble m = magnification;
989
990 canvas->width = width;
991 canvas->height = height;
992 canvas->pixmap_width = roundint(width * m);
993 canvas->pixmap_height = roundint(height * m);
994 gtk_plot_canvas_set_magnification(canvas, m);
995
996 gtk_fixed_set_has_window (GTK_FIXED(canvas), TRUE);
997 }
998
999 /**
1000 * gtk_plot_canvas_freeze:
1001 * @canvas: a #GtkPlotCanvas.
1002 *
1003 *
1004 */
1005 void
gtk_plot_canvas_freeze(GtkPlotCanvas * canvas)1006 gtk_plot_canvas_freeze(GtkPlotCanvas *canvas)
1007 {
1008 canvas->freeze_count++;
1009 }
1010
1011 /**
1012 * gtk_plot_canvas_thaw:
1013 * @canvas: a #GtkPlotCanvas.
1014 *
1015 *
1016 */
1017 void
gtk_plot_canvas_thaw(GtkPlotCanvas * canvas)1018 gtk_plot_canvas_thaw(GtkPlotCanvas *canvas)
1019 {
1020 if(canvas->freeze_count == 0) return;
1021 canvas->freeze_count--;
1022 }
1023
1024 static void
gtk_plot_canvas_destroy(GtkObject * object)1025 gtk_plot_canvas_destroy (GtkObject *object)
1026 {
1027 GtkPlotCanvas *plot_canvas;
1028 GList *list;
1029 gboolean veto = TRUE;
1030
1031 g_return_if_fail (object != NULL);
1032 g_return_if_fail (GTK_IS_PLOT_CANVAS (object));
1033
1034 plot_canvas = GTK_PLOT_CANVAS (object);
1035
1036 list = plot_canvas->childs;
1037 while(list){
1038 g_signal_emit(GTK_OBJECT(plot_canvas), canvas_signals[DELETE_ITEM], 0,
1039 GTK_PLOT_CANVAS_CHILD(list->data), &veto);
1040
1041 g_object_unref(GTK_OBJECT(list->data));
1042
1043 plot_canvas->childs = g_list_remove_link(plot_canvas->childs, list);
1044 g_list_free_1(list);
1045
1046 list = plot_canvas->childs;
1047 }
1048
1049 plot_canvas->childs = NULL;
1050
1051 if( plot_canvas->cursor ){
1052 gdk_cursor_destroy(plot_canvas->cursor);
1053 plot_canvas->cursor = NULL;
1054 }
1055 if( plot_canvas->pc ){
1056 g_object_unref(GTK_OBJECT(plot_canvas->pc));
1057 plot_canvas->pc = NULL;
1058 }
1059
1060 /* Added by Jacek Sieka jsieka at memphite.se , from Memphite AB */
1061 if( plot_canvas->pixmap ){
1062 gdk_pixmap_unref(plot_canvas->pixmap);
1063 plot_canvas->pixmap = NULL;
1064 }
1065
1066 if (GTK_OBJECT_CLASS (parent_class)->destroy)
1067 (*GTK_OBJECT_CLASS (parent_class)->destroy) (object);
1068
1069 gtk_psfont_unref();
1070 }
1071
1072 /**
1073 * gtk_plot_canvas_remove_child:
1074 * @canvas: a #GtkPlotCanvas.
1075 * @child: a #GtkPlotCanvasChild
1076 *
1077 *
1078 */
1079 void
gtk_plot_canvas_remove_child(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)1080 gtk_plot_canvas_remove_child(GtkPlotCanvas *canvas, GtkPlotCanvasChild *child)
1081 {
1082 GList *list;
1083
1084 gtk_plot_canvas_cancel_action(canvas);
1085
1086 list = canvas->childs;
1087 while(list){
1088 if(list->data == child){
1089 gboolean veto = TRUE;
1090
1091 _gtkextra_signal_emit(GTK_OBJECT(canvas), canvas_signals[DELETE_ITEM],
1092 child, &veto);
1093
1094 if(veto){
1095 child->parent = NULL;
1096 g_object_unref(GTK_OBJECT(child));
1097 canvas->childs = g_list_remove_link(canvas->childs, list);
1098 g_list_free_1(list);
1099 }
1100 break;
1101 }
1102 list = list->next;
1103 }
1104 }
1105
1106 /*
1107 static void
1108 gtk_plot_canvas_draw (GtkWidget *widget, GdkRectangle *area)
1109 {
1110 GtkPlotCanvas *canvas;
1111
1112 canvas = GTK_PLOT_CANVAS(widget);
1113
1114 if(!gtk_widget_get_realized(widget)) return;
1115 if(!canvas->pixmap) return;
1116
1117 GTK_WIDGET_CLASS(parent_class)->draw(widget, area);
1118
1119 gtk_plot_canvas_paint(canvas);
1120 gtk_plot_canvas_refresh(canvas);
1121 }
1122 */
1123
1124 /**
1125 * gtk_plot_canvas_paint:
1126 * @canvas: a #GtkPlotCanvas.
1127 *
1128 *
1129 */
1130 void
gtk_plot_canvas_paint(GtkPlotCanvas * canvas)1131 gtk_plot_canvas_paint (GtkPlotCanvas *canvas)
1132 {
1133 GtkWidget *widget;
1134 GList *childs;
1135
1136 widget = GTK_WIDGET(canvas);
1137
1138 if(gtk_widget_get_realized(widget) && !canvas->pixmap) return;
1139 if(canvas->freeze_count > 0) return;
1140
1141 if(!gtk_plot_pc_init(canvas->pc)) return;
1142
1143 gtk_plot_pc_gsave(canvas->pc);
1144
1145 if(!GTK_IS_PLOT_PS(canvas->pc) || !canvas->transparent){
1146 if(canvas->transparent){
1147 GdkColor white;
1148 gdk_color_white(gtk_widget_get_colormap(GTK_WIDGET(canvas)), &white);
1149 gtk_plot_pc_set_color(canvas->pc, &white);
1150 } else
1151 gtk_plot_pc_set_color(canvas->pc, &canvas->background);
1152 gtk_plot_pc_draw_rectangle(canvas->pc,
1153 TRUE,
1154 0,0,canvas->pixmap_width, canvas->pixmap_height);
1155 }
1156
1157 gtk_plot_canvas_draw_grid(canvas);
1158
1159 childs = canvas->childs;
1160 while(childs)
1161 {
1162 GtkPlotCanvasChild *child;
1163
1164 child = GTK_PLOT_CANVAS_CHILD(childs->data);
1165 gtk_plot_canvas_child_draw(canvas, child);
1166 childs = childs->next;
1167 }
1168
1169 gtk_plot_pc_grestore(canvas->pc);
1170 gtk_plot_pc_leave(canvas->pc);
1171 }
1172
1173 /**
1174 * gtk_plot_canvas_refresh:
1175 * @canvas: a #GtkPlotCanvas.
1176 *
1177 *
1178 */
1179 void
gtk_plot_canvas_refresh(GtkPlotCanvas * canvas)1180 gtk_plot_canvas_refresh(GtkPlotCanvas *canvas)
1181 {
1182 GList *children = NULL;
1183 GtkFixed *fixed = GTK_FIXED(canvas);
1184
1185 if(!gtk_widget_get_realized(GTK_WIDGET(canvas))) return;
1186 if(!canvas->pixmap) return;
1187 if(canvas->freeze_count > 0) return;
1188
1189 gdk_draw_drawable(gtk_widget_get_window(GTK_WIDGET(canvas)),
1190 gtk_widget_get_style(GTK_WIDGET(canvas))->fg_gc[GTK_STATE_NORMAL],
1191 canvas->pixmap,
1192 0, 0,
1193 0, 0,
1194 -1, -1);
1195
1196 children = fixed->children;
1197 while (children)
1198 {
1199 GtkFixedChild *child;
1200 child = children->data;
1201 gtk_widget_queue_draw(child->widget);
1202 children = children->next;
1203 }
1204
1205 }
1206
1207 static void
gtk_plot_canvas_draw_grid(GtkPlotCanvas * canvas)1208 gtk_plot_canvas_draw_grid(GtkPlotCanvas *canvas)
1209 {
1210 gdouble x, y;
1211
1212 if(!canvas->pixmap) return;
1213 if(!canvas->show_grid) return;
1214
1215 if(!canvas->pc) return;
1216
1217 gtk_plot_canvas_set_line_attributes(canvas, canvas->grid);
1218
1219 for(x = 0; x < canvas->pixmap_width; x += canvas->grid_step)
1220 gtk_plot_pc_draw_line(canvas->pc,
1221 roundint(x), 0, roundint(x), canvas->pixmap_height);
1222
1223 for(y = 0; y < canvas->pixmap_height; y += canvas->grid_step)
1224 gtk_plot_pc_draw_line(canvas->pc,
1225 0, roundint(y), canvas->pixmap_width, roundint(y));
1226 }
1227
1228 static void
gtk_plot_canvas_map(GtkWidget * widget)1229 gtk_plot_canvas_map(GtkWidget *widget)
1230 {
1231 GtkPlotCanvas *plot_canvas;
1232
1233 plot_canvas=GTK_PLOT_CANVAS(widget);
1234
1235 GTK_WIDGET_CLASS(parent_class)->map(widget);
1236
1237 if(!plot_canvas->pixmap){
1238 gtk_plot_canvas_create_pixmap(widget,
1239 plot_canvas->pixmap_width,
1240 plot_canvas->pixmap_height);
1241 if (GTK_IS_PLOT_CAIRO(plot_canvas->pc)) {
1242 gtk_plot_canvas_set_pc(plot_canvas, GTK_PLOT_PC(gtk_plot_cairo_new_with_drawable(plot_canvas->pixmap)));
1243 }
1244 }
1245
1246 gtk_plot_canvas_paint(plot_canvas);
1247 gdk_window_set_cursor(gtk_widget_get_window(widget), plot_canvas->cursor);
1248 }
1249
1250 static gint
gtk_plot_canvas_key_press(GtkWidget * widget,GdkEventKey * key)1251 gtk_plot_canvas_key_press(GtkWidget *widget, GdkEventKey *key)
1252 {
1253 GtkPlotCanvas *canvas = GTK_PLOT_CANVAS(widget);
1254
1255 switch (key->keyval)
1256 {
1257 case GDK_KEY_Escape:
1258 gtk_plot_canvas_cancel_action(canvas);
1259 break;
1260
1261 default: break;
1262 }
1263 return TRUE;
1264 }
1265
1266 static gint
gtk_plot_canvas_motion(GtkWidget * widget,GdkEventMotion * event)1267 gtk_plot_canvas_motion (GtkWidget *widget, GdkEventMotion *event)
1268 {
1269 GtkPlotCanvas *canvas;
1270 GtkAllocation area;
1271 gint x, y;
1272 gint new_x = 0, new_y = 0;
1273 gint new_width = 0, new_height = 0;
1274 gint cursor = GDK_TOP_LEFT_ARROW;
1275 gint pivot_x, pivot_y;
1276
1277 canvas = GTK_PLOT_CANVAS(widget);
1278 gtk_widget_get_pointer(widget, &x, &y);
1279
1280 if(canvas->active_item && canvas->active_item->flags == GTK_PLOT_CANVAS_CHILD_FROZEN) return TRUE;
1281
1282 if(canvas->active_item){
1283 area = canvas->active_item->drag_area;
1284 new_x = area.x;
1285 new_y = area.y;
1286 new_width = area.width;
1287 new_height = area.height;
1288 }
1289 pivot_x = x;
1290 pivot_y = y;
1291
1292 if(canvas->action == GTK_PLOT_CANVAS_ACTION_INACTIVE)
1293 cursor = GDK_TOP_LEFT_ARROW;
1294 else if(canvas->action == GTK_PLOT_CANVAS_ACTION_DRAG)
1295 cursor = GDK_FLEUR;
1296 else
1297 switch(canvas->drag_point){
1298 case GTK_PLOT_CANVAS_TOP_LEFT:
1299 cursor = GDK_UL_ANGLE;
1300 pivot_x = area.x + area.width;
1301 pivot_y = area.y + area.height;
1302 break;
1303 case GTK_PLOT_CANVAS_TOP_RIGHT:
1304 cursor = GDK_UR_ANGLE;
1305 pivot_x = area.x;
1306 pivot_y = area.y + area.height;
1307 break;
1308 case GTK_PLOT_CANVAS_TOP:
1309 cursor = GDK_TOP_SIDE;
1310 pivot_y = area.y + area.height;
1311 break;
1312 case GTK_PLOT_CANVAS_BOTTOM_LEFT:
1313 cursor = GDK_LL_ANGLE;
1314 pivot_x = area.x + area.width;
1315 pivot_y = area.y;
1316 break;
1317 case GTK_PLOT_CANVAS_BOTTOM_RIGHT:
1318 cursor = GDK_LR_ANGLE;
1319 pivot_x = area.x;
1320 pivot_y = area.y;
1321 break;
1322 case GTK_PLOT_CANVAS_BOTTOM:
1323 cursor = GDK_BOTTOM_SIDE;
1324 pivot_y = area.y;
1325 break;
1326 case GTK_PLOT_CANVAS_LEFT:
1327 cursor = GDK_LEFT_SIDE;
1328 pivot_x = area.x + area.width;
1329 break;
1330 case GTK_PLOT_CANVAS_RIGHT:
1331 cursor = GDK_RIGHT_SIDE;
1332 pivot_x = area.x;
1333 break;
1334 default:
1335 cursor = GDK_TOP_LEFT_ARROW;
1336 }
1337
1338 if(cursor != gdk_cursor_get_cursor_type(canvas->cursor)){
1339 gdk_cursor_destroy(canvas->cursor);
1340 canvas->cursor = gdk_cursor_new(cursor);
1341 gdk_window_set_cursor(gtk_widget_get_window(widget), canvas->cursor);
1342 }
1343
1344
1345 if(canvas->action == GTK_PLOT_CANVAS_ACTION_INACTIVE) return TRUE;
1346
1347 switch(canvas->action){
1348 case GTK_PLOT_CANVAS_ACTION_DRAG:
1349 if(canvas->active_item && canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_MOVE){
1350 gint dx, dy;
1351
1352 gtk_plot_canvas_child_draw_selection(canvas, canvas->active_item, canvas->drag_area);
1353 canvas->pointer_x = x;
1354 canvas->pointer_y = y;
1355 dx = x - canvas->drag_x;
1356 dy = y - canvas->drag_y;
1357 area.x = canvas->active_item->drag_area.x + dx;
1358 area.y = canvas->active_item->drag_area.y + dy;
1359 gtk_plot_canvas_child_draw_selection(canvas, canvas->active_item, area);
1360 canvas->drag_area = area;
1361 }
1362 break;
1363 case GTK_PLOT_CANVAS_ACTION_RESIZE:
1364 switch(canvas->drag_point){
1365 case GTK_PLOT_CANVAS_TOP_LEFT:
1366 case GTK_PLOT_CANVAS_TOP_RIGHT:
1367 if(canvas->active_item && canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE){
1368 new_x = MIN(x, pivot_x);
1369 new_width = abs(x - pivot_x);
1370 }
1371 case GTK_PLOT_CANVAS_TOP:
1372 if(canvas->active_item && canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE){
1373 new_y = MIN(y, pivot_y);
1374 new_height = abs(y - pivot_y);
1375 }
1376 gdk_cursor_destroy(canvas->cursor);
1377 canvas->cursor = gdk_cursor_new(cursor);
1378 gdk_window_set_cursor(gtk_widget_get_window(widget), canvas->cursor);
1379 break;
1380 case GTK_PLOT_CANVAS_BOTTOM_LEFT:
1381 case GTK_PLOT_CANVAS_BOTTOM_RIGHT:
1382 if(canvas->active_item && canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE){
1383 new_x = MIN(x, pivot_x);
1384 new_width = abs(x - pivot_x);
1385 }
1386 case GTK_PLOT_CANVAS_BOTTOM:
1387 if(canvas->active_item && canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE){
1388 new_y = MIN(y, pivot_y);
1389 new_height = abs(y - pivot_y);
1390 }
1391 break;
1392 case GTK_PLOT_CANVAS_LEFT:
1393 case GTK_PLOT_CANVAS_RIGHT:
1394 if(canvas->active_item && canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE){
1395 new_x = MIN(x, pivot_x);
1396 new_width = abs(x - pivot_x);
1397 }
1398 break;
1399 case GTK_PLOT_CANVAS_IN:
1400 case GTK_PLOT_CANVAS_OUT:
1401 default:
1402 break;
1403 }
1404
1405
1406 if(canvas->active_item && new_width >= canvas->active_item->min_width &&
1407 new_height >= canvas->active_item->min_height){
1408
1409 gtk_plot_canvas_child_draw_selection(canvas, canvas->active_item, canvas->drag_area);
1410 canvas->pointer_x = x;
1411 canvas->pointer_y = y;
1412 if(canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_MOVE || canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE){
1413 area.x = new_x;
1414 area.y = new_y;
1415 }
1416 if(canvas->active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE){
1417 area.width = new_width;
1418 area.height = new_height;
1419 }
1420 gtk_plot_canvas_child_draw_selection(canvas, canvas->active_item, area);
1421 canvas->drag_area = area;
1422
1423 }
1424
1425 break;
1426 case GTK_PLOT_CANVAS_ACTION_SELECTION:
1427 draw_selection(canvas, NULL, canvas->drag_area);
1428 canvas->pointer_x = x;
1429 canvas->pointer_y = y;
1430 area.x = MIN(canvas->pointer_x, canvas->drag_x);
1431 area.y = MIN(canvas->pointer_y, canvas->drag_y);
1432 area.width = abs(x - canvas->drag_x);
1433 area.height = abs(y - canvas->drag_y);
1434 canvas->drag_area = area;
1435 draw_selection(canvas, NULL, canvas->drag_area);
1436 break;
1437 case GTK_PLOT_CANVAS_ACTION_INACTIVE:
1438 default:
1439 break;
1440 }
1441
1442 return TRUE;
1443
1444 }
1445
1446 static GtkPlotCanvasPos
gtk_plot_canvas_child_button_press(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gint x,gint y)1447 gtk_plot_canvas_child_button_press(GtkPlotCanvas *canvas,
1448 GtkPlotCanvasChild *child,
1449 gint x, gint y)
1450 {
1451 GtkPlotCanvasPos pos;
1452 GtkAllocation area;
1453
1454 area = child->allocation;
1455
1456 if((pos = possible_selection(area, x, y)) != GTK_PLOT_CANVAS_OUT){
1457 child->state = GTK_STATE_SELECTED;
1458 child->drag_area = area;
1459 }
1460 return pos;
1461 }
1462
1463 static gint
gtk_plot_canvas_button_press(GtkWidget * widget,GdkEventButton * event)1464 gtk_plot_canvas_button_press(GtkWidget *widget, GdkEventButton *event)
1465 {
1466 GtkPlotCanvas *canvas = NULL;
1467 GtkPlotCanvasChild *active_item = NULL;
1468 GList *childs = NULL;
1469 GdkModifierType mods;
1470 gint x = 0, y = 0;
1471 gboolean veto;
1472 gboolean double_click = FALSE;
1473 gdouble m;
1474 gboolean new_item = FALSE;
1475 GtkPlotCanvasPos pos = GTK_PLOT_CANVAS_OUT;
1476
1477 gdk_window_get_pointer(gtk_widget_get_window(widget), NULL, NULL, &mods);
1478 if(!(mods & GDK_BUTTON1_MASK)) return FALSE;
1479 double_click = (event->button == GDK_2BUTTON_PRESS);
1480
1481 canvas = GTK_PLOT_CANVAS(widget);
1482 m = canvas->magnification;
1483
1484 /*
1485 if(double_click && canvas->state == GTK_STATE_SELECTED) return TRUE;
1486 */
1487 /*
1488 gdk_pointer_ungrab(event->time);
1489 */
1490
1491 if(!gtk_widget_has_focus(widget)) gtk_widget_grab_focus(widget);
1492
1493 gtk_widget_get_pointer(widget, &x, &y);
1494
1495 /**********************************************************************/
1496
1497 if(GTK_PLOT_CANVAS_CAN_SELECT_ITEM(canvas)){
1498 childs = g_list_last(canvas->childs);
1499 while(childs)
1500 {
1501 GtkPlotCanvasChild *child = GTK_PLOT_CANVAS_CHILD(childs->data);
1502
1503 pos = GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->button_press(canvas, child, x, y);
1504 if(pos != GTK_PLOT_CANVAS_OUT && child->state == GTK_STATE_SELECTED){
1505 active_item = child;
1506 break;
1507 }
1508
1509 childs = childs->prev;
1510 }
1511
1512 /**********************************************************************/
1513
1514 new_item = active_item && ((canvas->state != GTK_STATE_SELECTED ||
1515 active_item != canvas->active_item));
1516
1517 veto = TRUE;
1518 if(active_item && active_item->state == GTK_STATE_SELECTED)
1519 _gtkextra_signal_emit(GTK_OBJECT(canvas), canvas_signals[SELECT_ITEM],
1520 event, active_item, &veto);
1521
1522 if(new_item){
1523
1524 if(veto){
1525 gtk_plot_canvas_unselect(canvas);
1526 canvas->active_item = active_item;
1527 canvas->drag_area = active_item->drag_area;
1528 canvas->state = GTK_STATE_SELECTED;
1529 canvas->action = GTK_PLOT_CANVAS_ACTION_INACTIVE;
1530
1531 canvas->drag_point = pos;
1532
1533 canvas->drag_x = x;
1534 canvas->drag_y = y;
1535 canvas->pointer_x = x;
1536 canvas->pointer_y = y;
1537
1538 gtk_plot_canvas_child_draw_selection(canvas, active_item, active_item->drag_area);
1539
1540 if(active_item->mode == GTK_PLOT_CANVAS_SELECT_CLICK_2)
1541 return TRUE;
1542 }
1543 }
1544 if(active_item && veto){
1545 if((!new_item && active_item->mode == GTK_PLOT_CANVAS_SELECT_CLICK_2) || active_item->mode == GTK_PLOT_CANVAS_SELECT_CLICK_1) {
1546
1547 if(GTK_PLOT_CANVAS_CAN_DND(canvas)) {
1548 switch(pos){
1549 case GTK_PLOT_CANVAS_IN:
1550 canvas->action = GTK_PLOT_CANVAS_ACTION_DRAG;
1551 break;
1552 default:
1553 if(active_item->flags & GTK_PLOT_CANVAS_CHILD_CAN_RESIZE)
1554 canvas->action = GTK_PLOT_CANVAS_ACTION_RESIZE;
1555 else
1556 canvas->action = GTK_PLOT_CANVAS_ACTION_DRAG;
1557 }
1558 /*
1559 gdk_pointer_grab (gtk_widget_get_window(widget), FALSE,
1560 GDK_POINTER_MOTION_HINT_MASK |
1561 GDK_BUTTON1_MOTION_MASK |
1562 GDK_BUTTON_RELEASE_MASK,
1563 NULL, NULL, event->time);
1564 */
1565 canvas->drag_point = pos;
1566
1567 canvas->drag_x = x;
1568 canvas->drag_y = y;
1569 canvas->pointer_x = x;
1570 canvas->pointer_y = y;
1571
1572 return TRUE;
1573 }
1574 }
1575 }
1576 }
1577 gtk_plot_canvas_unselect(canvas);
1578
1579 if(GTK_PLOT_CANVAS_CAN_SELECT(canvas)){
1580 veto = TRUE;
1581
1582 _gtkextra_signal_emit(GTK_OBJECT(canvas), canvas_signals[SELECT_ITEM],
1583 event, NULL, &veto);
1584 if(veto){
1585 canvas->active_item = NULL;
1586 canvas->state = GTK_STATE_SELECTED;
1587 canvas->action = GTK_PLOT_CANVAS_ACTION_SELECTION;
1588 canvas->drag_point = pos;
1589 canvas->drag_x = x;
1590 canvas->drag_y = y;
1591 canvas->pointer_x = x;
1592 canvas->pointer_y = y;
1593 canvas->drag_area.x = x;
1594 canvas->drag_area.y = y;
1595 canvas->drag_area.width = 0;
1596 canvas->drag_area.height = 0;
1597 /*
1598 gdk_pointer_grab (gtk_widget_get_window(widget), FALSE,
1599 GDK_POINTER_MOTION_HINT_MASK |
1600 GDK_BUTTON1_MOTION_MASK |
1601 GDK_BUTTON_RELEASE_MASK,
1602 NULL, NULL, event->time);
1603 */
1604 draw_selection(canvas, NULL, canvas->drag_area);
1605 }
1606 }
1607
1608 return TRUE;
1609 }
1610
1611 static void
gtk_plot_canvas_child_button_release(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)1612 gtk_plot_canvas_child_button_release(GtkPlotCanvas *canvas, GtkPlotCanvasChild *child)
1613 {
1614 gdouble new_x, new_y, new_width, new_height;
1615 double dx, dy;
1616 gdouble x1, x2, y1, y2;
1617
1618 gtk_plot_canvas_get_position(canvas,
1619 canvas->drag_area.width,
1620 canvas->drag_area.height,
1621 &new_width, &new_height);
1622
1623 gtk_plot_canvas_get_position(canvas,
1624 canvas->drag_area.x,
1625 canvas->drag_area.y,
1626 &new_x, &new_y);
1627
1628 gtk_plot_canvas_get_position(canvas,
1629 canvas->drag_area.x - child->drag_area.x,
1630 canvas->drag_area.y - child->drag_area.y,
1631 &dx, &dy);
1632
1633 x1 = MIN(child->rx1, child->rx2);
1634 y1 = MIN(child->ry1, child->ry2);
1635 x2 = MAX(child->rx1, child->rx2);
1636 y2 = MAX(child->ry1, child->ry2);
1637 x1 += dx;
1638 y1 += dy;
1639 x2 = x1 + new_width;
1640 y2 = y1 + new_height;
1641
1642 gtk_plot_canvas_child_move_resize(canvas, child, x1, y1, x2, y2);
1643 child->drag_area = canvas->drag_area;
1644 }
1645
1646 static gint
gtk_plot_canvas_button_release(GtkWidget * widget,GdkEventButton * event)1647 gtk_plot_canvas_button_release(GtkWidget *widget, GdkEventButton *event)
1648 {
1649 GtkPlotCanvas *canvas;
1650 gdouble new_x, new_y;
1651 gdouble new_width, new_height;
1652 gdouble x1 = 0., y1 = 0., x2 = 0., y2 = 0.;
1653 gboolean veto = TRUE;
1654 gdouble dx = 0., dy = 0.;
1655
1656 canvas = GTK_PLOT_CANVAS(widget);
1657
1658 /*
1659 gdk_pointer_ungrab(event->time);
1660 */
1661
1662 if(gtk_widget_get_mapped(widget)){
1663 gdk_cursor_destroy(canvas->cursor);
1664 canvas->cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW);
1665 gdk_window_set_cursor(gtk_widget_get_window(widget),
1666 canvas->cursor);
1667 }
1668
1669 if(canvas->action == GTK_PLOT_CANVAS_ACTION_INACTIVE) return TRUE;
1670
1671 gtk_plot_canvas_get_position(canvas,
1672 canvas->drag_area.width,
1673 canvas->drag_area.height,
1674 &new_width, &new_height);
1675
1676 gtk_plot_canvas_get_position(canvas,
1677 canvas->drag_area.x,
1678 canvas->drag_area.y,
1679 &new_x, &new_y);
1680
1681 if(canvas->action != GTK_PLOT_CANVAS_ACTION_SELECTION && canvas->active_item){
1682 GtkPlotCanvasChild *child = canvas->active_item;
1683
1684 gtk_plot_canvas_get_position(canvas,
1685 canvas->drag_area.x -
1686 canvas->active_item->drag_area.x,
1687 canvas->drag_area.y -
1688 canvas->active_item->drag_area.y,
1689 &dx, &dy);
1690
1691 x1 = MIN(child->rx1, child->rx2);
1692 y1 = MIN(child->ry1, child->ry2);
1693 x2 = MAX(child->rx1, child->rx2);
1694 y2 = MAX(child->ry1, child->ry2);
1695 x1 += dx;
1696 y1 += dy;
1697 x2 = x1 + new_width;
1698 y2 = y1 + new_height;
1699
1700 if(canvas->action == GTK_PLOT_CANVAS_ACTION_DRAG){
1701 _gtkextra_signal_emit(GTK_OBJECT(canvas), canvas_signals[MOVE_ITEM],
1702 child,
1703 x1, y1, &veto);
1704 }
1705 if(canvas->action == GTK_PLOT_CANVAS_ACTION_RESIZE){
1706 _gtkextra_signal_emit(GTK_OBJECT(canvas),
1707 canvas_signals[RESIZE_ITEM],
1708 child, new_width, new_height, &veto);
1709 }
1710 if(canvas->action != GTK_PLOT_CANVAS_ACTION_INACTIVE && veto) {
1711 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(canvas->active_item)))->button_release)
1712 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(canvas->active_item)))->button_release(canvas, canvas->active_item);
1713
1714 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
1715 canvas->pointer_x = canvas->pointer_y = canvas->drag_x = canvas->drag_y = 0;
1716 gtk_plot_canvas_child_draw_selection(canvas, canvas->active_item, canvas->active_item->drag_area);
1717 canvas->action = GTK_PLOT_CANVAS_ACTION_INACTIVE;
1718 return TRUE;
1719 } else {
1720 canvas->state = GTK_STATE_NORMAL;
1721 }
1722
1723 } else {
1724 gtk_plot_canvas_get_position(canvas,
1725 canvas->drag_x, canvas->drag_y,
1726 &x1, &y1);
1727 gtk_plot_canvas_get_position(canvas,
1728 canvas->pointer_x, canvas->pointer_y,
1729 &x2, &y2);
1730 new_width = abs(canvas->pointer_x - canvas->drag_x);
1731 new_height = abs(canvas->pointer_y - canvas->drag_y);
1732 draw_selection(canvas, NULL, canvas->drag_area);
1733 g_signal_emit(GTK_OBJECT(canvas), canvas_signals[SELECT_REGION], 0,
1734 x1, y1, x2, y2);
1735 canvas->state = GTK_STATE_NORMAL;
1736 canvas->action = GTK_PLOT_CANVAS_ACTION_INACTIVE;
1737 return TRUE;
1738 }
1739
1740 canvas->drag_x = canvas->pointer_x;
1741 canvas->drag_y = canvas->pointer_y;
1742
1743 if(canvas->action != GTK_PLOT_CANVAS_ACTION_SELECTION)
1744 canvas->state = GTK_STATE_NORMAL;
1745 canvas->action = GTK_PLOT_CANVAS_ACTION_INACTIVE;
1746
1747 return TRUE;
1748
1749 }
1750
1751 static gint
gtk_plot_canvas_focus_in(GtkWidget * widget,GdkEventFocus * event)1752 gtk_plot_canvas_focus_in(GtkWidget *widget, GdkEventFocus *event)
1753 {
1754 GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
1755 return FALSE;
1756 }
1757
1758
1759 static gint
gtk_plot_canvas_focus_out(GtkWidget * widget,GdkEventFocus * event)1760 gtk_plot_canvas_focus_out(GtkWidget *widget, GdkEventFocus *event)
1761 {
1762 GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
1763 gtk_plot_canvas_unselect(GTK_PLOT_CANVAS(widget));
1764 return FALSE;
1765 }
1766
1767 /**
1768 * gtk_plot_canvas_set_transparent:
1769 * @canvas: a #GtkPlotCanvas.
1770 * @transparent:
1771 *
1772 *
1773 */
1774 void
gtk_plot_canvas_set_transparent(GtkPlotCanvas * canvas,gboolean transparent)1775 gtk_plot_canvas_set_transparent (GtkPlotCanvas *canvas, gboolean transparent)
1776 {
1777 g_return_if_fail (canvas != NULL);
1778 g_return_if_fail (GTK_IS_PLOT_CANVAS (canvas));
1779
1780 canvas->transparent = transparent;
1781 }
1782
1783 /**
1784 * gtk_plot_canvas_trasnparent:
1785 * @canvas: a #GtkPlotCanvas.
1786 *
1787 *
1788 *
1789 * Return value:
1790 */
1791 gboolean
gtk_plot_canvas_transparent(GtkPlotCanvas * canvas)1792 gtk_plot_canvas_transparent (GtkPlotCanvas *canvas)
1793 {
1794 g_return_val_if_fail (canvas != NULL, TRUE);
1795 g_return_val_if_fail (GTK_IS_PLOT_CANVAS (canvas), TRUE);
1796
1797 return(canvas->transparent);
1798 }
1799
1800 /**
1801 * gtk_plot_canvas_set_background:
1802 * @canvas: a #GtkPlotCanvas.
1803 * @bg_color: a GdkColor.
1804 *
1805 *
1806 */
1807 void
gtk_plot_canvas_set_background(GtkPlotCanvas * canvas,const GdkColor * bg_color)1808 gtk_plot_canvas_set_background (GtkPlotCanvas *canvas, const GdkColor *bg_color)
1809 {
1810
1811 g_return_if_fail (canvas != NULL);
1812 g_return_if_fail (GTK_IS_PLOT_CANVAS (canvas));
1813
1814 if(!bg_color) {
1815 canvas->transparent = TRUE;
1816 return;
1817 } else {
1818 canvas->background = *bg_color;
1819 canvas->transparent = FALSE;
1820 }
1821
1822 if(gtk_widget_get_realized(GTK_WIDGET(canvas)))
1823 gtk_plot_canvas_paint(canvas);
1824
1825 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
1826 }
1827
1828 /**
1829 * gtk_plot_canvas_get_pixel:
1830 * @canvas: a #GtkPlotCanvas.
1831 * @px:
1832 * @py:
1833 * @x:
1834 * @y:
1835 *
1836 *
1837 */
1838 void
gtk_plot_canvas_get_pixel(GtkPlotCanvas * canvas,gdouble px,gdouble py,gint * x,gint * y)1839 gtk_plot_canvas_get_pixel(GtkPlotCanvas *canvas, gdouble px, gdouble py,
1840 gint *x, gint *y)
1841 {
1842 *x = roundint(canvas->pixmap_width * px);
1843 *y = roundint(canvas->pixmap_height * py);
1844 }
1845
1846 /**
1847 * gtk_plot_canvas_get_position:
1848 * @plot_canvas: a #GtkPlotCanvas.
1849 * @x:
1850 * @y:
1851 * @px:
1852 * @py:
1853 *
1854 *
1855 */
1856 void
gtk_plot_canvas_get_position(GtkPlotCanvas * plot_canvas,gint x,gint y,gdouble * px,gdouble * py)1857 gtk_plot_canvas_get_position(GtkPlotCanvas *plot_canvas, gint x, gint y,
1858 gdouble *px, gdouble *py)
1859 {
1860 *px = (gdouble) x / (gdouble) plot_canvas->pixmap_width;
1861 *py = (gdouble) y / (gdouble) plot_canvas->pixmap_height;
1862 }
1863
1864 /**
1865 * gtk_plot_canvas_unselect:
1866 * @plot_canvas: a #GtkPlotCanvas.
1867 *
1868 *
1869 */
1870 void
gtk_plot_canvas_unselect(GtkPlotCanvas * plot_canvas)1871 gtk_plot_canvas_unselect (GtkPlotCanvas *plot_canvas)
1872 {
1873
1874 if(plot_canvas->state == GTK_STATE_SELECTED){
1875 if(plot_canvas->active_item)
1876 gtk_plot_canvas_child_draw_selection(plot_canvas, plot_canvas->active_item, plot_canvas->drag_area);
1877 else
1878 draw_selection(plot_canvas, NULL, plot_canvas->drag_area);
1879 }
1880
1881 plot_canvas->action = GTK_PLOT_CANVAS_ACTION_INACTIVE;
1882 plot_canvas->state = GTK_STATE_NORMAL;
1883 if(plot_canvas->active_item){
1884 plot_canvas->active_item->state = GTK_STATE_NORMAL;
1885 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(plot_canvas->active_item)))->unselect)
1886 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(plot_canvas->active_item)))->unselect(plot_canvas, plot_canvas->active_item);
1887 }
1888 plot_canvas->active_item = NULL;
1889
1890 if(gtk_widget_get_mapped(GTK_WIDGET(plot_canvas))){
1891 gdk_cursor_destroy(plot_canvas->cursor);
1892 plot_canvas->cursor = gdk_cursor_new(GDK_TOP_LEFT_ARROW);
1893 gdk_window_set_cursor(gtk_widget_get_window(GTK_WIDGET(plot_canvas)),
1894 plot_canvas->cursor);
1895 }
1896 }
1897
1898 /**
1899 * gtk_plot_canvas_cancel_action:
1900 * @plot_canvas: a #GtkPlotCanvas.
1901 *
1902 *
1903 */
1904
1905 void
gtk_plot_canvas_cancel_action(GtkPlotCanvas * plot_canvas)1906 gtk_plot_canvas_cancel_action (GtkPlotCanvas *plot_canvas)
1907 {
1908 gtk_plot_canvas_unselect(plot_canvas);
1909 /*
1910 gdk_pointer_ungrab(GDK_CURRENT_TIME);
1911 */
1912 }
1913
1914
1915 /**
1916 * gtk_plot_canvas_get_active_item:
1917 * @canvas: a #GtkPlotCanvas.
1918 *
1919 * Return value: (transfer none): the active #GtkPlotCanvasChild
1920 */
1921 GtkPlotCanvasChild *
gtk_plot_canvas_get_active_item(GtkPlotCanvas * canvas)1922 gtk_plot_canvas_get_active_item(GtkPlotCanvas *canvas)
1923 {
1924 return (canvas->active_item);
1925 }
1926
1927 /**
1928 * gtk_plot_canvas_child_get_position:
1929 * @canvas: a #GtkPlotCanvas.
1930 * @child: a #GtkPlotCanvasChild.
1931 * @x1:
1932 * @y1:
1933 * @x2:
1934 * @y2:
1935 *
1936 *
1937 *
1938 * Return value:
1939 */
1940 gboolean
gtk_plot_canvas_child_get_position(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,double * x1,double * y1,double * x2,double * y2)1941 gtk_plot_canvas_child_get_position(GtkPlotCanvas *canvas,
1942 GtkPlotCanvasChild *child,
1943 double *x1, double *y1,
1944 double *x2, double *y2)
1945 {
1946 GList *list;
1947 gpointer data;
1948
1949 *x1 = child->rx1;
1950 *x2 = child->rx2;
1951 *y1 = child->ry1;
1952 *y2 = child->ry2;
1953
1954 list = canvas->childs;
1955
1956 /* Return TRUE if child is actually contained w/in canvas, and
1957 coordinates of the childs bounding box, else FALSE */
1958 while(list)
1959 {
1960 data = list->data;
1961 if(GTK_PLOT_CANVAS_CHILD(data) == child) return TRUE;
1962 list = list->next;
1963 }
1964
1965 return FALSE;
1966
1967 }
1968
1969 /**
1970 * gtk_plot_canvas_get_size:
1971 * @canvas: a #GtkPlotCanvas.
1972 * @width:
1973 * @height:
1974 *
1975 */
1976 void
gtk_plot_canvas_set_size(GtkPlotCanvas * canvas,gint width,gint height)1977 gtk_plot_canvas_set_size(GtkPlotCanvas *canvas, gint width, gint height)
1978 {
1979 GList *list = NULL;
1980 gdouble m = canvas->magnification;
1981 GtkAllocation allocation;
1982
1983 gtk_widget_get_allocation(GTK_WIDGET(canvas), &allocation);
1984
1985 gtk_plot_canvas_cancel_action(canvas);
1986
1987 canvas->width = width;
1988 canvas->height = height;
1989 canvas->pixmap_width = roundint(m * width);
1990 canvas->pixmap_height = roundint(m * height);
1991
1992 if(gtk_widget_get_mapped(GTK_WIDGET(canvas)) && canvas->pixmap){
1993 gtk_plot_canvas_create_pixmap(GTK_WIDGET(canvas),
1994 canvas->pixmap_width,
1995 canvas->pixmap_height);
1996 }
1997
1998 /*
1999 gtk_widget_set_size_request(GTK_WIDGET(canvas),
2000 canvas->pixmap_width, canvas->pixmap_height);
2001 */
2002
2003 allocation.width = canvas->pixmap_width;
2004 allocation.height = canvas->pixmap_height;
2005
2006 gtk_widget_size_allocate(GTK_WIDGET(canvas), &allocation);
2007
2008 list = canvas->childs;
2009 while(list){
2010 GtkPlotCanvasChild *child = GTK_PLOT_CANVAS_CHILD(list->data);
2011 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate)
2012 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate(canvas, child);
2013 list = list->next;
2014 }
2015
2016
2017 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2018 }
2019
2020 static void
gtk_plot_canvas_create_pixmap(GtkWidget * widget,gint width,gint height)2021 gtk_plot_canvas_create_pixmap(GtkWidget *widget, gint width, gint height)
2022 {
2023 GtkPlotCanvas *canvas;
2024 gint pixmap_width, pixmap_height;
2025
2026 canvas = GTK_PLOT_CANVAS(widget);
2027 if (!canvas->pixmap){
2028 canvas->pixmap = gdk_pixmap_new (gtk_widget_get_window(widget),
2029 width,
2030 height, -1);
2031 }else{
2032 gdk_window_get_size(canvas->pixmap, &pixmap_width, &pixmap_height);
2033 if(width != pixmap_width || height != pixmap_height){
2034 gdk_pixmap_unref(canvas->pixmap);
2035 canvas->pixmap = gdk_pixmap_new (gtk_widget_get_window(widget),
2036 width,
2037 height, -1);
2038 }
2039 }
2040
2041 if (canvas->pc && GTK_IS_PLOT_CAIRO(canvas->pc)) {
2042 gtk_plot_canvas_set_pc(canvas, GTK_PLOT_PC(gtk_plot_cairo_new_with_drawable(canvas->pixmap)));
2043 }
2044
2045 if(canvas->pc && GTK_IS_PLOT_GDK(canvas->pc)){
2046 GTK_PLOT_GDK(canvas->pc)->drawable = canvas->pixmap;
2047 }
2048 gtk_plot_pc_set_viewport(canvas->pc, width, height);
2049 }
2050
2051 static gint
gtk_plot_canvas_expose(GtkWidget * widget,GdkEventExpose * event)2052 gtk_plot_canvas_expose(GtkWidget *widget, GdkEventExpose *event)
2053 {
2054 GtkPlotCanvas *canvas;
2055 GdkPixmap *pixmap;
2056
2057 if(!gtk_widget_is_drawable(widget)) return FALSE;
2058
2059 canvas = GTK_PLOT_CANVAS(widget);
2060
2061 if(!canvas->pixmap){
2062 gtk_plot_canvas_create_pixmap(widget,
2063 canvas->pixmap_width,
2064 canvas->pixmap_height);
2065 gtk_plot_canvas_paint(canvas);
2066 return FALSE;
2067 }
2068
2069 pixmap = canvas->pixmap;
2070 gdk_draw_pixmap(gtk_widget_get_window(GTK_WIDGET(canvas)),
2071 gtk_widget_get_style(widget)->fg_gc[GTK_STATE_NORMAL],
2072 pixmap,
2073 event->area.x,
2074 event->area.y,
2075 event->area.x,
2076 event->area.y,
2077 event->area.width, event->area.height);
2078
2079 GTK_WIDGET_CLASS(parent_class)->expose_event(widget, event);
2080
2081 return FALSE;
2082
2083 }
2084
2085
2086 static void
gtk_plot_canvas_size_request(GtkWidget * widget,GtkRequisition * requisition)2087 gtk_plot_canvas_size_request (GtkWidget *widget, GtkRequisition *requisition)
2088 {
2089 GtkPlotCanvas *canvas;
2090
2091 canvas = GTK_PLOT_CANVAS(widget);
2092
2093 GTK_WIDGET_CLASS(parent_class)->size_request(widget, requisition);
2094
2095 gtk_widget_set_size_request(widget,
2096 MAX(canvas->pixmap_width, requisition->width),
2097 MAX(canvas->pixmap_height, requisition->height));
2098 }
2099
2100
2101 /**
2102 * gtk_plot_canvas_set_magnification:
2103 * @canvas: a #GtkPlotCanvas.
2104 * @magnification:
2105 *
2106 *
2107 */
2108 void
gtk_plot_canvas_set_magnification(GtkPlotCanvas * canvas,gdouble magnification)2109 gtk_plot_canvas_set_magnification(GtkPlotCanvas *canvas,
2110 gdouble magnification)
2111 {
2112 GList *list;
2113
2114 canvas->magnification = magnification;
2115
2116 list = canvas->childs;
2117 while(list){
2118 GtkPlotCanvasChild *child = GTK_PLOT_CANVAS_CHILD(list->data);
2119
2120 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->set_magnification)
2121 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->set_magnification(canvas, child, magnification);
2122
2123 list = list->next;
2124 }
2125
2126 gtk_plot_canvas_set_size(canvas,
2127 canvas->width,
2128 canvas->height);
2129 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2130 }
2131
2132 static void
gtk_plot_canvas_child_draw_selection(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,GtkAllocation area)2133 gtk_plot_canvas_child_draw_selection(GtkPlotCanvas *canvas, GtkPlotCanvasChild *child, GtkAllocation area)
2134 {
2135 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->draw_selection)
2136 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->draw_selection(canvas, child, area);
2137 }
2138
2139 static void
draw_selection(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,GtkAllocation area)2140 draw_selection(GtkPlotCanvas *canvas, GtkPlotCanvasChild *child, GtkAllocation area)
2141 {
2142 GdkGC *xor_gc = NULL;
2143 GdkGCValues values;
2144
2145 gdk_gc_get_values(gtk_widget_get_style(GTK_WIDGET(canvas))->fg_gc[0], &values);
2146 values.function = GDK_INVERT;
2147 values.foreground = gtk_widget_get_style(GTK_WIDGET(canvas))->white;
2148 values.subwindow_mode = GDK_INCLUDE_INFERIORS;
2149 xor_gc = gdk_gc_new_with_values(gtk_widget_get_window(GTK_WIDGET(canvas)),
2150 &values,
2151 GDK_GC_FOREGROUND |
2152 GDK_GC_FUNCTION |
2153 GDK_GC_SUBWINDOW);
2154
2155 if(canvas->active_item){
2156 if(canvas->active_item->selection == GTK_PLOT_CANVAS_SELECT_TARGET){
2157 area.x += area.width / 2 - 10;
2158 area.y += area.height / 2 - 10;
2159 area.width = 20;
2160 area.height = 20;
2161 gdk_draw_rectangle (gtk_widget_get_window(GTK_WIDGET(canvas)),
2162 xor_gc,
2163 FALSE,
2164 area.x, area.y,
2165 area.width, area.height);
2166
2167 gdk_draw_line(gtk_widget_get_window(GTK_WIDGET(canvas)), xor_gc,
2168 area.x + 1, area.y + area.height/2,
2169 area.x + 6, area.y + area.height/2);
2170 gdk_draw_line(gtk_widget_get_window(GTK_WIDGET(canvas)), xor_gc,
2171 area.x + area.width - 1, area.y + area.height / 2,
2172 area.x + area.width - 6, area.y + area.height / 2);
2173 gdk_draw_line(gtk_widget_get_window(GTK_WIDGET(canvas)), xor_gc,
2174 area.x + area.width/2, area.y + 1,
2175 area.x + area.width/2, area.y + 6);
2176 gdk_draw_line(gtk_widget_get_window(GTK_WIDGET(canvas)), xor_gc,
2177 area.x + area.width/2, area.y + area.height - 1,
2178 area.x + area.width/2, area.y + area.height - 6);
2179
2180 if(xor_gc) gdk_gc_destroy(xor_gc);
2181 return;
2182 }
2183
2184
2185 if(canvas->active_item->selection == GTK_PLOT_CANVAS_SELECT_MARKERS){
2186 gdk_draw_rectangle (gtk_widget_get_window(GTK_WIDGET(canvas)),
2187 xor_gc,
2188 FALSE,
2189 area.x, area.y,
2190 area.width, area.height);
2191 draw_marker(canvas, xor_gc, area.x, area.y);
2192 draw_marker(canvas, xor_gc, area.x, area.y + area.height);
2193 draw_marker(canvas, xor_gc, area.x + area.width, area.y);
2194 draw_marker(canvas, xor_gc, area.x + area.width, area.y + area.height);
2195 if(area.height > DEFAULT_MARKER_SIZE * 2){
2196 draw_marker(canvas, xor_gc, area.x, area.y + area.height / 2);
2197 draw_marker(canvas, xor_gc, area.x + area.width,
2198 area.y + area.height / 2);
2199 }
2200 if(area.width > DEFAULT_MARKER_SIZE * 2){
2201 draw_marker(canvas, xor_gc, area.x + area.width / 2, area.y);
2202 draw_marker(canvas, xor_gc, area.x + area.width / 2,
2203 area.y + area.height);
2204 }
2205 }
2206 } else {
2207 gdk_gc_set_line_attributes(xor_gc, 1, 1, 0 ,0 );
2208
2209 gdk_draw_rectangle (gtk_widget_get_window(GTK_WIDGET(canvas)),
2210 xor_gc,
2211 FALSE,
2212 area.x, area.y,
2213 area.width, area.height);
2214 }
2215 if(xor_gc) gdk_gc_unref(xor_gc);
2216 }
2217
2218 static void
draw_marker(GtkPlotCanvas * canvas,GdkGC * gc,gint x,gint y)2219 draw_marker(GtkPlotCanvas *canvas, GdkGC *gc, gint x, gint y)
2220 {
2221 GdkDrawable *darea;
2222
2223 darea = gtk_widget_get_window(GTK_WIDGET(canvas));
2224
2225 gdk_draw_rectangle(darea, gc, TRUE,
2226 x - DEFAULT_MARKER_SIZE / 2, y - DEFAULT_MARKER_SIZE / 2,
2227 DEFAULT_MARKER_SIZE + 1, DEFAULT_MARKER_SIZE + 1);
2228 }
2229
2230 /* FIXME:: Is this private or public */
2231 GtkPlotCanvasPos
possible_selection(GtkAllocation area,gint x,gint y)2232 possible_selection(GtkAllocation area, gint x, gint y)
2233 {
2234 GtkPlotCanvasPos return_value = GTK_PLOT_CANVAS_OUT;
2235
2236 if(x >= area.x - DEFAULT_MARKER_SIZE / 2 &&
2237 x <= area.x + DEFAULT_MARKER_SIZE / 2){
2238 if(y >= area.y - DEFAULT_MARKER_SIZE / 2. &&
2239 y <= area.y + DEFAULT_MARKER_SIZE / 2.)
2240 return_value = GTK_PLOT_CANVAS_TOP_LEFT;
2241 if(y >= area.y + area.height - DEFAULT_MARKER_SIZE / 2. &&
2242 y <= area.y + area.height + DEFAULT_MARKER_SIZE / 2.)
2243 return_value = GTK_PLOT_CANVAS_BOTTOM_LEFT;
2244 if(y >= area.y + area.height / 2 - DEFAULT_MARKER_SIZE / 2. &&
2245 y <= area.y + area.height / 2 + DEFAULT_MARKER_SIZE / 2. &&
2246 area.height > DEFAULT_MARKER_SIZE * 2)
2247 return_value = GTK_PLOT_CANVAS_LEFT;
2248 }
2249
2250 if(x >= area.x + area.width - DEFAULT_MARKER_SIZE / 2 &&
2251 x <= area.x + area.width + DEFAULT_MARKER_SIZE / 2){
2252 if(y >= area.y - DEFAULT_MARKER_SIZE / 2. &&
2253 y <= area.y + DEFAULT_MARKER_SIZE / 2.)
2254 return_value = GTK_PLOT_CANVAS_TOP_RIGHT;
2255 if(y >= area.y + area.height - DEFAULT_MARKER_SIZE / 2. &&
2256 y <= area.y + area.height + DEFAULT_MARKER_SIZE / 2.)
2257 return_value = GTK_PLOT_CANVAS_BOTTOM_RIGHT;
2258 if(y >= area.y + area.height / 2 - DEFAULT_MARKER_SIZE / 2. &&
2259 y <= area.y + area.height / 2 + DEFAULT_MARKER_SIZE / 2. &&
2260 area.height > DEFAULT_MARKER_SIZE * 2)
2261 return_value = GTK_PLOT_CANVAS_RIGHT;
2262 }
2263
2264 if(x >= area.x + area.width / 2 - DEFAULT_MARKER_SIZE / 2 &&
2265 x <= area.x + area.width / 2 + DEFAULT_MARKER_SIZE / 2 &&
2266 area.width > DEFAULT_MARKER_SIZE * 2){
2267 if(y >= area.y - DEFAULT_MARKER_SIZE / 2. &&
2268 y <= area.y + DEFAULT_MARKER_SIZE / 2.)
2269 return_value = GTK_PLOT_CANVAS_TOP;
2270 if(y >= area.y + area.height - DEFAULT_MARKER_SIZE / 2. &&
2271 y <= area.y + area.height + DEFAULT_MARKER_SIZE / 2.)
2272 return_value = GTK_PLOT_CANVAS_BOTTOM;
2273 }
2274
2275 if(return_value == GTK_PLOT_CANVAS_OUT){
2276 if (x >= area.x && x <= area.x + area.width &&
2277 y >= area.y && y <= area.y + area.height)
2278 return_value = GTK_PLOT_CANVAS_IN;
2279 }
2280
2281 return (return_value);
2282 }
2283
2284 /**********************************************************************/
2285
2286 /**
2287 * gtk_plot_canvas_grid_set_visible:
2288 * @canvas: a #GtkPlotCanvas.
2289 * @visible:
2290 *
2291 *
2292 */
2293 void
gtk_plot_canvas_grid_set_visible(GtkPlotCanvas * canvas,gboolean visible)2294 gtk_plot_canvas_grid_set_visible(GtkPlotCanvas *canvas, gboolean visible)
2295 {
2296 canvas->show_grid= visible;
2297 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2298 }
2299
2300 /**
2301 * gtk_plot_canvas_grid_set_step:
2302 * @canvas: a #GtkPlotCanvas.
2303 * @step:
2304 *
2305 *
2306 */
2307 void
gtk_plot_canvas_grid_set_step(GtkPlotCanvas * canvas,gdouble step)2308 gtk_plot_canvas_grid_set_step(GtkPlotCanvas *canvas, gdouble step)
2309 {
2310 canvas->grid_step = step;
2311 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2312 }
2313
2314 /**
2315 * gtk_plot_canvas_grid_set_attributes:
2316 * @canvas: a #GtkPlotCanvas.
2317 * @style:
2318 * @width:
2319 * @color:
2320 *
2321 *
2322 */
2323 void
gtk_plot_canvas_grid_set_attributes(GtkPlotCanvas * canvas,GtkPlotLineStyle style,gint width,const GdkColor * color)2324 gtk_plot_canvas_grid_set_attributes(GtkPlotCanvas *canvas,
2325 GtkPlotLineStyle style,
2326 gint width,
2327 const GdkColor *color)
2328 {
2329 if(color)
2330 canvas->grid.color = *color;
2331 canvas->grid.line_width = width;
2332 canvas->grid.line_style = style;
2333 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2334 }
2335
2336 /**********************************************************************/
2337
2338 /**
2339 * gtk_plot_canvas_put_child:
2340 * @canvas: a #GtkPlotCanvas.
2341 * @x1:
2342 * @y1:
2343 * @x2:
2344 * @y2:
2345 *
2346 *
2347 */
2348 void
gtk_plot_canvas_put_child(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x1,gdouble y1,gdouble x2,gdouble y2)2349 gtk_plot_canvas_put_child(GtkPlotCanvas *canvas,
2350 GtkPlotCanvasChild *child,
2351 gdouble x1, gdouble y1,
2352 gdouble x2, gdouble y2)
2353 {
2354 child->rx1 = x1;
2355 child->ry1 = y1;
2356 child->rx2 = x2;
2357 child->ry2 = y2;
2358
2359 child->parent = canvas;
2360 canvas->childs = g_list_append(canvas->childs, child);
2361 g_object_ref(GTK_OBJECT(child));
2362 gtk_object_sink(GTK_OBJECT(child));
2363
2364 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate)
2365 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate(canvas, child);
2366 if(gtk_widget_get_realized(GTK_WIDGET(canvas)) &&
2367 gtk_widget_get_visible(GTK_WIDGET(canvas)))
2368 gtk_plot_canvas_child_draw(canvas, child);
2369 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2370 g_signal_emit(GTK_OBJECT(canvas), canvas_signals[ADD_ITEM], 0, child);
2371 }
2372
2373 /**
2374 * gtk_plot_canvas_child_move:
2375 * @canvas: a #GtkPlotCanvas.
2376 * @child: a #GtkPlotCanvasChild
2377 * @x1:
2378 * @y1:
2379 *
2380 *
2381 */
2382 void
gtk_plot_canvas_child_move(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x1,gdouble y1)2383 gtk_plot_canvas_child_move(GtkPlotCanvas *canvas,
2384 GtkPlotCanvasChild *child,
2385 gdouble x1, gdouble y1)
2386 {
2387 child->rx2 += (x1 - child->rx1);
2388 child->ry2 += (y1 - child->ry1);
2389 child->rx1 = x1;
2390 child->ry1 = y1;
2391
2392 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->move)
2393 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->move(canvas, child, x1, y1);
2394 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate(canvas, child);
2395 gtk_plot_canvas_paint(canvas);
2396 gtk_plot_canvas_refresh(canvas);
2397 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2398 }
2399
2400 /**
2401 * gtk_plot_canvas_child_move_resize:
2402 * @canvas: a #GtkPlotCanvas.
2403 * @x1:
2404 * @y1:
2405 * @x2:
2406 * @y2:
2407 *
2408 *
2409 */
2410 void
gtk_plot_canvas_child_move_resize(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child,gdouble x1,gdouble y1,gdouble x2,gdouble y2)2411 gtk_plot_canvas_child_move_resize(GtkPlotCanvas *canvas,
2412 GtkPlotCanvasChild *child,
2413 gdouble x1, gdouble y1,
2414 gdouble x2, gdouble y2)
2415 {
2416 child->rx1 = x1;
2417 child->ry1 = y1;
2418 child->rx2 = x2;
2419 child->ry2 = y2;
2420
2421 if(GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->move_resize)
2422 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->move_resize(canvas, child, x1, y1, x2, y2);
2423 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->size_allocate(canvas, child);
2424 gtk_plot_canvas_paint(canvas);
2425 gtk_plot_canvas_refresh(canvas);
2426 g_signal_emit (GTK_OBJECT(canvas), canvas_signals[CHANGED], 0);
2427 }
2428
2429 static void
gtk_plot_canvas_child_size_allocate(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)2430 gtk_plot_canvas_child_size_allocate(GtkPlotCanvas *canvas, GtkPlotCanvasChild *child)
2431 {
2432 gint x1, x2, y1, y2;
2433
2434 gtk_plot_canvas_get_pixel(canvas, child->rx1, child->ry1, &x1, &y1);
2435 gtk_plot_canvas_get_pixel(canvas, child->rx2, child->ry2, &x2, &y2);
2436 child->allocation.x = MIN(x1, x2);
2437 child->allocation.y = MIN(y1, y2);
2438 child->allocation.width = abs(x1 - x2);
2439 child->allocation.height = abs(y1 - y2);
2440 }
2441
2442 /**
2443 * gtk_plot_canvas_set_selection:
2444 * @child: a #GtkPlotCanvasChild.
2445 * @selection: a #GtkPlotCanvasSelection
2446 *
2447 *
2448 */
2449 void
gtk_plot_canvas_child_set_selection(GtkPlotCanvasChild * child,GtkPlotCanvasSelection selection)2450 gtk_plot_canvas_child_set_selection (GtkPlotCanvasChild *child,
2451 GtkPlotCanvasSelection selection)
2452 {
2453 if(!child) return;
2454 child->selection = selection;
2455 }
2456
2457 /**
2458 * gtk_plot_canvas_child_set_selection_mode:
2459 * @child: a #GtkPlotCanvasChild.
2460 * @mode:
2461 *
2462 *
2463 */
2464 void
gtk_plot_canvas_child_set_selection_mode(GtkPlotCanvasChild * child,GtkPlotCanvasSelectionMode mode)2465 gtk_plot_canvas_child_set_selection_mode (GtkPlotCanvasChild *child,
2466 GtkPlotCanvasSelectionMode mode)
2467 {
2468 if(!child) return;
2469 child->mode = mode;
2470 }
2471
2472 /**
2473 * gtk_plot_canvas_child_draw:
2474 * @canvas: a #GtkPlotCanvas.
2475 * @child: a #GtkPlotCanvasChild.
2476 *
2477 *
2478 */
2479 void
gtk_plot_canvas_child_draw(GtkPlotCanvas * canvas,GtkPlotCanvasChild * child)2480 gtk_plot_canvas_child_draw(GtkPlotCanvas *canvas,
2481 GtkPlotCanvasChild *child)
2482 {
2483 gtk_plot_pc_gsave(canvas->pc);
2484
2485 GTK_PLOT_CANVAS_CHILD_CLASS(GTK_OBJECT_GET_CLASS(GTK_OBJECT(child)))->draw(canvas, child);
2486
2487 gtk_plot_pc_grestore(canvas->pc);
2488 }
2489
2490 /**
2491 * gtk_plot_canvas_set_line_attributes:
2492 * @canvas: a #GtkPlotCanvas.
2493 * @line:
2494 *
2495 *
2496 */
2497 void
gtk_plot_canvas_set_line_attributes(GtkPlotCanvas * canvas,GtkPlotLine line)2498 gtk_plot_canvas_set_line_attributes(GtkPlotCanvas *canvas, GtkPlotLine line)
2499 {
2500 gdouble dot[] = {2., 3.};
2501 gdouble dash[] = {6., 4.};
2502 gdouble dot_dash[] = {6., 4., 2., 4.};
2503 gdouble dot_dot_dash[] = {6., 4., 2., 4., 2., 4.};
2504 gdouble dot_dash_dash[] = {6., 4., 6., 4., 2., 4.};
2505
2506 gtk_plot_pc_set_color(canvas->pc, &line.color);
2507
2508 switch(line.line_style){
2509 case GTK_PLOT_LINE_SOLID:
2510 gtk_plot_pc_set_lineattr(canvas->pc, line.line_width, 0, 0, 0);
2511 break;
2512 case GTK_PLOT_LINE_DOTTED:
2513 gtk_plot_pc_set_lineattr(canvas->pc, line.line_width,
2514 GDK_LINE_ON_OFF_DASH, 0, 0);
2515 gtk_plot_pc_set_dash(canvas->pc, 0, dot, 2);
2516 break;
2517 case GTK_PLOT_LINE_DASHED:
2518 gtk_plot_pc_set_lineattr(canvas->pc, line.line_width,
2519 GDK_LINE_ON_OFF_DASH, 0, 0);
2520 gtk_plot_pc_set_dash(canvas->pc, 0, dash, 2);
2521 case GTK_PLOT_LINE_DOT_DASH:
2522 gtk_plot_pc_set_lineattr(canvas->pc, line.line_width,
2523 GDK_LINE_ON_OFF_DASH, 0, 0);
2524 gtk_plot_pc_set_dash(canvas->pc, 0, dot_dash, 4);
2525 break;
2526 case GTK_PLOT_LINE_DOT_DOT_DASH:
2527 gtk_plot_pc_set_lineattr(canvas->pc, line.line_width,
2528 GDK_LINE_ON_OFF_DASH, 0, 0);
2529 gtk_plot_pc_set_dash(canvas->pc, 0, dot_dot_dash, 6);
2530 break;
2531 case GTK_PLOT_LINE_DOT_DASH_DASH:
2532 gtk_plot_pc_set_lineattr(canvas->pc, line.line_width,
2533 GDK_LINE_ON_OFF_DASH, 0, 0);
2534 gtk_plot_pc_set_dash(canvas->pc, 0, dot_dash_dash, 6);
2535 break;
2536 case GTK_PLOT_LINE_NONE:
2537 default:
2538 break;
2539 }
2540 }
2541