[demo] Removed custom signal catching from adg-demo
[adg.git] / demo / adg-demo.c
blobd182d3d174713b56b9f57992b12642b726270751
1 #include <adg/adg.h>
2 #include <math.h>
4 #include "demo.h"
7 static AdgCanvas * ldim_canvas (void);
8 static AdgCanvas * drawing_canvas (void);
9 static void to_pdf (AdgWidget *widget,
10 GtkWidget *caller);
11 static void to_png (AdgWidget *widget,
12 GtkWidget *caller);
13 static void to_ps (AdgWidget *widget,
14 GtkWidget *caller);
17 int
18 main(gint argc, gchar **argv)
20 gchar *path;
21 GtkBuilder *builder;
22 GError *error;
23 GtkWidget *window, *ldim, *drawing;
25 gtk_init(&argc, &argv);
27 path = demo_find_data_file("adg-demo.ui");
28 if (path == NULL) {
29 g_print("adg-demo.ui not found!\n");
30 return 1;
33 builder = gtk_builder_new();
34 error = NULL;
36 gtk_builder_add_from_file(builder, path, &error);
37 if (error != NULL) {
38 g_print("%s\n", error->message);
39 return 2;
42 window = (GtkWidget *) gtk_builder_get_object(builder, "wndMain");
44 ldim = (GtkWidget *) gtk_builder_get_object(builder, "areaLDim");
45 adg_widget_set_canvas(ADG_WIDGET(ldim), ldim_canvas());
47 drawing = (GtkWidget *) gtk_builder_get_object(builder, "areaDrawing");
48 adg_widget_set_canvas(ADG_WIDGET(drawing), drawing_canvas());
50 /* Connect signals */
51 g_signal_connect(window, "delete-event",
52 G_CALLBACK(gtk_main_quit), NULL);
53 g_signal_connect(gtk_builder_get_object(builder, "btnQuit"),
54 "clicked", G_CALLBACK(gtk_main_quit), NULL);
55 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPng"),
56 "clicked", G_CALLBACK(to_png), drawing);
57 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPdf"),
58 "clicked", G_CALLBACK(to_pdf), drawing);
59 g_signal_connect_swapped(gtk_builder_get_object(builder, "btnPs"),
60 "clicked", G_CALLBACK(to_ps), drawing);
62 g_object_unref(builder);
64 gtk_widget_show_all(window);
65 gtk_main();
67 return 0;
71 /**********************************************
72 * A simple example
73 **********************************************/
75 static AdgCanvas *
76 ldim_canvas(void)
78 AdgPath *path;
79 AdgCanvas *canvas;
80 AdgContainer *container;
81 AdgEntity *entity;
82 AdgMatrix transformation;
84 /* Build the path model */
85 path = (AdgPath *) adg_path_new();
87 adg_path_move_to(path, 0, 0);
88 adg_path_line_to(path, 0, -5);
89 adg_path_line_to(path, 2, -5);
90 adg_path_line_to(path, 2, -10);
91 adg_path_line_to(path, 8, -10);
92 adg_path_line_to(path, 8, -5);
93 adg_path_line_to(path, 10, -5);
94 adg_path_line_to(path, 10, 0);
95 adg_path_close(path);
97 /* Populate the canvas */
98 canvas = adg_canvas_new();
99 container = (AdgContainer *) canvas;
101 entity = adg_stroke_new(path);
102 adg_container_add(container, entity);
104 entity = adg_ldim_new_full_explicit(2, -10, 8, -10, ADG_DIR_UP, 0, -10);
105 adg_container_add(container, entity);
107 entity = adg_ldim_new_full_explicit(0, -5, 10, -5, ADG_DIR_UP, 0, -10);
108 adg_dim_set_level(ADG_DIM(entity), 2);
109 adg_container_add(container, entity);
111 /* Set a decent starting pan position and zoom */
112 cairo_matrix_init_translate(&transformation, 10, 80);
113 cairo_matrix_scale(&transformation, 39, 39);
114 cairo_matrix_translate(&transformation, 0, 10);
115 adg_container_set_model_transformation(container, &transformation);
117 return canvas;
121 /**********************************************
122 * A more complex example
123 **********************************************/
125 #define SQRT3 1.732050808
126 #define CHAMFER 0.3
128 typedef struct _DrawingData DrawingData;
130 struct _DrawingData {
131 gdouble A, B, C;
132 gdouble D1, D2, D3, D4, D5, D6, D7;
133 gdouble RD34, RD56;
134 gdouble LD2, LD3, LD5, LD6, LD7;
137 static void drawing_get (DrawingData *data);
138 static AdgPath *drawing_path (const DrawingData *data);
139 static void drawing_add_dimensions (AdgCanvas *canvas,
140 const DrawingData *data);
141 static void drawing_add_stuff (AdgCanvas *canvas,
142 const DrawingData *data);
145 static AdgCanvas *
146 drawing_canvas(void)
148 DrawingData data;
149 AdgPath *path;
150 AdgCanvas *canvas;
151 AdgContainer *container;
152 AdgEntity *entity;
153 AdgMatrix transformation;
155 drawing_get(&data);
156 path = drawing_path(&data);
157 canvas = adg_canvas_new();
158 container = (AdgContainer *) canvas;
160 entity = adg_stroke_new(path);
161 adg_container_add(container, entity);
163 drawing_add_dimensions(canvas, &data);
164 drawing_add_stuff(canvas, &data);
166 cairo_matrix_init_translate(&transformation, 100, 70);
167 cairo_matrix_scale(&transformation, 6.883, 6.883);
168 cairo_matrix_translate(&transformation, 0, 10);
169 adg_container_set_model_transformation(container, &transformation);
171 return canvas;
174 static void
175 drawing_get(DrawingData *data)
177 data->A = 52.3;
178 data->B = 20.6;
179 data->C = 2;
180 data->D1 = 9.3;
181 data->D2 = 6.5;
182 data->D3 = 11.9;
183 data->D4 = 6.5;
184 data->D5 = 4.5;
185 data->D6 = 7.2;
186 data->D7 = 3.;
187 data->RD34 = 1.;
188 data->LD2 = 7.;
189 data->LD3 = 3.5;
190 data->LD5 = 5.;
191 data->LD6 = 1.;
192 data->LD7 = 0.5;
195 static AdgPath *
196 drawing_path(const DrawingData *data)
198 AdgPath *path;
199 double x, y;
200 cairo_path_t *cairo_path;
201 CpmlSegment segment;
202 cairo_matrix_t matrix;
204 path = (AdgPath *) adg_path_new();
206 adg_path_move_to(path, 0, data->D1 / 2);
207 adg_path_line_to(path, data->A - data->B - data->LD2, data->D1 / 2);
208 y = (data->D1 - data->D2) / 2;
209 adg_path_line_to(path, data->A - data->B - data->LD2 + y * SQRT3, data->D1 / 2 - y);
210 adg_path_line_to(path, data->A - data->B, data->D2 / 2);
211 adg_path_line_to(path, data->A - data->B, data->D3 / 2 - CHAMFER);
212 adg_path_line_to(path, data->A - data->B + CHAMFER, data->D3 / 2);
213 adg_path_line_to(path, data->A - data->B + data->LD3 - CHAMFER, data->D3 / 2);
214 adg_path_line_to(path, data->A - data->B + data->LD3, data->D3 / 2 - CHAMFER);
215 x = data->A - data->B + data->LD3 + data->RD34;
216 y = data->D4 / 2 + data->RD34;
217 adg_path_arc(path, x, y, data->RD34, G_PI, -G_PI_2);
218 adg_path_line_to(path, data->A - data->C - data->LD5, data->D4 / 2);
219 y = (data->D4 - data->D5) / 2;
220 adg_path_line_to(path, data->A - data->C - data->LD5 + y, data->D4 / 2 - y);
221 adg_path_line_to(path, data->A - data->C, data->D5 / 2);
222 adg_path_line_to(path, data->A - data->C, data->D6 / 2);
223 adg_path_line_to(path, data->A - data->C + data->LD6, data->D6 / 2);
224 x = data->C - data->LD7 - data->LD6;
225 y = x / SQRT3;
226 adg_path_line_to(path, data->A - data->C + data->LD6 + x, data->D6 / 2 - y);
227 adg_path_line_to(path, data->A - data->LD7, data->D7 / 2);
228 adg_path_line_to(path, data->A, data->D7 / 2);
230 /* Build the shape by reflecting the current path, reversing the order
231 * and joining the result to the current path */
232 cairo_path = adg_path_dup_cpml_path(path);
234 cpml_segment_from_cairo(&segment, cairo_path);
235 cpml_segment_reverse(&segment);
236 adg_matrix_init_reflection(&matrix, 0);
237 cpml_segment_transform(&segment, &matrix);
238 cairo_path->data[0].header.type = CAIRO_PATH_LINE_TO;
240 adg_path_append_cairo_path(path, cairo_path);
242 g_free(cairo_path);
244 adg_path_close(path);
245 return path;
248 static void
249 drawing_add_dimensions(AdgCanvas *canvas, const DrawingData *data)
251 AdgEntity *entity;
252 double x, y;
254 /* NORTH */
256 /* LD2 */
257 entity = adg_ldim_new_full_explicit(data->A - data->B - data->LD2, -data->D1 / 2, data->A - data->B,
258 -data->D3 / 2 + CHAMFER, ADG_DIR_UP, 0,
259 -data->D3 / 2);
260 adg_container_add(ADG_CONTAINER(canvas), entity);
262 /* LD3 */
263 entity = adg_ldim_new_full_explicit(data->A - data->B, -data->D3 / 2 + CHAMFER, data->A - data->B + data->LD3,
264 -data->D3 / 2 + CHAMFER, ADG_DIR_UP, 0,
265 -data->D3 / 2);
266 adg_container_add(ADG_CONTAINER(canvas), entity);
268 /* SOUTH */
270 /* B */
271 entity = adg_ldim_new_full_explicit(data->A - data->B, data->D3 / 2 - CHAMFER, data->A, data->D7 / 2,
272 ADG_DIR_DOWN, 0, data->D3 / 2);
273 adg_dim_set_tolerances(ADG_DIM(entity), "+0.1", NULL);
274 adg_container_add(ADG_CONTAINER(canvas), entity);
276 /* A */
277 entity = adg_ldim_new_full_explicit(0, data->D1 / 2, data->A, data->D7 / 2,
278 ADG_DIR_DOWN, 0, data->D3 / 2);
279 adg_dim_set_tolerances(ADG_DIM(entity), "+0.05", "-0.05");
280 adg_dim_set_level(ADG_DIM(entity), 2);
281 adg_container_add(ADG_CONTAINER(canvas), entity);
283 /* EAST */
285 /* D3 */
286 x = data->A - data->B + data->LD3 - CHAMFER;
287 entity = adg_ldim_new_full_explicit(x, -data->D3 / 2, x, data->D3 / 2,
288 ADG_DIR_RIGHT, data->A, 0);
289 adg_dim_set_tolerances(ADG_DIM(entity), "-0.25", NULL);
290 adg_dim_set_level(ADG_DIM(entity), 5);
291 adg_container_add(ADG_CONTAINER(canvas), entity);
293 /* D6 */
294 x = data->A - data->C + data->LD6;
295 entity = adg_ldim_new_full_explicit(x, -data->D6 / 2, x, data->D6 / 2,
296 ADG_DIR_RIGHT, data->A, 0);
297 adg_dim_set_tolerances(ADG_DIM(entity), "-0.1", NULL);
298 adg_dim_set_level(ADG_DIM(entity), 4);
299 adg_container_add(ADG_CONTAINER(canvas), entity);
301 /* D4 */
302 x = data->A - data->C - data->LD5;
303 entity = adg_ldim_new_full_explicit(x, -data->D4 / 2, x, data->D4 / 2,
304 ADG_DIR_RIGHT, data->A, 0);
305 adg_dim_set_level(ADG_DIM(entity), 3);
306 adg_container_add(ADG_CONTAINER(canvas), entity);
308 /* D5 */
309 x = data->A - data->C;
310 entity = adg_ldim_new_full_explicit(x, -data->D5 / 2, x, data->D5 / 2,
311 ADG_DIR_RIGHT, data->A, 0);
312 adg_dim_set_tolerances(ADG_DIM(entity), "-0.1", NULL);
313 adg_dim_set_level(ADG_DIM(entity), 2);
314 adg_container_add(ADG_CONTAINER(canvas), entity);
316 /* D7 */
317 entity = adg_ldim_new_full_explicit(data->A, -data->D7 / 2, data->A, data->D7 / 2,
318 ADG_DIR_RIGHT, data->A, 0);
319 adg_container_add(ADG_CONTAINER(canvas), entity);
321 /* WEST */
323 /* D1 */
324 entity = adg_ldim_new_full_explicit(0, -data->D1 / 2, 0, data->D1 / 2,
325 ADG_DIR_LEFT, 0, 0);
326 adg_dim_set_tolerances(ADG_DIM(entity), "+0.05", "-0.05");
327 adg_dim_set_level(ADG_DIM(entity), 2);
328 adg_container_add(ADG_CONTAINER(canvas), entity);
330 /* D2 */
331 y = (data->D1 - data->D2) / 2;
332 x = data->A - data->B - data->LD2 + y * SQRT3;
333 entity = adg_ldim_new_full_explicit(x, -data->D2 / 2, x, data->D2 / 2,
334 ADG_DIR_LEFT, 0, 0);
335 adg_dim_set_tolerances(ADG_DIM(entity), "-0.1", NULL);
336 adg_container_add(ADG_CONTAINER(canvas), entity);
339 static void
340 drawing_add_stuff(AdgCanvas *canvas, const DrawingData *data)
342 AdgEntity *toy_text;
344 toy_text = adg_toy_text_new("Horizontal toy_text above the piston");
345 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text),
346 0., -data->D1 / 2,
347 0., -5.);
348 adg_container_add(ADG_CONTAINER(canvas), toy_text);
350 toy_text = adg_toy_text_new("toy_text");
351 adg_translatable_set_origin_explicit(ADG_TRANSLATABLE(toy_text),
352 0., data->D1 / 2,
353 0., -5.);
354 adg_rotable_set_angle(ADG_ROTABLE(toy_text), M_PI * 3./2.);
355 adg_container_add(ADG_CONTAINER(canvas), toy_text);
359 #if defined(CAIRO_HAS_PNG_FUNCTIONS) || defined(CAIRO_HAS_PDF_SURFACE) || defined(CAIRO_HAS_PS_SURFACE)
361 /* Only needed if there is at least one supported surface */
362 static void
363 file_generated(GtkWidget *caller, const gchar *file)
365 GtkWindow *window;
366 GtkWidget *dialog;
368 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
369 dialog = gtk_message_dialog_new_with_markup(window, GTK_DIALOG_MODAL,
370 GTK_MESSAGE_INFO,
371 GTK_BUTTONS_CLOSE,
372 "The requested operation generated\n"
373 "<b>%s</b> in the current directory.",
374 file);
375 gtk_window_set_title(GTK_WINDOW(dialog), "Operation completed");
376 gtk_dialog_run(GTK_DIALOG(dialog));
377 gtk_widget_destroy(dialog);
380 #endif
382 #if !defined(CAIRO_HAS_PNG_FUNCTIONS) || !defined(CAIRO_HAS_PDF_SURFACE) || !defined(CAIRO_HAS_PS_SURFACE)
384 /* Only needed if there is a missing surface */
385 static void
386 missing_feature(GtkWidget *caller, const gchar *feature)
388 GtkWindow *window;
389 GtkWidget *dialog;
391 window = (GtkWindow *) gtk_widget_get_toplevel(caller);
392 dialog = gtk_message_dialog_new(window, GTK_DIALOG_MODAL,
393 GTK_MESSAGE_WARNING,
394 GTK_BUTTONS_OK,
395 "The provided cairo library\n"
396 "was compiled with no %s support!",
397 feature);
398 gtk_window_set_title(GTK_WINDOW(dialog), "Missing feature");
399 gtk_dialog_run(GTK_DIALOG(dialog));
400 gtk_widget_destroy(dialog);
403 #endif
406 #ifdef CAIRO_HAS_PNG_FUNCTIONS
408 static void
409 to_png(AdgWidget *widget, GtkWidget *caller)
411 cairo_surface_t *surface;
412 cairo_t *cr;
414 surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 800, 600);
415 cr = cairo_create(surface);
416 cairo_surface_destroy(surface);
418 /* Rendering process */
419 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
421 cairo_show_page(cr);
422 cairo_surface_write_to_png(surface, "test.png");
423 cairo_destroy(cr);
425 file_generated(caller, "test.png");
428 #else
430 static void
431 to_png(AdgWidget *widget, GtkWidget *caller)
433 missing_feature(caller, "PNG");
436 #endif
438 #ifdef CAIRO_HAS_PDF_SURFACE
440 #include <cairo-pdf.h>
442 static void
443 to_pdf(AdgWidget *widget, GtkWidget *caller)
445 cairo_surface_t *surface;
446 cairo_t *cr;
448 surface = cairo_pdf_surface_create("test.pdf", 841, 595);
449 cr = cairo_create(surface);
450 cairo_surface_destroy(surface);
452 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
454 cairo_show_page(cr);
455 cairo_destroy(cr);
457 file_generated(caller, "test.pdf");
460 #else
462 static void
463 to_pdf(AdgWidget *widget, GtkWidget *caller)
465 missing_feature(caller, "PDF");
468 #endif
470 #ifdef CAIRO_HAS_PS_SURFACE
472 #include <cairo-ps.h>
474 static void
475 to_ps(AdgWidget *widget, GtkWidget *caller)
477 cairo_surface_t *surface;
478 cairo_t *cr;
480 /* Surface creation: A4 size */
481 surface = cairo_ps_surface_create("test.ps", 841, 595);
482 cairo_ps_surface_dsc_comment(surface,
483 "%%Title: Automatic Drawing Generation (Adg) demo");
484 cairo_ps_surface_dsc_comment(surface,
485 "%%Copyright: Copyright (C) 2006 Fontana Nicola");
486 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
488 cairo_ps_surface_dsc_begin_setup(surface);
490 cairo_ps_surface_dsc_begin_page_setup(surface);
491 cairo_ps_surface_dsc_comment(surface,
492 "%%IncludeFeature: *PageSize A4");
494 cr = cairo_create(surface);
495 cairo_surface_destroy(surface);
497 adg_entity_render(ADG_ENTITY(adg_widget_get_canvas(widget)), cr);
499 cairo_show_page(cr);
500 cairo_destroy(cr);
502 file_generated(caller, "test.ps");
505 #else
507 static void
508 to_ps(AdgWidget *widget, GtkWidget *caller)
510 missing_feature(caller, "PostScript");
513 #endif