1 #include <stdlib.h>
2 #include <goocanvas.h>
3 
4 typedef enum {
5   MODE_MOVE,
6   MODE_RESIZE
7 } Mode;
8 
9 Mode             drag_mode;
10 GooCanvasItem   *drag_item = NULL;
11 gdouble          drag_x = 0.0;
12 gdouble          drag_y = 0.0;
13 
14 gdouble          item_x = 0.0;
15 gdouble          item_y = 0.0;
16 gdouble          item_width = 0.0;
17 gdouble          item_height = 0.0;
18 
19 static gboolean
on_button_press_event_cb(GooCanvasItem * item,GooCanvasItem * target_item,GdkEventButton * event,gpointer user_data)20 on_button_press_event_cb (GooCanvasItem *item,
21                           GooCanvasItem *target_item,
22                           GdkEventButton *event,
23                           gpointer user_data)
24 {
25   if (event->state & GDK_CONTROL_MASK)
26   {
27     if (event->button == 1 || event->button == 3)
28     {
29       if (event->button == 1)
30         drag_mode = MODE_MOVE;
31       else
32         drag_mode = MODE_RESIZE;
33 
34       drag_item = item;
35       drag_x = event->x;
36       drag_y = event->y;
37 
38       g_object_get (G_OBJECT (item),
39                     "x", &item_x,
40                     "y", &item_y,
41                     "width", &item_width,
42                     "height", &item_height,
43                     NULL);
44 
45       goo_canvas_pointer_grab (GOO_CANVAS (user_data), item, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_RELEASE_MASK, NULL, event->time);
46       return TRUE;
47     }
48   }
49 
50   return FALSE;
51 }
52 
53 static gboolean
on_button_release_event_cb(GooCanvasItem * item,GooCanvasItem * target_item,GdkEventButton * event,gpointer user_data)54 on_button_release_event_cb (GooCanvasItem  *item,
55                             GooCanvasItem  *target_item,
56                             GdkEventButton *event,
57                             gpointer user_data)
58 {
59   if (drag_item == item && drag_item != NULL)
60   {
61     goo_canvas_pointer_ungrab (GOO_CANVAS (user_data), drag_item, event->time);
62     drag_item = NULL;
63     return TRUE;
64   }
65 
66   return FALSE;
67 }
68 
69 static gboolean
on_motion_notify_event_cb(GooCanvasItem * item,GooCanvasItem * target_item,GdkEventMotion * event,gpointer user_data)70 on_motion_notify_event_cb (GooCanvasItem  *item,
71                            GooCanvasItem  *target_item,
72                            GdkEventMotion *event,
73                            gpointer user_data)
74 {
75   if (drag_item == item && drag_item != NULL)
76   {
77     gdouble rel_x = event->x - drag_x;
78     gdouble rel_y = event->y - drag_y;
79 
80     if (drag_mode == MODE_MOVE)
81     {
82       g_object_set (G_OBJECT (item), "x", item_x + rel_x, "y", item_y + rel_y, NULL);
83     }
84     else
85     {
86       gdouble new_width = MAX (item_width + rel_x, 5.0);
87       gdouble new_height = MAX (item_height + rel_y, 5.0);
88 
89       g_object_set (G_OBJECT (item), "width", new_width, "height", new_height, NULL);
90     }
91 
92     return TRUE;
93   }
94 
95   return FALSE;
96 }
97 
98 static void
setup_dnd_handlers(GooCanvas * canvas,GooCanvasItem * item)99 setup_dnd_handlers (GooCanvas *canvas,
100                     GooCanvasItem *item)
101 {
102   g_signal_connect (G_OBJECT (item), "button-press-event", G_CALLBACK (on_button_press_event_cb), canvas);
103   g_signal_connect (G_OBJECT (item), "button-release-event", G_CALLBACK (on_button_release_event_cb), canvas);
104 /*  g_signal_connect (G_OBJECT (item), "grab-broken-event", G_CALLBACK (on_button_release_event_cb), canvas);*/
105   g_signal_connect (G_OBJECT (item), "motion-notify-event", G_CALLBACK (on_motion_notify_event_cb), canvas);
106 }
107 
108 
109 void
setup_canvas(GtkWidget * canvas)110 setup_canvas (GtkWidget *canvas)
111 {
112   GooCanvasItem *root;
113   GooCanvasItem *item;
114   GdkPixbuf *pixbuf;
115   GtkWidget *button;
116   GooCanvasItem* child;
117 
118   root = goo_canvas_get_root_item (GOO_CANVAS (canvas));
119 
120   /* Test clipping of GooCanvasGroup: We put the rectangle and the ellipse into
121    * a group with width=200 and height=200. */
122   item = goo_canvas_group_new (root, "x", 50.0, "y", 350.0, "width", 200.0, "height", 200.0, NULL);
123   /*goo_canvas_item_rotate(item, 45.0, 150.0, 450.0);*/
124 
125   child = goo_canvas_rect_new (item, 0.0, 0.0, 100, 100, "fill-color", "blue", NULL);
126   setup_dnd_handlers (GOO_CANVAS (canvas), child);
127   goo_canvas_item_rotate(child, 45.0, 50.0, 50.0);
128 
129   child = goo_canvas_ellipse_new (item, 150, 00, 50, 50, "fill-color", "red", NULL);
130   setup_dnd_handlers (GOO_CANVAS (canvas), child);
131 
132   item = goo_canvas_polyline_new (root, FALSE, 5.0, 250.0, 350.0, 275.0, 400.0, 300.0, 350.0, 325.0, 400.0, 350.0, 350.0, "stroke-color", "cyan", "line-width", 5.0, NULL);
133   setup_dnd_handlers (GOO_CANVAS (canvas), item);
134 
135   item = goo_canvas_path_new (root, "M20,500 C20,450 100,450 100,500", "stroke-color", "green", "line-width", 5.0, NULL);
136   setup_dnd_handlers (GOO_CANVAS (canvas), item);
137 
138   pixbuf = gtk_widget_render_icon (GTK_WIDGET (canvas), GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG, NULL);
139   item = goo_canvas_image_new (root, pixbuf, 150, 450, /*"fill-color", "yellow", */NULL);
140   g_object_unref (pixbuf);
141   setup_dnd_handlers (GOO_CANVAS (canvas), item);
142 
143   item = goo_canvas_text_new (root, "Hello, World!", 250, 450, -1, GTK_ANCHOR_NW, "fill-color", "magenta", "wrap", PANGO_WRAP_WORD_CHAR, NULL);
144   setup_dnd_handlers (GOO_CANVAS (canvas), item);
145 
146   button = gtk_label_new ("GtkLabel");
147   item = goo_canvas_widget_new (root, button, 50, 550, -1, -1, NULL);
148   setup_dnd_handlers (GOO_CANVAS (canvas), item);
149 
150   item = goo_canvas_table_new (root, "horz-grid-line-width", 2.0, "vert-grid-line-width", 2.0, "row-spacing", 2.0, "column-spacing", 2.0, NULL);
151   goo_canvas_item_translate (item, 10.0, 10.0);
152   setup_dnd_handlers (GOO_CANVAS (canvas), item);
153 
154   child = goo_canvas_rect_new (item, 10.0, 10.0, 50.0, 50.0, "fill-color", "blue", "x", 10.0, "y", 25.0, NULL);
155   setup_dnd_handlers (GOO_CANVAS (canvas), child);
156   goo_canvas_item_set_child_properties (item, child, "column", 0, "row", 0, "columns", 1, "rows", 1, NULL);
157   /*goo_canvas_item_translate (child, 10.0, 10.0);*/
158 
159   child = goo_canvas_rect_new (item, 0.0, 0.0, 50.0, 50.0, "fill-color", "red", NULL);
160   setup_dnd_handlers (GOO_CANVAS (canvas), child);
161   goo_canvas_item_set_child_properties (item, child, "column", 1, "row", 0, "columns", 1, "rows", 1, NULL);
162 
163   child = goo_canvas_rect_new (item, 0.0, 0.0, 50.0, 50.0, "fill-color", "green", NULL);
164   setup_dnd_handlers (GOO_CANVAS (canvas), child);
165   goo_canvas_item_set_child_properties (item, child, "column", 0, "row", 1, "columns", 1, "rows", 1, NULL);
166 
167   child = goo_canvas_rect_new (item, 0.0, 0.0, 50.0, 50.0, "fill-color", "yellow", NULL);
168   setup_dnd_handlers (GOO_CANVAS (canvas), child);
169   goo_canvas_item_set_child_properties (item, child, "column", 1, "row", 1, "columns", 1, "rows", 1, NULL);
170 }
171 
172 
173 int
main(int argc,char * argv[])174 main (int argc, char *argv[])
175 {
176   GtkWidget *window, *vbox, *label, *scrolled_win, *canvas;
177 
178   /* Initialize GTK+. */
179   gtk_set_locale ();
180   gtk_init (&argc, &argv);
181 
182   /* Create the window and widgets. */
183   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
184   gtk_window_set_default_size (GTK_WINDOW (window), 640, 600);
185   gtk_widget_show (window);
186   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
187 
188   vbox = gtk_vbox_new (FALSE, 4);
189   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
190   gtk_widget_show (vbox);
191   gtk_container_add (GTK_CONTAINER (window), vbox);
192 
193   label = gtk_label_new ("Use Ctrl+Left Click to move items or Ctrl+Right Click to resize items");
194   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
195   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
196   gtk_widget_show (label);
197 
198   /* Create top canvas. */
199   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
200   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
201                                        GTK_SHADOW_IN);
202   gtk_widget_show (scrolled_win);
203   gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
204 
205   canvas = goo_canvas_new ();
206   g_object_set (G_OBJECT (canvas), "integer-layout", TRUE, NULL);
207 /*  gtk_widget_set_size_request (canvas, 600, 250);*/
208   goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 1000);
209   gtk_widget_show (canvas);
210   gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);
211 
212   setup_canvas (canvas);
213 
214   gtk_main ();
215 
216   return 0;
217 }
218