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   GooCanvasItemModel *model = goo_canvas_item_get_model (item);
26 
27   if (event->state & GDK_CONTROL_MASK)
28   {
29     if (event->button == 1 || event->button == 3)
30     {
31       if (event->button == 1)
32         drag_mode = MODE_MOVE;
33       else
34         drag_mode = MODE_RESIZE;
35 
36       drag_item = item;
37       drag_x = event->x;
38       drag_y = event->y;
39 
40       g_object_get (G_OBJECT (model),
41                     "x", &item_x,
42                     "y", &item_y,
43                     "width", &item_width,
44                     "height", &item_height,
45                     NULL);
46 
47       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);
48       return TRUE;
49     }
50   }
51 
52   return FALSE;
53 }
54 
55 static gboolean
on_button_release_event_cb(GooCanvasItem * item,GooCanvasItem * target_item,GdkEventButton * event,gpointer user_data)56 on_button_release_event_cb (GooCanvasItem  *item,
57                             GooCanvasItem  *target_item,
58                             GdkEventButton *event,
59                             gpointer user_data)
60 {
61   if (drag_item == item && drag_item != NULL)
62   {
63     goo_canvas_pointer_ungrab (GOO_CANVAS (user_data), drag_item, event->time);
64     drag_item = NULL;
65     return TRUE;
66   }
67 
68   return FALSE;
69 }
70 
71 static gboolean
on_motion_notify_event_cb(GooCanvasItem * item,GooCanvasItem * target_item,GdkEventMotion * event,gpointer user_data)72 on_motion_notify_event_cb (GooCanvasItem  *item,
73                            GooCanvasItem  *target_item,
74                            GdkEventMotion *event,
75                            gpointer user_data)
76 {
77   GooCanvasItemModel *model = goo_canvas_item_get_model (item);
78 
79   if (drag_item == item && drag_item != NULL)
80   {
81     gdouble rel_x = event->x - drag_x;
82     gdouble rel_y = event->y - drag_y;
83 
84     if (drag_mode == MODE_MOVE)
85     {
86       g_object_set (G_OBJECT (model), "x", item_x + rel_x, "y", item_y + rel_y, NULL);
87     }
88     else
89     {
90       gdouble new_width = MAX (item_width + rel_x, 5.0);
91       gdouble new_height = MAX (item_height + rel_y, 5.0);
92 
93       g_object_set (G_OBJECT (model), "width", new_width, "height", new_height, NULL);
94     }
95 
96     return TRUE;
97   }
98 
99   return FALSE;
100 }
101 
102 
103 static void
on_item_created(GooCanvas * canvas,GooCanvasItem * item,GooCanvasItemModel * model,gpointer data)104 on_item_created (GooCanvas          *canvas,
105 		 GooCanvasItem      *item,
106 		 GooCanvasItemModel *model,
107 		 gpointer            data)
108 {
109   if (g_object_get_data (G_OBJECT (model), "setup-dnd-signals"))
110     {
111       g_signal_connect (G_OBJECT (item), "button-press-event", G_CALLBACK (on_button_press_event_cb), canvas);
112       g_signal_connect (G_OBJECT (item), "button-release-event", G_CALLBACK (on_button_release_event_cb), canvas);
113       /*  g_signal_connect (G_OBJECT (item), "grab-broken-event", G_CALLBACK (on_button_release_event_cb), canvas);*/
114       g_signal_connect (G_OBJECT (item), "motion-notify-event", G_CALLBACK (on_motion_notify_event_cb), canvas);
115     }
116 }
117 
118 
119 static GooCanvasItemModel*
create_model(GdkPixbuf * pixbuf)120 create_model (GdkPixbuf *pixbuf)
121 {
122   GooCanvasItemModel *root;
123   GooCanvasItemModel *item;
124   GooCanvasItemModel* child;
125 
126   root = goo_canvas_group_model_new (NULL, NULL);
127 
128   /* Test clipping of GooCanvasGroup: We put the rectangle and the ellipse into
129    * a group with width=200 and height=200. */
130   item = goo_canvas_group_model_new (root, "x", 50.0, "y", 350.0, "width", 200.0, "height", 200.0, NULL);
131   /*goo_canvas_item_model_rotate(item, 45.0, 150.0, 450.0);*/
132 
133   child = goo_canvas_rect_model_new (item, 0.0, 0.0, 100, 100, "fill-color", "blue", NULL);
134   g_object_set_data (G_OBJECT (child), "setup-dnd-signals", "TRUE");
135   goo_canvas_item_model_rotate(child, 45.0, 50.0, 50.0);
136 
137   child = goo_canvas_ellipse_model_new (item, 150, 00, 50, 50, "fill-color", "red", NULL);
138   g_object_set_data (G_OBJECT (child), "setup-dnd-signals", "TRUE");
139 
140   item = goo_canvas_polyline_model_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);
141   g_object_set_data (G_OBJECT (item), "setup-dnd-signals", "TRUE");
142 
143   item = goo_canvas_path_model_new (root, "M20,500 C20,450 100,450 100,500", "stroke-color", "green", "line-width", 5.0, NULL);
144   g_object_set_data (G_OBJECT (item), "setup-dnd-signals", "TRUE");
145 
146   item = goo_canvas_image_model_new (root, pixbuf, 150, 450, /*"fill-color", "yellow", */NULL);
147   g_object_unref (pixbuf);
148   g_object_set_data (G_OBJECT (item), "setup-dnd-signals", "TRUE");
149 
150   item = goo_canvas_text_model_new (root, "Hello, World!", 250, 450, -1, GTK_ANCHOR_NW, "fill-color", "magenta", "wrap", PANGO_WRAP_WORD_CHAR, NULL);
151   g_object_set_data (G_OBJECT (item), "setup-dnd-signals", "TRUE");
152 
153   item = goo_canvas_table_model_new (root, "horz-grid-line-width", 2.0, "vert-grid-line-width", 2.0, "row-spacing", 2.0, "column-spacing", 2.0, NULL);
154   goo_canvas_item_model_translate (item, 10.0, 10.0);
155   g_object_set_data (G_OBJECT (item), "setup-dnd-signals", "TRUE");
156 
157   child = goo_canvas_rect_model_new (item, 10.0, 10.0, 50.0, 50.0, "fill-color", "blue", "x", 10.0, "y", 25.0, NULL);
158   g_object_set_data (G_OBJECT (child), "setup-dnd-signals", "TRUE");
159   goo_canvas_item_model_set_child_properties (item, child, "column", 0, "row", 0, "columns", 1, "rows", 1, NULL);
160   /*goo_canvas_item_model_translate (child, 10.0, 10.0);*/
161 
162   child = goo_canvas_rect_model_new (item, 0.0, 0.0, 50.0, 50.0, "fill-color", "red", NULL);
163   g_object_set_data (G_OBJECT (child), "setup-dnd-signals", "TRUE");
164   goo_canvas_item_model_set_child_properties (item, child, "column", 1, "row", 0, "columns", 1, "rows", 1, NULL);
165 
166   child = goo_canvas_rect_model_new (item, 0.0, 0.0, 50.0, 50.0, "fill-color", "green", NULL);
167   g_object_set_data (G_OBJECT (child), "setup-dnd-signals", "TRUE");
168   goo_canvas_item_model_set_child_properties(item, child, "column", 0, "row", 1, "columns", 1, "rows", 1, NULL);
169 
170   child = goo_canvas_rect_model_new (item, 0.0, 0.0, 50.0, 50.0, "fill-color", "yellow", NULL);
171   g_object_set_data (G_OBJECT (child), "setup-dnd-signals", "TRUE");
172   goo_canvas_item_model_set_child_properties (item, child, "column", 1, "row", 1, "columns", 1, "rows", 1, NULL);
173 
174   return root;
175 }
176 
177 
178 static GtkWidget*
create_window(GooCanvasItemModel * model)179 create_window (GooCanvasItemModel *model)
180 {
181   GtkWidget *window, *vbox, *label, *scrolled_win, *canvas;
182 
183   /* Create the window and widgets. */
184   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
185   gtk_window_set_default_size (GTK_WINDOW (window), 640, 600);
186   gtk_widget_show (window);
187   g_signal_connect (window, "destroy", G_CALLBACK (gtk_main_quit), NULL);
188 
189   vbox = gtk_vbox_new (FALSE, 4);
190   gtk_container_set_border_width (GTK_CONTAINER (vbox), 4);
191   gtk_widget_show (vbox);
192   gtk_container_add (GTK_CONTAINER (window), vbox);
193 
194   label = gtk_label_new ("Use Ctrl+Left Click to move items or Ctrl+Right Click to resize items");
195   gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
196   gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
197   gtk_widget_show (label);
198 
199   /* Create top canvas. */
200   scrolled_win = gtk_scrolled_window_new (NULL, NULL);
201   gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
202                                        GTK_SHADOW_IN);
203   gtk_widget_show (scrolled_win);
204   gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0);
205 
206   canvas = goo_canvas_new ();
207   g_object_set (G_OBJECT (canvas), "integer-layout", TRUE, NULL);
208 /*  gtk_widget_set_size_request (canvas, 600, 250);*/
209   goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 1000);
210   gtk_widget_show (canvas);
211   gtk_container_add (GTK_CONTAINER (scrolled_win), canvas);
212 
213   g_signal_connect (canvas, "item_created",
214 		    G_CALLBACK (on_item_created), NULL);
215 
216   goo_canvas_set_root_item_model (GOO_CANVAS (canvas), model);
217 
218   return window;
219 }
220 
221 
222 int
main(int argc,char * argv[])223 main (int argc, char *argv[])
224 {
225   GtkWidget *window;
226   GooCanvasItemModel *model;
227   GdkPixbuf *pixbuf;
228 
229   /* Initialize GTK+. */
230   gtk_set_locale ();
231   gtk_init (&argc, &argv);
232 
233   window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
234   pixbuf = gtk_widget_render_icon (window, GTK_STOCK_DIALOG_WARNING,
235 				   GTK_ICON_SIZE_DIALOG, NULL);
236 
237   model = create_model (pixbuf);
238 
239   /* Create 2 windows to show off multiple views. */
240   window = create_window (model);
241 #if 1
242   window = create_window (model);
243 #endif
244 
245   g_object_unref (model);
246 
247   gtk_main ();
248 
249   return 0;
250 }
251