1 /*
2 * GooCanvas Demo. Copyright (C) 2005 Damon Chaplin.
3 * Released under the GNU LGPL license. See COPYING for details.
4 *
5 * main.c - demo app.
6 */
7 #include <config.h>
8 #include <math.h>
9 #include <string.h>
10 #include <stdlib.h>
11 #include <glib/gi18n.h>
12 #include <gtk/gtk.h>
13 #include <cairo.h>
14 #if CAIRO_HAS_PDF_SURFACE
15 #include <cairo-pdf.h>
16 #endif
17 #include <goocanvas.h>
18 #include "demo-item.h"
19
20 static GooCanvasItem *ellipse2, *textitem;
21
22 static gboolean dragging = FALSE;
23 static double drag_x, drag_y;
24
25 static void setup_canvas (GooCanvas *canvas);
26 GtkWidget *create_canvas_fifteen (void);
27 GtkWidget *create_canvas_features (void);
28 GtkWidget *create_canvas_arrowhead (void);
29 GtkWidget *create_canvas_scalability (void);
30 GtkWidget *create_grabs_page (void);
31 GtkWidget *create_events_page (void);
32 GtkWidget *create_paths_page (void);
33 GtkWidget *create_focus_page (void);
34 GtkWidget *create_animation_page (void);
35 GtkWidget *create_clipping_page (void);
36 GtkWidget *create_table_page (void);
37 GtkWidget *create_large_items_page (void);
38
39 #if CAIRO_HAS_PDF_SURFACE
40 static void
write_pdf_clicked(GtkWidget * button,GooCanvas * canvas)41 write_pdf_clicked (GtkWidget *button, GooCanvas *canvas)
42 {
43 cairo_surface_t *surface;
44 GooCanvasBounds bounds G_GNUC_UNUSED;
45 cairo_t *cr;
46
47 g_print ("In write_pdf_clicked\n");
48
49 surface = cairo_pdf_surface_create ("demo.pdf", 9 * 72, 10 * 72);
50 cr = cairo_create (surface);
51
52 /* Place it in the middle of our 9x10 page. */
53 cairo_translate (cr, 20, 130);
54
55 bounds.x1 = 100;
56 bounds.y1 = 100;
57 bounds.x2 = 300;
58 bounds.y2 = 300;
59
60 #if 1
61 goo_canvas_render (canvas, cr, NULL, 1.0);
62 #else
63 goo_canvas_render (canvas, cr, &bounds, 1.0);
64 #endif
65
66 cairo_show_page (cr);
67
68 cairo_surface_destroy (surface);
69 cairo_destroy (cr);
70 }
71 #endif
72
73 static void
zoom_changed(GtkAdjustment * adj,GooCanvas * canvas)74 zoom_changed (GtkAdjustment *adj, GooCanvas *canvas)
75 {
76 goo_canvas_set_scale (canvas, gtk_adjustment_get_value (adj));
77 }
78
79
80 static void
zoom_x_changed(GtkAdjustment * adj,GooCanvas * canvas)81 zoom_x_changed (GtkAdjustment *adj, GooCanvas *canvas)
82 {
83 g_object_set (G_OBJECT (canvas),
84 "scale-x", gtk_adjustment_get_value (adj),
85 NULL);
86 }
87
88
89 static void
zoom_y_changed(GtkAdjustment * adj,GooCanvas * canvas)90 zoom_y_changed (GtkAdjustment *adj, GooCanvas *canvas)
91 {
92 g_object_set (G_OBJECT (canvas),
93 "scale-y", gtk_adjustment_get_value (adj),
94 NULL);
95 }
96
97
98 static void
center_toggled(GtkToggleButton * button,gpointer data)99 center_toggled (GtkToggleButton *button, gpointer data)
100 {
101 /*foo_canvas_set_center_scroll_region (data,
102 gtk_toggle_button_get_active (button));*/
103 }
104
105
106 static void
anchor_toggled(GtkWidget * button,GooCanvas * canvas)107 anchor_toggled (GtkWidget *button, GooCanvas *canvas)
108 {
109 GooCanvasAnchorType anchor;
110
111 anchor = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (button), "anchor"));
112
113 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (button)))
114 g_object_set (canvas, "anchor", anchor, NULL);
115 }
116
117
118 static void
scroll_to_50_50_clicked(GtkWidget * button,GooCanvas * canvas)119 scroll_to_50_50_clicked (GtkWidget *button, GooCanvas *canvas)
120 {
121 goo_canvas_scroll_to (canvas, 50, 50);
122 }
123
124
125 static void
scroll_to_500_500_clicked(GtkWidget * button,GooCanvas * canvas)126 scroll_to_500_500_clicked (GtkWidget *button, GooCanvas *canvas)
127 {
128 goo_canvas_scroll_to (canvas, 500, 500);
129 }
130
131
132 static void
scroll_to_250_250_clicked(GtkWidget * button,GooCanvas * canvas)133 scroll_to_250_250_clicked (GtkWidget *button, GooCanvas *canvas)
134 {
135 goo_canvas_scroll_to (canvas, 250, 250);
136 }
137
138
139 static void
animate_ellipse_clicked(GtkWidget * button,GooCanvas * canvas)140 animate_ellipse_clicked (GtkWidget *button, GooCanvas *canvas)
141 {
142 #if 1
143 goo_canvas_item_animate (ellipse2, 100, 100, 1, 90, TRUE, 1000, 40,
144 GOO_CANVAS_ANIMATE_BOUNCE);
145 #endif
146 #if 0
147 goo_canvas_item_animate (textitem, -300, -200, 1, 90, TRUE, 1000, 40,
148 GOO_CANVAS_ANIMATE_BOUNCE);
149 #endif
150 }
151
152
153 static void
stop_animation_clicked(GtkWidget * button,GooCanvas * canvas)154 stop_animation_clicked (GtkWidget *button, GooCanvas *canvas)
155 {
156 goo_canvas_item_stop_animation (ellipse2);
157 }
158
159
160 static void
change_bounds_clicked(GtkWidget * button,GooCanvas * canvas)161 change_bounds_clicked (GtkWidget *button, GooCanvas *canvas)
162 {
163 static gdouble bounds[4][4] = {
164 { -100, -100, 200, 200 },
165 { 100, 100, 200, 200 },
166 { 0, 0, 300, 300 },
167 { 0, 0, 604, 454 }
168 };
169 static gint bounds_num = 0;
170
171 gboolean automatic_bounds = TRUE;
172 gboolean bounds_from_origin = FALSE;
173 gdouble bounds_padding = 50.0;
174
175 if (bounds_num < 4)
176 {
177 automatic_bounds = FALSE;
178 goo_canvas_set_bounds (canvas,
179 bounds[bounds_num][0], bounds[bounds_num][1],
180 bounds[bounds_num][2], bounds[bounds_num][3]);
181 }
182 else if (bounds_num == 4)
183 {
184 bounds_from_origin = TRUE;
185 bounds_padding = 50.0;
186 }
187
188 g_object_set (G_OBJECT (canvas),
189 "automatic-bounds", automatic_bounds,
190 "bounds-from-origin", bounds_from_origin,
191 "bounds-padding", bounds_padding,
192 NULL);
193
194 bounds_num = (bounds_num + 1) % 6;
195 }
196
197
198 static void
move_ellipse_clicked(GtkWidget * button,GooCanvas * canvas)199 move_ellipse_clicked (GtkWidget *button, GooCanvas *canvas)
200 {
201 static int last_state = 0;
202
203 #if 0
204 g_print ("Moving ellipse\n");
205 #endif
206
207 goo_canvas_item_set_transform (ellipse2, NULL);
208
209 if (last_state == 0)
210 {
211 g_object_set (ellipse2,
212 "center-x", 300.0,
213 "center-y", 70.0,
214 "radius-x", 45.0,
215 "radius-y", 30.0,
216 "fill-color", "red",
217 "stroke-color", "midnightblue",
218 "line-width", 4.0,
219 "title", "A red ellipse",
220 NULL);
221 last_state = 1;
222 }
223 else if (last_state == 1)
224 {
225 g_object_set (ellipse2,
226 "center-x", 390.0,
227 "center-y", 150.0,
228 "radius-x", 45.0,
229 "radius-y", 40.0,
230 "fill-pattern", NULL,
231 "stroke-color", "midnightblue",
232 "line-width", 4.0,
233 "title", "A brown ellipse",
234 NULL);
235 last_state = 2;
236 }
237 else if (last_state == 2)
238 {
239 g_object_set (ellipse2,
240 "center-x", 0.0,
241 "center-y", 0.0,
242 "radius-y", 30.0,
243 NULL);
244 goo_canvas_item_set_simple_transform (ellipse2, 100, 100, 1, 0);
245 last_state = 3;
246 }
247 else if (last_state == 3)
248 {
249 goo_canvas_item_set_simple_transform (ellipse2, 200, 100, 2, 0);
250 last_state = 4;
251 }
252 else if (last_state == 4)
253 {
254 goo_canvas_item_set_simple_transform (ellipse2, 200, 200, 1, 45);
255 last_state = 5;
256 }
257 else if (last_state == 5)
258 {
259 goo_canvas_item_set_simple_transform (ellipse2, 50, 50, 0.2, 225);
260 last_state = 6;
261 }
262 else
263 {
264 g_object_set (ellipse2,
265 "center-x", 335.0,
266 "center-y", 70.0,
267 "radius-x", 45.0,
268 "radius-y", 30.0,
269 "fill-color", "purple",
270 "stroke-color", "midnightblue",
271 "line-width", 4.0,
272 "title", "A purple ellipse",
273 NULL);
274 last_state = 0;
275 }
276 }
277
278
279 static gboolean
on_motion_notify(GooCanvasItem * item,GooCanvasItem * target,GdkEventMotion * event,gpointer data)280 on_motion_notify (GooCanvasItem *item,
281 GooCanvasItem *target,
282 GdkEventMotion *event,
283 gpointer data)
284 {
285 #if 0
286 g_print ("received 'motion-notify' signal at %g, %g\n",
287 event->x, event->y);
288 #endif
289
290 if (dragging && (event->state & GDK_BUTTON1_MASK))
291 {
292 double new_x = event->x;
293 double new_y = event->y;
294
295 goo_canvas_item_translate (item, new_x - drag_x, new_y - drag_y);
296 }
297
298 return TRUE;
299 }
300
301
302 static void
output_items_in_area(GooCanvas * canvas,gdouble x,gdouble y)303 output_items_in_area (GooCanvas *canvas,
304 gdouble x,
305 gdouble y)
306 {
307 static gdouble last_x = 0.0, last_y = 0.0;
308 GooCanvasBounds area;
309 GList *items, *elem;
310
311 /* Print out the items from the last point to this one. */
312 area.x1 = MIN (x, last_x);
313 area.x2 = MAX (x, last_x);
314 area.y1 = MIN (y, last_y);
315 area.y2 = MAX (y, last_y);
316 items = goo_canvas_get_items_in_area (canvas, &area, TRUE, FALSE, FALSE);
317 for (elem = items; elem; elem = elem->next)
318 {
319 g_print (" found items in area (%g, %g - %g, %g): %p\n",
320 area.x1, area.y1, area.x2, area.y2, elem->data);
321 }
322 g_list_free (items);
323 last_x = x;
324 last_y = y;
325 }
326
327
328 static gboolean
on_button_press(GooCanvasItem * item,GooCanvasItem * target,GdkEventButton * event,gpointer data)329 on_button_press (GooCanvasItem *item,
330 GooCanvasItem *target,
331 GdkEventButton *event,
332 gpointer data)
333 {
334 GooCanvas *canvas;
335 GdkDisplay *display;
336 GdkCursor *fleur;
337 GList *items, *elem;
338
339 g_print ("%p received 'button-press' signal at %g, %g (root: %g, %g)\n",
340 item, event->x, event->y, event->x_root, event->y_root);
341
342 canvas = goo_canvas_item_get_canvas (item);
343 items = goo_canvas_get_items_at (canvas, event->x_root, event->y_root,
344 TRUE);
345 for (elem = items; elem; elem = elem->next)
346 g_print (" found items: %p\n", elem->data);
347 g_list_free (items);
348
349 output_items_in_area (canvas, event->x_root, event->y_root);
350
351 switch (event->button)
352 {
353 case 1:
354 if (event->state & GDK_SHIFT_MASK)
355 {
356 goo_canvas_item_remove (item);
357 }
358 else
359 {
360 drag_x = event->x;
361 drag_y = event->y;
362
363 display = gtk_widget_get_display (GTK_WIDGET (canvas));
364 fleur = gdk_cursor_new_for_display (display, GDK_FLEUR);
365 goo_canvas_pointer_grab (canvas, item,
366 GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK,
367 fleur,
368 event->time);
369 g_object_unref (fleur);
370 dragging = TRUE;
371 }
372 break;
373
374 case 2:
375 goo_canvas_item_lower (item, NULL);
376 break;
377
378 case 3:
379 goo_canvas_item_raise (item, NULL);
380 break;
381
382 default:
383 break;
384 }
385
386 return TRUE;
387 }
388
389
390 static gboolean
on_scroll(GooCanvasItem * item,GooCanvasItem * target,GdkEventScroll * event,gpointer data)391 on_scroll (GooCanvasItem *item,
392 GooCanvasItem *target,
393 GdkEventScroll *event,
394 gpointer data)
395 {
396 #if 0
397 g_print ("received 'scroll-event' signal\n");
398 #endif
399
400 if (event->direction == GDK_SCROLL_UP)
401 goo_canvas_item_scale (item, 1.1, 1.1);
402 else if (event->direction == GDK_SCROLL_DOWN)
403 goo_canvas_item_scale (item, 0.909, 0.909);
404 else return FALSE;
405
406 return TRUE;
407 }
408
409 static gboolean
on_button_release(GooCanvasItem * item,GooCanvasItem * target,GdkEventButton * event,gpointer data)410 on_button_release (GooCanvasItem *item,
411 GooCanvasItem *target,
412 GdkEventButton *event,
413 gpointer data)
414 {
415 GooCanvas *canvas;
416
417 #if 0
418 g_print ("received 'button-release' signal\n");
419 #endif
420
421 canvas = goo_canvas_item_get_canvas (item);
422 goo_canvas_pointer_ungrab (canvas, item, event->time);
423 dragging = FALSE;
424
425 return TRUE;
426 }
427
428 static gboolean
on_background_button_press(GooCanvasItem * item,GooCanvasItem * target,GdkEventButton * event,gpointer data)429 on_background_button_press (GooCanvasItem *item,
430 GooCanvasItem *target,
431 GdkEventButton *event,
432 gpointer data)
433 {
434 GooCanvas *canvas;
435 GList *items, *elem;
436
437 #if 1
438 g_print ("background received 'button-press' signal\n");
439 #endif
440
441 canvas = goo_canvas_item_get_canvas (item);
442 output_items_in_area (canvas, event->x_root, event->y_root);
443
444 items = goo_canvas_get_items_at (canvas, event->x_root, event->y_root,
445 FALSE);
446 for (elem = items; elem; elem = elem->next)
447 g_print (" clicked items: %p\n", elem->data);
448 g_list_free (items);
449
450 return TRUE;
451 }
452
453
454 static void
setup_item_signals(GooCanvasItem * item)455 setup_item_signals (GooCanvasItem *item)
456 {
457 g_signal_connect (item, "motion_notify_event",
458 G_CALLBACK (on_motion_notify), NULL);
459 g_signal_connect (item, "button_press_event",
460 G_CALLBACK (on_button_press), NULL);
461 g_signal_connect (item, "button_release_event",
462 G_CALLBACK (on_button_release), NULL);
463 }
464
465
466 GtkWidget *
create_canvas_primitives()467 create_canvas_primitives ()
468 {
469 GtkWidget *vbox;
470 GtkWidget *hbox;
471 GtkWidget *w;
472 GtkWidget *scrolled_win, *canvas;
473 GtkAdjustment *adj;
474 GSList *group = NULL;
475
476 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 4);
477 gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
478 gtk_widget_show (vbox);
479
480 w = gtk_label_new ("Drag an item with button 1. Click button 2 on an item to lower it, or button 3 to raise it.");
481 gtk_box_pack_start (GTK_BOX (vbox), w, FALSE, FALSE, 0);
482 gtk_widget_show (w);
483
484 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
485 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
486 gtk_widget_show (hbox);
487
488 /* Create the canvas */
489
490 canvas = goo_canvas_new ();
491 g_object_set (G_OBJECT (canvas),
492 "automatic-bounds", TRUE,
493 "bounds-from-origin", FALSE,
494 "bounds-padding", 4.0,
495 "background-color-rgb", 0xC3C3FF,
496 "has-tooltip", TRUE,
497 #if 0
498 "redraw-when-scrolled", TRUE,
499 #endif
500 NULL);
501 goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 604, 454);
502
503 /* Scale */
504
505 w = gtk_label_new ("Scale:");
506 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
507 gtk_widget_show (w);
508
509 adj = GTK_ADJUSTMENT (gtk_adjustment_new (1.00, 0.05, 50.00, 0.05, 0.50, 0.50));
510 w = gtk_spin_button_new (adj, 0.0, 2);
511 g_signal_connect (adj, "value_changed",
512 G_CALLBACK (zoom_changed),
513 canvas);
514 gtk_widget_set_size_request (w, 50, -1);
515 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
516 gtk_widget_show (w);
517
518
519 w = gtk_label_new ("Scale X:");
520 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
521 gtk_widget_show (w);
522
523 adj = GTK_ADJUSTMENT (gtk_adjustment_new (1.00, 0.05, 50.00, 0.05, 0.50, 0.50));
524 w = gtk_spin_button_new (adj, 0.0, 2);
525 g_signal_connect (adj, "value_changed",
526 G_CALLBACK (zoom_x_changed),
527 canvas);
528 gtk_widget_set_size_request (w, 50, -1);
529 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
530 gtk_widget_show (w);
531
532
533 w = gtk_label_new ("Scale Y:");
534 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
535 gtk_widget_show (w);
536
537 adj = GTK_ADJUSTMENT (gtk_adjustment_new (1.00, 0.05, 50.00, 0.05, 0.50, 0.50));
538 w = gtk_spin_button_new (adj, 0.0, 2);
539 g_signal_connect (adj, "value_changed",
540 G_CALLBACK (zoom_y_changed),
541 canvas);
542 gtk_widget_set_size_request (w, 50, -1);
543 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
544 gtk_widget_show (w);
545
546
547 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
548 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
549 gtk_widget_show (hbox);
550
551 /* Center: */
552
553 w = gtk_check_button_new_with_label("Center scroll region");
554 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
555 /*gtk_widget_show (w);*/
556 g_signal_connect (w, "toggled",
557 G_CALLBACK (center_toggled),
558 canvas);
559
560 /* Move Ellipse */
561
562 w = gtk_button_new_with_label("Move Ellipse");
563 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
564 gtk_widget_show (w);
565 g_signal_connect (w, "clicked",
566 G_CALLBACK (move_ellipse_clicked),
567 canvas);
568
569 /* Animate Ellipse */
570
571 w = gtk_button_new_with_label("Animate Ellipse");
572 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
573 gtk_widget_show (w);
574 g_signal_connect (w, "clicked",
575 G_CALLBACK (animate_ellipse_clicked),
576 canvas);
577
578 /* Stop Animation */
579
580 w = gtk_button_new_with_label("Stop Animation");
581 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
582 gtk_widget_show (w);
583 g_signal_connect (w, "clicked",
584 G_CALLBACK (stop_animation_clicked),
585 canvas);
586
587
588 #if CAIRO_HAS_PDF_SURFACE
589 /* Create PDF */
590
591 w = gtk_button_new_with_label("Write PDF");
592 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
593 gtk_widget_show (w);
594 g_signal_connect (w, "clicked",
595 G_CALLBACK (write_pdf_clicked),
596 canvas);
597 #endif
598
599 w = gtk_button_new_with_label("Change Bounds");
600 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
601 gtk_widget_show (w);
602 g_signal_connect (w, "clicked",
603 G_CALLBACK (change_bounds_clicked),
604 canvas);
605
606 hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 4);
607 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
608 gtk_widget_show (hbox);
609
610 /* Scroll to */
611
612 w = gtk_label_new ("Scroll To:");
613 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
614 gtk_widget_show (w);
615
616 w = gtk_button_new_with_label("50,50");
617 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
618 gtk_widget_show (w);
619 g_signal_connect (w, "clicked",
620 G_CALLBACK (scroll_to_50_50_clicked),
621 canvas);
622
623 w = gtk_button_new_with_label("250,250");
624 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
625 gtk_widget_show (w);
626 g_signal_connect (w, "clicked",
627 G_CALLBACK (scroll_to_250_250_clicked),
628 canvas);
629
630 w = gtk_button_new_with_label("500,500");
631 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
632 gtk_widget_show (w);
633 g_signal_connect (w, "clicked",
634 G_CALLBACK (scroll_to_500_500_clicked),
635 canvas);
636
637 /* Scroll anchor */
638
639 w = gtk_label_new ("Anchor:");
640 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
641 gtk_widget_show (w);
642
643 w = gtk_radio_button_new_with_label (group, "NW");
644 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
645 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
646 gtk_widget_show (w);
647 g_signal_connect (w, "toggled",
648 G_CALLBACK (anchor_toggled),
649 canvas);
650 g_object_set_data (G_OBJECT (w), "anchor",
651 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_NW));
652
653 w = gtk_radio_button_new_with_label (group, "N");
654 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
655 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
656 gtk_widget_show (w);
657 g_signal_connect (w, "toggled",
658 G_CALLBACK (anchor_toggled),
659 canvas);
660 g_object_set_data (G_OBJECT (w), "anchor",
661 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_N));
662
663 w = gtk_radio_button_new_with_label (group, "NE");
664 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
665 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
666 gtk_widget_show (w);
667 g_signal_connect (w, "toggled",
668 G_CALLBACK (anchor_toggled),
669 canvas);
670 g_object_set_data (G_OBJECT (w), "anchor",
671 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_NE));
672
673 w = gtk_radio_button_new_with_label (group, "W");
674 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
675 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
676 gtk_widget_show (w);
677 g_signal_connect (w, "toggled",
678 G_CALLBACK (anchor_toggled),
679 canvas);
680 g_object_set_data (G_OBJECT (w), "anchor",
681 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_W));
682
683 w = gtk_radio_button_new_with_label (group, "C");
684 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
685 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
686 gtk_widget_show (w);
687 g_signal_connect (w, "toggled",
688 G_CALLBACK (anchor_toggled),
689 canvas);
690 g_object_set_data (G_OBJECT (w), "anchor",
691 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_CENTER));
692
693 w = gtk_radio_button_new_with_label (group, "E");
694 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
695 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
696 gtk_widget_show (w);
697 g_signal_connect (w, "toggled",
698 G_CALLBACK (anchor_toggled),
699 canvas);
700 g_object_set_data (G_OBJECT (w), "anchor",
701 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_E));
702
703 w = gtk_radio_button_new_with_label (group, "SW");
704 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
705 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
706 gtk_widget_show (w);
707 g_signal_connect (w, "toggled",
708 G_CALLBACK (anchor_toggled),
709 canvas);
710 g_object_set_data (G_OBJECT (w), "anchor",
711 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_SW));
712
713 w = gtk_radio_button_new_with_label (group, "S");
714 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
715 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
716 gtk_widget_show (w);
717 g_signal_connect (w, "toggled",
718 G_CALLBACK (anchor_toggled),
719 canvas);
720 g_object_set_data (G_OBJECT (w), "anchor",
721 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_S));
722
723 w = gtk_radio_button_new_with_label (group, "SE");
724 group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (w));
725 gtk_box_pack_start (GTK_BOX (hbox), w, FALSE, FALSE, 0);
726 gtk_widget_show (w);
727 g_signal_connect (w, "toggled",
728 G_CALLBACK (anchor_toggled),
729 canvas);
730 g_object_set_data (G_OBJECT (w), "anchor",
731 GINT_TO_POINTER (GOO_CANVAS_ANCHOR_SE));
732
733
734 /* Layout the stuff */
735
736 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
737 gtk_widget_show (scrolled_win);
738 gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
739
740 gtk_widget_show (canvas);
741 gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);
742
743 /* Add all the canvas items. */
744 setup_canvas (GOO_CANVAS (canvas));
745
746 #if 0
747 g_signal_connect_after (canvas, "key_press_event",
748 G_CALLBACK (key_press),
749 NULL);
750
751 GTK_WIDGET_SET_FLAGS (canvas, GTK_CAN_FOCUS);
752 gtk_widget_grab_focus (canvas);
753 #endif
754
755 return vbox;
756 }
757
758
759 static void
setup_heading(GooCanvasItem * root,char * text,int pos)760 setup_heading (GooCanvasItem *root, char *text, int pos)
761 {
762 double x = (pos % 3) * 200 + 100;
763 double y = (pos / 3) * 150 + 5;
764 GooCanvasItem *item;
765 PangoRectangle ink_rect, logical_rect;
766
767 item = goo_canvas_text_new (root, text, x, y, -1, GOO_CANVAS_ANCHOR_N,
768 "font", "Sans 12",
769 NULL);
770 goo_canvas_item_skew_y (item, 30, x, y);
771 /*goo_canvas_item_rotate (item, 30, x, y);*/
772
773 goo_canvas_text_get_natural_extents (GOO_CANVAS_TEXT (item),
774 &ink_rect, &logical_rect);
775 g_print ("Ink Extents: %i,%i %ix%i Logical: %i,%i %ix%i\n",
776 ink_rect.x, ink_rect.y, ink_rect.width, ink_rect.height,
777 logical_rect.x, logical_rect.y,
778 logical_rect.width, logical_rect.height);
779 }
780
781
782 static void
setup_divisions(GooCanvasItem * root)783 setup_divisions (GooCanvasItem *root)
784 {
785 GooCanvasItem *group, *item G_GNUC_UNUSED;
786
787 group = goo_canvas_group_new (root, NULL);
788 goo_canvas_item_translate (group, 2, 2);
789
790 item = goo_canvas_rect_new (group, 0, 0, 600, 450,
791 "line-width", 4.0,
792 NULL);
793
794 item = goo_canvas_polyline_new_line (group, 0, 150, 600, 150,
795 "line-width", 4.0,
796 NULL);
797
798 item = goo_canvas_polyline_new_line (group, 0, 300, 600, 300,
799 "line-width", 4.0,
800 NULL);
801
802 item = goo_canvas_polyline_new_line (group, 200, 0, 200, 450,
803 "line-width", 4.0,
804 NULL);
805
806 item = goo_canvas_polyline_new_line (group, 400, 0, 400, 450,
807 "line-width", 4.0,
808 NULL);
809
810 #if 1
811 setup_heading (group, "Rectangles", 0);
812 setup_heading (group, "Ellipses", 1);
813 setup_heading (group, "Texts", 2);
814 setup_heading (group, "Images", 3);
815 setup_heading (group, "Lines", 4);
816 /*setup_heading (group, "No Curves", 5);*/
817 /*setup_heading (group, "Arcs", 6);*/
818 setup_heading (group, "Polygons", 7);
819 /*setup_heading (group, "Widgets", 8);*/
820 #endif
821 }
822
823
824 /* FIXME: I think we may need to check byte order. */
825 static cairo_pattern_t*
create_stipple(const char * color_name,guchar stipple_data[16])826 create_stipple (const char *color_name, guchar stipple_data[16])
827 {
828 cairo_surface_t *surface;
829 cairo_pattern_t *pattern;
830 GdkRGBA color;
831
832 gdk_rgba_parse (&color, color_name);
833 stipple_data[2] = stipple_data[14] = color.red * 255;
834 stipple_data[1] = stipple_data[13] = color.green * 255;
835 stipple_data[0] = stipple_data[12] = color.blue * 255;
836 surface = cairo_image_surface_create_for_data (stipple_data,
837 CAIRO_FORMAT_ARGB32,
838 2, 2, 8);
839 pattern = cairo_pattern_create_for_surface (surface);
840 cairo_surface_destroy (surface);
841 cairo_pattern_set_extend (pattern, CAIRO_EXTEND_REPEAT);
842
843 return pattern;
844 }
845
846 static void
setup_rectangles(GooCanvasItem * root)847 setup_rectangles (GooCanvasItem *root)
848 {
849 GooCanvasItem *item;
850 cairo_pattern_t *pattern;
851 static guchar stipple_data[16] = {
852 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255
853 };
854 GooCanvasLineDash *dash;
855
856 item = goo_canvas_rect_new (root, 20, 30, 50, 30,
857 "stroke-color", "red",
858 "line-width", 8.0,
859 "tooltip", "Red stroked rectangle",
860 NULL);
861 setup_item_signals (item);
862
863 pattern = create_stipple ("mediumseagreen", stipple_data);
864 item = goo_canvas_rect_new (root, 90, 40, 90, 60,
865 "fill-pattern", pattern,
866 "stroke-color", "black",
867 "line-width", 4.0,
868 "tooltip", "Medium Sea Green stippled rectangle",
869 NULL);
870 cairo_pattern_destroy (pattern);
871 setup_item_signals (item);
872
873 item = goo_canvas_rect_new (root, 10, 80, 70, 60,
874 "fill-color", "steelblue",
875 /*"fill-pattern", NULL,*/
876 "tooltip", "Steel Blue rectangle",
877 NULL);
878 setup_item_signals (item);
879
880 dash = goo_canvas_line_dash_new (2, 5.0, 2.0);
881 goo_canvas_line_dash_set_offset (dash, 2.0);
882 item = goo_canvas_rect_new (root, 20, 90, 70, 60,
883 "fill-color-rgba", 0x3cb37180,
884 "line-dash", dash,
885 "stroke-color", "blue",
886 "line-width", 2.0,
887 "tooltip", "Partially transparent rectangle",
888 NULL);
889 goo_canvas_line_dash_unref (dash);
890 setup_item_signals (item);
891
892 item = goo_canvas_rect_new (root, 110, 80, 50, 30,
893 "radius-x", 20.0,
894 "radius-y", 10.0,
895 "stroke-color", "yellow",
896 "fill-color-rgba", 0x3cb3f180,
897 "tooltip", "Rectangle with rounded corners",
898 NULL);
899 setup_item_signals (item);
900
901 item = goo_demo_item_new (root, 30, 20, 50, 30,
902 "fill-color", "yellow",
903 "tooltip", "Yellow demo item",
904 NULL);
905 setup_item_signals (item);
906 }
907
908
909 static void
setup_ellipses(GooCanvasItem * root)910 setup_ellipses (GooCanvasItem *root)
911 {
912 GooCanvasItem *ellipse1, *ellipse3;
913 cairo_pattern_t *pattern;
914 static guchar stipple_data[16] = {
915 0, 0, 0, 255, 0, 0, 0, 0,
916 0, 0, 0, 0, 0, 0, 0, 255
917 };
918
919 #if 1
920 ellipse1 = goo_canvas_ellipse_new (root, 245, 45, 25, 15,
921 "stroke-color", "goldenrod",
922 "line-width", 8.0,
923 NULL);
924 setup_item_signals (ellipse1);
925 #endif
926
927 ellipse2 = goo_canvas_ellipse_new (root, 335, 70, 45, 30,
928 "fill-color", "wheat",
929 "stroke-color", "midnightblue",
930 "line-width", 4.0,
931 "title", "An ellipse",
932 NULL);
933 #if 0
934 goo_canvas_item_rotate (ellipse2, 30, 0, 0);
935 #endif
936 setup_item_signals (ellipse2);
937
938 #if 1
939 pattern = create_stipple ("cadetblue", stipple_data);
940 ellipse3 = goo_canvas_ellipse_new (root, 245, 110, 35, 30,
941 "fill-pattern", pattern,
942 "stroke-color", "black",
943 "line-width", 1.0,
944 NULL);
945 cairo_pattern_destroy (pattern);
946 setup_item_signals (ellipse3);
947 #endif
948 }
949
950
951 #define VERTICES 10
952 #define RADIUS 60.0
953
954 static void
polish_diamond(GooCanvasItem * root)955 polish_diamond (GooCanvasItem *root)
956 {
957 GooCanvasItem *group, *item G_GNUC_UNUSED;
958 int i, j;
959 double a, x1, y1, x2, y2;
960
961 group = goo_canvas_group_new (root,
962 "line-width", 1.0,
963 "line-cap", CAIRO_LINE_CAP_ROUND,
964 NULL);
965 goo_canvas_item_translate (group, 270, 230);
966 setup_item_signals (group);
967
968 for (i = 0; i < VERTICES; i++) {
969 a = 2.0 * M_PI * i / VERTICES;
970 x1 = RADIUS * cos (a);
971 y1 = RADIUS * sin (a);
972
973 for (j = i + 1; j < VERTICES; j++) {
974 a = 2.0 * M_PI * j / VERTICES;
975 x2 = RADIUS * cos (a);
976 y2 = RADIUS * sin (a);
977 item = goo_canvas_polyline_new_line (group, x1, y1, x2, y2, NULL);
978 }
979 }
980 }
981
982
983 #define SCALE 7.0
984
985 static void
make_hilbert(GooCanvasItem * root)986 make_hilbert (GooCanvasItem *root)
987 {
988 char hilbert[] = "urdrrulurulldluuruluurdrurddldrrruluurdrurddldrddlulldrdldrrurd";
989 char *c;
990 double *pp, *p;
991 GooCanvasItem *item;
992 GooCanvasPoints *points;
993 cairo_pattern_t *pattern;
994 static guchar stipple_data[16] = {
995 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255
996 };
997
998 points = goo_canvas_points_new (strlen (hilbert) + 1);
999 points->coords[0] = 340.0;
1000 points->coords[1] = 290.0;
1001
1002 pp = points->coords;
1003 for (c = hilbert, p = points->coords + 2; *c; c++, p += 2, pp += 2)
1004 switch (*c) {
1005 case 'u':
1006 p[0] = pp[0];
1007 p[1] = pp[1] - SCALE;
1008 break;
1009
1010 case 'd':
1011 p[0] = pp[0];
1012 p[1] = pp[1] + SCALE;
1013 break;
1014
1015 case 'l':
1016 p[0] = pp[0] - SCALE;
1017 p[1] = pp[1];
1018 break;
1019
1020 case 'r':
1021 p[0] = pp[0] + SCALE;
1022 p[1] = pp[1];
1023 break;
1024 }
1025
1026 pattern = create_stipple ("red", stipple_data);
1027 item = goo_canvas_polyline_new (root, FALSE, 0,
1028 "points", points,
1029 "line-width", 4.0,
1030 "stroke-pattern", pattern,
1031 "line-cap", CAIRO_LINE_CAP_SQUARE,
1032 "line-join", CAIRO_LINE_JOIN_MITER,
1033 NULL);
1034 cairo_pattern_destroy (pattern);
1035 setup_item_signals (item);
1036
1037 goo_canvas_points_unref (points);
1038 }
1039
1040 static void
setup_lines(GooCanvasItem * root)1041 setup_lines (GooCanvasItem *root)
1042 {
1043 GooCanvasItem *polyline1, *polyline2, *polyline3, *polyline4, *polyline5;
1044
1045 polish_diamond (root);
1046 make_hilbert (root);
1047
1048 /* Arrow tests */
1049
1050 polyline1 = goo_canvas_polyline_new (root, FALSE, 4,
1051 340.0, 170.0,
1052 340.0, 230.0,
1053 390.0, 230.0,
1054 390.0, 170.0,
1055 "stroke-color", "midnightblue",
1056 "line-width", 3.0,
1057 "start-arrow", TRUE,
1058 "end-arrow", TRUE,
1059 "arrow-tip-length", 3.0,
1060 "arrow-length", 4.0,
1061 "arrow-width", 3.5,
1062 NULL);
1063 setup_item_signals (polyline1);
1064
1065 polyline2 = goo_canvas_polyline_new (root, FALSE, 2,
1066 356.0, 180.0,
1067 374.0, 220.0,
1068 "stroke-color", "blue",
1069 "line-width", 1.0,
1070 "start-arrow", TRUE,
1071 "end-arrow", TRUE,
1072 "arrow-tip-length", 5.0,
1073 "arrow-length", 6.0,
1074 "arrow-width", 6.0,
1075 NULL);
1076 setup_item_signals (polyline2);
1077
1078 polyline3 = goo_canvas_polyline_new (root, FALSE, 2,
1079 356.0, 220.0,
1080 374.0, 180.0,
1081 "stroke-color", "blue",
1082 "line-width", 1.0,
1083 "start-arrow", TRUE,
1084 "end-arrow", TRUE,
1085 "arrow-tip-length", 5.0,
1086 "arrow-length", 6.0,
1087 "arrow-width", 6.0,
1088 NULL);
1089 setup_item_signals (polyline3);
1090
1091 /* Test polyline without any coords. */
1092 polyline4 = goo_canvas_polyline_new (root, FALSE, 0,
1093 NULL);
1094 setup_item_signals (polyline4);
1095
1096 /* Test polyline with 1 coord and arrows. */
1097 polyline5 = goo_canvas_polyline_new (root, FALSE, 1,
1098 356.0, 220.0,
1099 "start-arrow", TRUE,
1100 "end-arrow", TRUE,
1101 NULL);
1102 setup_item_signals (polyline5);
1103 }
1104
1105
1106 static void
setup_polygons(GooCanvasItem * root)1107 setup_polygons (GooCanvasItem *root)
1108 {
1109 GooCanvasItem *polyline1, *polyline2;
1110 GooCanvasPoints *points;
1111 cairo_pattern_t *pattern;
1112 static guchar stipple_data[16] = {
1113 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255
1114 };
1115
1116 points = goo_canvas_points_new (3);
1117 points->coords[0] = 210.0;
1118 points->coords[1] = 320.0;
1119 points->coords[2] = 210.0;
1120 points->coords[3] = 380.0;
1121 points->coords[4] = 260.0;
1122 points->coords[5] = 350.0;
1123 pattern = create_stipple ("blue", stipple_data);
1124 polyline1 = goo_canvas_polyline_new (root, TRUE, 0,
1125 "line-width", 1.0,
1126 "points", points,
1127 "fill_pattern", pattern,
1128 "stroke_color", "black",
1129 NULL);
1130 cairo_pattern_destroy (pattern);
1131 goo_canvas_points_unref (points);
1132 setup_item_signals (polyline1);
1133
1134
1135 points = goo_canvas_points_new (14);
1136 points->coords[0] = 270.0;
1137 points->coords[1] = 330.0;
1138 points->coords[2] = 270.0;
1139 points->coords[3] = 430.0;
1140 points->coords[4] = 390.0;
1141 points->coords[5] = 430.0;
1142 points->coords[6] = 390.0;
1143 points->coords[7] = 330.0;
1144 points->coords[8] = 310.0;
1145 points->coords[9] = 330.0;
1146 points->coords[10] = 310.0;
1147 points->coords[11] = 390.0;
1148 points->coords[12] = 350.0;
1149 points->coords[13] = 390.0;
1150 points->coords[14] = 350.0;
1151 points->coords[15] = 370.0;
1152 points->coords[16] = 330.0;
1153 points->coords[17] = 370.0;
1154 points->coords[18] = 330.0;
1155 points->coords[19] = 350.0;
1156 points->coords[20] = 370.0;
1157 points->coords[21] = 350.0;
1158 points->coords[22] = 370.0;
1159 points->coords[23] = 410.0;
1160 points->coords[24] = 290.0;
1161 points->coords[25] = 410.0;
1162 points->coords[26] = 290.0;
1163 points->coords[27] = 330.0;
1164 polyline2 = goo_canvas_polyline_new (root, TRUE, 0,
1165 "points", points,
1166 "fill_color", "tan",
1167 "stroke_color", "black",
1168 "line-width", 3.0,
1169 NULL);
1170 goo_canvas_points_unref (points);
1171 setup_item_signals (polyline2);
1172 }
1173
1174
1175 static GooCanvasItem *
make_anchor(GooCanvasItem * root,double x,double y)1176 make_anchor (GooCanvasItem *root, double x, double y)
1177 {
1178 GooCanvasItem *group, *item;
1179 cairo_matrix_t transform = { 0.8, 0.2, -0.3, 0.5, x, y };
1180
1181 group = goo_canvas_group_new (root, NULL);
1182 goo_canvas_item_translate (group, x, y);
1183 #if 1
1184 g_object_set (group,
1185 "transform", &transform,
1186 NULL);
1187 #endif
1188
1189 item = goo_canvas_rect_new (group, -2.5, -2.5, 4, 4,
1190 "line-width", 1.0,
1191 NULL);
1192 setup_item_signals (item);
1193
1194 g_signal_connect (group, "scroll_event",
1195 G_CALLBACK (on_scroll), NULL);
1196
1197 return group;
1198 }
1199
1200 static void
setup_texts(GooCanvasItem * root)1201 setup_texts (GooCanvasItem *root)
1202 {
1203 GooCanvasItem *item;
1204 cairo_pattern_t *pattern;
1205 static guchar stipple_data[16] = {
1206 0, 0, 0, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 255
1207 };
1208
1209 #if 1
1210 pattern = create_stipple ("blue", stipple_data);
1211 item = goo_canvas_text_new (make_anchor (root, 420, 20),
1212 "Anchor NW", 0, 0, -1, GOO_CANVAS_ANCHOR_NW,
1213 "font", "Sans Bold 24",
1214 "fill_pattern", pattern,
1215 NULL);
1216 cairo_pattern_destroy (pattern);
1217 setup_item_signals (item);
1218
1219 item = goo_canvas_text_new (make_anchor (root, 470, 75),
1220 "Anchor center\nJustify center\nMultiline text\nb8bit text ÅÄÖåäö",
1221 0, 0, -1, GOO_CANVAS_ANCHOR_CENTER,
1222 "font", "monospace bold 14",
1223 "alignment", PANGO_ALIGN_CENTER,
1224 "fill_color", "firebrick",
1225 NULL);
1226 setup_item_signals (item);
1227 #endif
1228
1229 #if 0
1230 item = goo_canvas_text_new (make_anchor (root, 590, 140),
1231 "Clipped text\nClipped text\nClipped text\nClipped text\nClipped text\nClipped text",
1232 0, 0, -1, GOO_CANVAS_ANCHOR_SE,
1233 "font", "Sans 12",
1234 /*"clip", TRUE,*/
1235 /*"clip_width", 50.0,*/
1236 /*"clip_height", 55.0,*/
1237 /*"x_offset", 10.0,*/
1238 "fill_color", "darkgreen",
1239 NULL);
1240 setup_item_signals (item);
1241 #endif
1242
1243 #if 1
1244 textitem = goo_canvas_text_new (make_anchor (root, 420, 240),
1245 "This is a very long paragraph that will need to be wrapped over several lines so we can see what happens to line-breaking as the view is zoomed in and out.",
1246 0, 0, 180, GOO_CANVAS_ANCHOR_W,
1247 "font", "Sans 12",
1248 "fill_color", "goldenrod",
1249 NULL);
1250 setup_item_signals (textitem);
1251 #endif
1252
1253 #if 1
1254 textitem = goo_canvas_text_new (root,
1255 "Ellipsized text.",
1256 20, 420, 115, GOO_CANVAS_ANCHOR_W,
1257 "font", "Sans 12",
1258 "fill_color", "blue",
1259 "ellipsize", PANGO_ELLIPSIZE_END,
1260 NULL);
1261 setup_item_signals (textitem);
1262 #endif
1263 }
1264
1265
1266 static void
setup_invisible_texts(GooCanvasItem * root)1267 setup_invisible_texts (GooCanvasItem *root)
1268 {
1269 goo_canvas_text_new (root, "Visible above 0.8x", 500, 330, -1,
1270 GOO_CANVAS_ANCHOR_CENTER,
1271 "visibility", GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD,
1272 "visibility-threshold", 0.8,
1273 NULL);
1274 goo_canvas_rect_new (root, 410.5, 322.5, 180, 15,
1275 "line-width", 1.0,
1276 "visibility", GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD,
1277 "visibility-threshold", 0.8,
1278 NULL);
1279
1280 goo_canvas_text_new (root, "Visible above 1.5x", 500, 350, -1,
1281 GOO_CANVAS_ANCHOR_CENTER,
1282 "visibility", GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD,
1283 "visibility-threshold", 1.5,
1284 NULL);
1285 goo_canvas_rect_new (root, 410.5, 342.5, 180, 15,
1286 "line-width", 1.0,
1287 "visibility", GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD,
1288 "visibility-threshold", 1.5,
1289 NULL);
1290
1291 goo_canvas_text_new (root, "Visible above 3.0x", 500, 370, -1,
1292 GOO_CANVAS_ANCHOR_CENTER,
1293 "visibility", GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD,
1294 "visibility-threshold", 3.0,
1295 NULL);
1296 goo_canvas_rect_new (root, 410.5, 362.5, 180, 15,
1297 "line-width", 1.0,
1298 "visibility", GOO_CANVAS_ITEM_VISIBLE_ABOVE_THRESHOLD,
1299 "visibility-threshold", 3.0,
1300 NULL);
1301
1302 /* This should never be seen. */
1303 goo_canvas_text_new (root, "Always Invisible", 500, 390, -1,
1304 GOO_CANVAS_ANCHOR_CENTER,
1305 "visibility", GOO_CANVAS_ITEM_INVISIBLE,
1306 NULL);
1307 goo_canvas_rect_new (root, 410.5, 350.5, 180, 15,
1308 "line-width", 1.0,
1309 "visibility", GOO_CANVAS_ITEM_INVISIBLE,
1310 NULL);
1311 }
1312
1313
1314 static void
plant_flower(GooCanvasItem * root,double x,double y,GooCanvasAnchorType anchor,gdouble opacity)1315 plant_flower (GooCanvasItem *root, double x, double y, GooCanvasAnchorType anchor, gdouble opacity)
1316 {
1317 cairo_pattern_t *pattern;
1318 cairo_surface_t *surface;
1319 GooCanvasItem *image;
1320 double w, h;
1321
1322 surface = cairo_image_surface_create_from_png ("flower.png");
1323 w = cairo_image_surface_get_width (surface);
1324 h = cairo_image_surface_get_height (surface);
1325
1326 pattern = cairo_pattern_create_for_surface (surface);
1327 cairo_surface_destroy (surface);
1328
1329 image = goo_canvas_image_new (root, NULL, x, y,
1330 "pattern", pattern,
1331 "width", w * 1.5,
1332 "height", h * 2,
1333 "scale-to-fit", TRUE,
1334 "alpha", opacity,
1335 NULL);
1336 cairo_pattern_destroy (pattern);
1337 setup_item_signals (image);
1338 }
1339
1340 static void
setup_images(GooCanvasItem * root)1341 setup_images (GooCanvasItem *root)
1342 {
1343 GdkPixbuf *im;
1344 GooCanvasItem *image;
1345
1346 im = gdk_pixbuf_new_from_file ("toroid.png", NULL);
1347
1348 if (im)
1349 {
1350 double w = gdk_pixbuf_get_width (im);
1351 double h = gdk_pixbuf_get_height (im);
1352 image = goo_canvas_image_new (root, im, 100.0 - w / 2, 225.0 - h / 2,
1353 "width", w,
1354 "height", h,
1355 /* "anchor", GOO_CANVAS_ANCHOR_CENTER, */
1356 NULL);
1357 g_object_unref(im);
1358 setup_item_signals (image);
1359 }
1360 else
1361 g_warning ("Could not find the toroid.png sample file");
1362
1363 plant_flower (root, 20.0, 170.0, GOO_CANVAS_ANCHOR_NW, 0.3);
1364 plant_flower (root, 180.0, 170.0, GOO_CANVAS_ANCHOR_NE, 0.5);
1365 plant_flower (root, 20.0, 280.0, GOO_CANVAS_ANCHOR_SW, 0.7);
1366 plant_flower (root, 180.0, 280.0, GOO_CANVAS_ANCHOR_SE, 1.0);
1367 }
1368
1369
1370 static void
setup_static_items(GooCanvas * canvas)1371 setup_static_items (GooCanvas *canvas)
1372 {
1373 GooCanvasItem *static_root, *group, *item;
1374
1375 static_root = goo_canvas_get_static_root_item (canvas);
1376
1377 /* All static items in one place in the canvas should be placed in the same
1378 group. */
1379 group = goo_canvas_group_new (static_root, NULL);
1380
1381 item = goo_canvas_polyline_new_line (group,
1382 40.0, 410.0,
1383 40.0, 330.0,
1384 "stroke-color", "midnightblue",
1385 "line-width", 3.0,
1386 "end-arrow", TRUE,
1387 "arrow-tip-length", 3.0,
1388 "arrow-length", 4.0,
1389 "arrow-width", 3.5,
1390 NULL);
1391 setup_item_signals (item);
1392
1393 item = goo_canvas_polyline_new_line (group,
1394 32.0, 370.0,
1395 48.0, 370.0,
1396 "stroke-color", "midnightblue",
1397 "line-width", 3.0,
1398 NULL);
1399 setup_item_signals (item);
1400
1401 item = goo_canvas_text_new (group, "N", 40, 320, -1, GOO_CANVAS_ANCHOR_S,
1402 "font", "Sans 12",
1403 NULL);
1404 setup_item_signals (item);
1405 }
1406
1407
1408 /* This checks that the rgba color properties work properly, i.e. the value
1409 written to them is the same when read back out. */
1410 static void
test_color_properties(GooCanvasItem * root)1411 test_color_properties (GooCanvasItem *root)
1412 {
1413 #if 0
1414 GooCanvasItem *item;
1415 guint red, green, blue, alpha, rgba_in, rgba_out;
1416
1417 item = goo_canvas_rect_new (root, 20, 30, 50, 30,
1418 NULL);
1419
1420 for (red = 0; red < 256; red += 15)
1421 {
1422 for (green = 0; green < 256; green += 15)
1423 {
1424 for (blue = 0; blue < 256; blue ++)
1425 {
1426 for (alpha = 0; alpha < 256; alpha += 15)
1427 {
1428 rgba_in = (red << 24) + (green << 16) + (blue << 8) + alpha;
1429 g_object_set (item, "fill_color_rgba", rgba_in, NULL);
1430 rgba_out = 0;
1431 g_object_get (item, "fill_color_rgba", &rgba_out, NULL);
1432
1433 if (rgba_in != rgba_out)
1434 g_print ("ERROR: rgba in: %.8X out: %.8X\n", rgba_in, rgba_out);
1435 }
1436 }
1437 }
1438 }
1439 #endif
1440 }
1441
1442 static void
test_simple_transforms(GooCanvasItem * root)1443 test_simple_transforms (GooCanvasItem *root)
1444 {
1445 #if 0
1446 GooCanvasItem *item;
1447 int rotation, x, y;
1448 double scale, x_out, y_out, scale_out, rotation_out, max_error = 0.0000001;
1449
1450 item = goo_canvas_rect_new (root, 20, 30, 50, 30,
1451 NULL);
1452
1453 for (rotation = 0; rotation < 360; rotation += 20)
1454 {
1455 scale = 0.1;
1456 while (scale < 10)
1457 {
1458 g_print ("Rotation: %i Scale: %g\n", rotation, scale);
1459
1460 for (x = -100; x < 100; x += 10)
1461 {
1462 for (y = -100; y < 100; y += 10)
1463 {
1464 goo_canvas_item_set_simple_transform (item, x, y, scale,
1465 rotation);
1466
1467 goo_canvas_item_get_simple_transform (item, &x_out, &y_out,
1468 &scale_out,
1469 &rotation_out);
1470
1471 if (fabs (x_out - x) > max_error
1472 || fabs (y_out - y) > max_error
1473 || fabs (scale_out - scale) > max_error
1474 || fabs (rotation_out - rotation) > max_error)
1475 {
1476 g_print ("IN X:%i Y:%i Scale:%g Rotation:%i -> %g, %g, %g, %g\n", x, y, scale, rotation, x_out, y_out, scale_out, rotation_out);
1477 }
1478 }
1479 }
1480 scale += 0.1;
1481 }
1482 }
1483 #endif
1484 }
1485
1486
1487 static void
setup_grids(GooCanvasItem * root)1488 setup_grids (GooCanvasItem *root)
1489 {
1490 GooCanvasItem *item G_GNUC_UNUSED;
1491
1492 item = goo_canvas_grid_new (root, 80, 310, 90, 90, 10, 10, 5, 5,
1493 "stroke-color", "yellow",
1494 "fill-color", "pink",
1495 "border-width", 2.0,
1496 "border-color", "red",
1497 "vert-grid-line-color", "lightblue",
1498 "horz-grid-line-width", 1.0,
1499 "vert-grid-line-width", 1.0,
1500 "vert-grid-lines-on-top", TRUE,
1501 NULL);
1502 }
1503
1504
1505 static void
setup_canvas(GooCanvas * canvas)1506 setup_canvas (GooCanvas *canvas)
1507 {
1508 GooCanvasItem *root;
1509
1510 root = goo_canvas_get_root_item (canvas);
1511 g_signal_connect (root, "button_press_event",
1512 G_CALLBACK (on_background_button_press), NULL);
1513
1514 /* Setup canvas items */
1515 #if 1
1516 setup_divisions (root);
1517 setup_rectangles (root);
1518 setup_ellipses (root);
1519 setup_lines (root);
1520 setup_polygons (root);
1521 setup_texts (root);
1522 setup_images (root);
1523 setup_invisible_texts (root);
1524 setup_static_items (canvas);
1525 setup_grids (root);
1526 #endif
1527
1528 test_color_properties (root);
1529 test_simple_transforms (root);
1530 }
1531
1532
1533 static gboolean
on_delete_event(GtkWidget * window,GdkEvent * event,gpointer unused_data)1534 on_delete_event (GtkWidget *window,
1535 GdkEvent *event,
1536 gpointer unused_data)
1537 {
1538 gtk_main_quit ();
1539 return FALSE;
1540 }
1541
1542
1543 static GtkWidget*
create_window()1544 create_window ()
1545 {
1546 GtkWidget *window, *notebook;
1547
1548 window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
1549 gtk_window_set_default_size (GTK_WINDOW (window), 640, 600);
1550 gtk_widget_show (window);
1551 g_signal_connect (window, "delete_event", G_CALLBACK (on_delete_event),
1552 NULL);
1553
1554 notebook = gtk_notebook_new ();
1555 gtk_widget_show (notebook);
1556 gtk_container_add (GTK_CONTAINER (window), notebook);
1557
1558 #if 1
1559 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1560 create_canvas_primitives (),
1561 gtk_label_new ("Primitives"));
1562 #endif
1563 #if 1
1564 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1565 create_canvas_arrowhead (),
1566 gtk_label_new ("Arrowhead"));
1567 #endif
1568 #if 1
1569 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1570 create_canvas_fifteen (),
1571 gtk_label_new ("Fifteen"));
1572 #endif
1573 #if 1
1574 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1575 create_canvas_features (),
1576 gtk_label_new ("Reparent"));
1577 #endif
1578 #if 1
1579 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1580 create_canvas_scalability (),
1581 gtk_label_new ("Scalability"));
1582 #endif
1583 #if 1
1584 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1585 create_grabs_page (),
1586 gtk_label_new ("Grabs"));
1587 #endif
1588 #if 1
1589 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1590 create_events_page (),
1591 gtk_label_new ("Events"));
1592 #endif
1593 #if 1
1594 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1595 create_paths_page (),
1596 gtk_label_new ("Paths"));
1597 #endif
1598 #if 1
1599 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1600 create_focus_page (),
1601 gtk_label_new ("Focus"));
1602 #endif
1603 #if 1
1604 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1605 create_animation_page (),
1606 gtk_label_new ("Animation"));
1607 #endif
1608 #if 1
1609 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1610 create_clipping_page (),
1611 gtk_label_new ("Clipping"));
1612 #endif
1613 #if 1
1614 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1615 create_table_page (),
1616 gtk_label_new ("Table"));
1617 #endif
1618 #if 1
1619 gtk_notebook_append_page (GTK_NOTEBOOK (notebook),
1620 create_large_items_page (),
1621 gtk_label_new ("Large Items"));
1622 #endif
1623
1624 return window;
1625 }
1626
1627
1628 int
main(int argc,char * argv[])1629 main (int argc, char *argv[])
1630 {
1631 GtkWidget *window G_GNUC_UNUSED;
1632
1633 gtk_init (&argc, &argv);
1634
1635 window = create_window ();
1636
1637 gtk_main ();
1638 return 0;
1639 }
1640