Optimization
[gmodulargraph.git] / src / gtkgraph-demo.c
blob90ecf8047dd0f65c8b917eaa3eaf276dc69c37e6
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
2 /*
3 * gtkgraph-demo.c
4 * Copyright (C) Nikita Zlobin 2011 <nick87720z@gmail.com>
5 *
6 * gtkgraph is free software: you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * gtkgraph is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along
17 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <goocanvas.h>
21 #include <math.h>
22 #include <stdint.h>
23 #include <stdlib.h>
24 #include <string.h>
26 static gboolean on_module_buttonPress_event (GooCanvasItem * item, GooCanvasItem * target, GdkEventButton * event, gpointer data);
27 static gboolean on_module_buttonRelease_event (GooCanvasItem * item, GooCanvasItem * target, GdkEventButton * event, gpointer data);
28 static gboolean on_module_dragged (GooCanvasItem * item, GooCanvasItem * target, GdkEventMotion * event, gpointer data);
30 static gboolean on_module_text_notify (GooCanvasItem * item, GParamSpec * event, gpointer data);
32 static gboolean wire_entered (GooCanvasItem * item, GooCanvasItem * target, GdkEventCrossing * event, gpointer data);
33 static gboolean wire_left (GooCanvasItem * item, GooCanvasItem * target, GdkEventCrossing * event, gpointer data);
35 GtkWidget * root_menu, obj_menu, port_menu;
36 GooCanvasItem * wire;
38 #define drag_button 1
40 typedef
41 struct {
42 GtkOrientation * orientation;
43 GooCanvasItem * box; /* Background */
44 GooCanvasItem * caption;
45 GooCanvasItem * group; /* Just a logical container, without any look */
46 GList * ports;
48 /* Dragging data */
49 double drag_hold_x, drag_hold_y;
50 unsigned drag_cb;
51 } GModularGraph_Module;
53 #define G_MODULAR_GRAPH_MODULE(p) ((GModularGraph_Module *) p)
55 typedef
56 struct {
57 GooCanvasItem * box;
58 GooCanvasItem * text;
60 double wire_x, wire_y;
61 double direction;
62 } GModularGraph_Port;
64 /* Canvas data */
65 GtkWidget * canvas;
66 GooCanvasItem * root_item;
67 static double rounding = 3;
69 static GModularGraph_Module * module[2] = {NULL, NULL};
71 GModularGraph_Module * g_modular_graph_module_new (GooCanvasItem * parent, char * caption, char * tooltip, int placing, int x, int y)
73 GModularGraph_Module * module;
75 module = calloc (1, sizeof (GModularGraph_Module));
76 module->group = goo_canvas_group_new (parent, "x", (double) x, "y", (double) y, "tooltip", tooltip, NULL);
78 module->box = goo_canvas_rect_new (module->group,
79 0.5, 0.5, 50, 20,
80 "radius-x", rounding,
81 "radius-y", rounding,
82 "stroke-color", "gray60",
83 "fill-color", "gray50",
84 NULL);
85 module->caption = goo_canvas_text_new (module->group, "",
86 rounding, 0, -1, GTK_ANCHOR_NORTH_WEST,
87 "font", "sans 8", NULL);
88 g_signal_connect (G_OBJECT (module->caption), "notify::text", G_CALLBACK (on_module_text_notify), module);
90 /* Dragging capabilities */
91 g_signal_connect (G_OBJECT (module->group), "button-press-event", G_CALLBACK (on_module_buttonPress_event), module);
92 g_signal_connect (G_OBJECT (module->group), "button-release-event", G_CALLBACK (on_module_buttonRelease_event), module);
94 g_object_set (G_OBJECT (module->caption), "text", caption, NULL);
95 return module;
98 int main( int argc, char ** argv )
100 GtkWidget * win;
101 GtkWidget * scroller;
103 gtk_init (& argc, & argv);
104 win = gtk_window_new (GTK_WINDOW_TOPLEVEL);
105 g_signal_connect (G_OBJECT (win), "delete-event", G_CALLBACK (gtk_main_quit), NULL);
107 scroller = gtk_scrolled_window_new (NULL, NULL);
108 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scroller), GTK_SHADOW_IN);
109 gtk_container_add (GTK_CONTAINER (win), scroller);
111 /* Create canvas widget */
112 canvas = goo_canvas_new ();
113 gtk_widget_set_size_request (canvas, 600, 450);
114 goo_canvas_set_bounds (GOO_CANVAS (canvas), 0, 0, 1000, 1000);
115 g_object_set (G_OBJECT (canvas), "automatic-bounds", TRUE, NULL);
117 gtk_container_add (GTK_CONTAINER (scroller), canvas);
119 /* Root */
120 root_item = goo_canvas_get_root_item (GOO_CANVAS (canvas));
121 g_object_set (G_OBJECT (root_item), "antialias", CAIRO_ANTIALIAS_SUBPIXEL, NULL);
122 g_object_set (G_OBJECT (root_item), "line-join", CAIRO_LINE_JOIN_ROUND, NULL);
123 g_object_set (G_OBJECT (root_item), "line-cap", CAIRO_LINE_CAP_ROUND, NULL);
124 g_object_set (G_OBJECT (root_item), "line-width", 1.0, NULL);
126 module[0] = g_modular_graph_module_new (root_item, "Module 1", "Module 1 tip", 0, 50, 50);
127 module[1] = g_modular_graph_module_new (root_item, "Module 2", "Module 2 tip", 0, 200, 10);
129 /* 2. Connection */
130 char * wire_data = "M50,100 C100,100 50,200 100,200";
131 wire = goo_canvas_path_new (root_item,
132 wire_data,
133 "line-width", 3.0,
134 "stroke-color", "black", NULL);
135 wire = goo_canvas_path_new (root_item,
136 wire_data,
137 "line-width", 2.0,
138 "stroke-color", "violet", NULL);
139 g_signal_connect (G_OBJECT (wire), "enter-notify-event", G_CALLBACK (wire_entered), NULL);
140 g_signal_connect (G_OBJECT (wire), "leave-notify-event", G_CALLBACK (wire_left), NULL);
142 gtk_widget_set_has_tooltip (canvas, TRUE);
143 g_object_set (wire, "tooltip", "Wire Test", NULL);
145 gtk_widget_show_all (win);
146 gtk_main ();
147 return 0;
150 /* Helpers (nothing yet) */
152 /* Module callbacks */
153 #define DRAG_CB( mod ) (G_MODULAR_GRAPH_MODULE( mod )->drag_cb)
154 #define DRAG_HOLD_X( mod ) (G_MODULAR_GRAPH_MODULE( mod )->drag_hold_x)
155 #define DRAG_HOLD_Y( mod ) (G_MODULAR_GRAPH_MODULE( mod )->drag_hold_y)
157 static
158 gboolean on_module_buttonPress_event (GooCanvasItem * item, GooCanvasItem * target, GdkEventButton * event, gpointer data)
160 g_object_get (G_OBJECT (item),
161 "x", & DRAG_HOLD_X (data),
162 "y", & DRAG_HOLD_Y (data), NULL);
163 DRAG_HOLD_X (data) = event->x - DRAG_HOLD_X (data);
164 DRAG_HOLD_Y (data) = event->y - DRAG_HOLD_Y (data);
166 DRAG_CB (data) = g_signal_connect (G_OBJECT (root_item), "motion-notify-event", G_CALLBACK (on_module_dragged), data);
167 return FALSE;
170 static
171 gboolean on_module_buttonRelease_event (GooCanvasItem * item, GooCanvasItem * target, GdkEventButton * event, gpointer data)
173 if (DRAG_CB (data))
174 g_signal_handler_disconnect (G_OBJECT (root_item), DRAG_CB (data));
175 return FALSE;
178 static
179 gboolean on_module_dragged (GooCanvasItem * item, GooCanvasItem * target, GdkEventMotion * event, gpointer data)
181 g_object_set (G_MODULAR_GRAPH_MODULE (data)->group, "x", event->x - DRAG_HOLD_X (data), NULL);
182 g_object_set (G_MODULAR_GRAPH_MODULE (data)->group, "y", event->y - DRAG_HOLD_Y (data), NULL);
184 return FALSE;
187 static gboolean on_module_text_notify (GooCanvasItem * item, GParamSpec * event, gpointer data)
189 PangoRectangle rect;
190 double w, h;
192 goo_canvas_text_get_natural_extents (GOO_CANVAS_TEXT (item), NULL, & rect);
193 w = (double) PANGO_PIXELS (rect.width) + rounding * 2;
194 h = (double) PANGO_PIXELS (rect.height);
195 g_object_set (G_MODULAR_GRAPH_MODULE (data)->box, "width", w, NULL);
196 g_object_set (G_MODULAR_GRAPH_MODULE (data)->box, "height", h, NULL);
198 return FALSE;
201 /* Wire callbacks */
203 static
204 gboolean wire_entered (GooCanvasItem *item,
205 GooCanvasItem *target,
206 GdkEventCrossing *event,
207 gpointer data)
209 g_object_set (item, "stroke-color", "white", NULL);
210 return FALSE;
213 static
214 gboolean wire_left (GooCanvasItem *item,
215 GooCanvasItem *target,
216 GdkEventCrossing *event,
217 gpointer data)
219 g_object_set (item, "stroke-color", "violet", NULL);
220 return FALSE;