[build] Cross-building on MinGW32 working
[adg.git] / demo / adg-demo.c
blobd6d5a94aec959a0ec6a941ac1ef7b45f3106b1f9
1 #include <adg-gtk.h>
2 #include <math.h>
4 #include "demo.h"
7 #define SQRT3 1.732050808
8 #define CHAMFER 0.3
11 typedef struct _AdgPart AdgPart;
13 struct _AdgPart {
14 /* Raw data */
15 gdouble A, B, C;
16 gdouble DHOLE, LHOLE;
17 gdouble D1, D2, D3, D4, D5, D6, D7;
18 gdouble RD34, RD56;
19 gdouble LD2, LD3, LD5, LD6, LD7;
21 /* User interface widgets */
22 AdgGtkArea *area;
23 GHashTable *widgets;
24 GtkButton *apply, *reset;
26 /* Models */
27 AdgPath *shape, *hatch;
28 AdgEdges *edges;
32 static void
33 _adg_version(void)
35 g_print("adg-demo " PACKAGE_VERSION "\n");
36 exit(0);
39 static void
40 _adg_parse_args(gint *p_argc, gchar **p_argv[], gboolean *show_extents)
42 GError *error = NULL;
43 GOptionEntry entries[] = {
44 {"version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
45 _adg_version, "Display version information", NULL},
46 {"show-extents", 'E', 0, G_OPTION_ARG_NONE,
47 NULL, "Show the boundary boxes of every entity", NULL},
48 {NULL}
51 entries[1].arg_data = show_extents;
52 *show_extents = FALSE;
53 gtk_init_with_args(p_argc, p_argv, "- ADG demonstration program",
54 entries, GETTEXT_PACKAGE, &error);
56 if (error != NULL) {
57 gint error_code = error->code;
59 g_printerr("%s\n", error->message);
61 g_error_free(error);
62 exit(error_code);
66 static void
67 _adg_define_hole(AdgPath *path, const AdgPart *part, gdouble height)
69 AdgModel *model;
70 AdgPair pair;
72 model = ADG_MODEL(path);
74 pair.x = part->LHOLE;
75 pair.y = 0;
76 adg_path_move_to(path, &pair);
77 adg_model_set_named_pair(model, "LHOLE", &pair);
79 pair.y = part->DHOLE / 2;
80 pair.x -= pair.y / SQRT3;
81 adg_path_line_to(path, &pair);
83 pair.x = 0;
84 adg_path_line_to(path, &pair);
85 adg_model_set_named_pair(model, "DHOLE", &pair);
87 pair.y = part->D1 / 2;
88 adg_path_line_to(path, &pair);
89 adg_model_set_named_pair(model, "D1I", &pair);
91 pair.x = height;
92 adg_path_line_to(path, &pair);
93 adg_model_set_named_pair(model, "D1F", &pair);
96 static void
97 _adg_define_hatch(AdgPath *path, const AdgPart *part)
99 _adg_define_hole(path, part, part->LHOLE + 2);
100 adg_path_reflect(path, NULL);
101 adg_path_close(path);
104 static void
105 _adg_define_shape(AdgPath *path, const AdgPart *part)
107 AdgModel *model;
108 AdgPair pair, tmp;
109 const AdgPrimitive *primitive;
111 pair.x = part->A - part->B - part->LD2;
112 _adg_define_hole(path, part, pair.x);
113 model = ADG_MODEL(path);
115 pair.x += (part->D1 - part->D2) / 2;
116 pair.y = part->D2 / 2;
117 adg_path_line_to(path, &pair);
118 adg_model_set_named_pair(model, "D2I", &pair);
120 pair.x = part->A - part->B;
121 adg_path_line_to(path, &pair);
122 adg_path_fillet(path, 0.4);
124 pair.x = part->A - part->B;
125 pair.y = part->D3 / 2;
126 adg_path_line_to(path, &pair);
127 adg_model_set_named_pair(model, "D3I", &pair);
129 pair.x = part->A;
130 adg_model_set_named_pair(model, "East", &pair);
132 pair.x = 0;
133 adg_model_set_named_pair(model, "West", &pair);
135 adg_path_chamfer(path, CHAMFER, CHAMFER);
137 pair.x = part->A - part->B + part->LD3;
138 pair.y = part->D3 / 2;
139 adg_path_line_to(path, &pair);
141 primitive = adg_path_over_primitive(path);
142 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
143 adg_model_set_named_pair(model, "D3I_X", &tmp);
145 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
146 adg_model_set_named_pair(model, "D3I_Y", &tmp);
148 adg_path_chamfer(path, CHAMFER, CHAMFER);
150 pair.y = part->D4 / 2;
151 adg_path_line_to(path, &pair);
153 primitive = adg_path_over_primitive(path);
154 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
155 adg_model_set_named_pair(model, "D3F_Y", &tmp);
156 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
157 adg_model_set_named_pair(model, "D3F_X", &tmp);
159 adg_path_fillet(path, part->RD34);
161 pair.x += part->RD34;
162 adg_model_set_named_pair(model, "D4I", &pair);
164 pair.x = part->A - part->C - part->LD5;
165 adg_path_line_to(path, &pair);
166 adg_model_set_named_pair(model, "D4F", &pair);
168 pair.y = part->D3 / 2;
169 adg_model_set_named_pair(model, "D4_POS", &pair);
171 primitive = adg_path_over_primitive(path);
172 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
173 tmp.x += part->RD34;
174 adg_model_set_named_pair(model, "RD34", &tmp);
176 tmp.x -= cos(G_PI_4) * part->RD34,
177 tmp.y -= sin(G_PI_4) * part->RD34,
178 adg_model_set_named_pair(model, "RD34_R", &tmp);
180 tmp.x += part->RD34,
181 tmp.y += part->RD34,
182 adg_model_set_named_pair(model, "RD34_XY", &tmp);
184 pair.x += (part->D4 - part->D5) / 2;
185 pair.y = part->D5 / 2;
186 adg_path_line_to(path, &pair);
187 adg_model_set_named_pair(model, "D5I", &pair);
189 pair.x = part->A - part->C;
190 adg_path_line_to(path, &pair);
192 adg_path_fillet(path, 0.2);
194 pair.y = part->D6 / 2;
195 adg_path_line_to(path, &pair);
197 primitive = adg_path_over_primitive(path);
198 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
199 adg_model_set_named_pair(model, "D5F", &tmp);
201 adg_path_fillet(path, 0.1);
203 pair.x += part->LD6;
204 adg_path_line_to(path, &pair);
205 adg_model_set_named_pair(model, "D6F", &pair);
207 primitive = adg_path_over_primitive(path);
208 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, 0));
209 adg_model_set_named_pair(model, "D6I_X", &tmp);
211 primitive = adg_path_over_primitive(path);
212 cpml_pair_from_cairo(&tmp, cpml_primitive_get_point(primitive, -1));
213 adg_model_set_named_pair(model, "D6I_Y", &tmp);
215 pair.x = part->A - part->LD7;
216 pair.y -= (part->C - part->LD7 - part->LD6) / SQRT3;
217 adg_path_line_to(path, &pair);
218 adg_model_set_named_pair(model, "D67", &pair);
220 pair.y = part->D7 / 2;
221 adg_path_line_to(path, &pair);
223 pair.x = part->A;
224 adg_path_line_to(path, &pair);
225 adg_model_set_named_pair(model, "D7F", &pair);
227 adg_path_reflect(path, NULL);
228 adg_path_close(path);
229 adg_path_move_to_explicit(path, part->LHOLE + 2, part->D1 / 2);
230 adg_path_line_to_explicit(path, part->LHOLE + 2, -part->D1 / 2);
233 static void
234 _adg_part_lock(AdgPart *part)
236 gtk_widget_set_sensitive(GTK_WIDGET(part->apply), FALSE);
237 gtk_widget_set_sensitive(GTK_WIDGET(part->reset), FALSE);
240 static void
241 _adg_part_unlock(AdgPart *part)
243 gtk_widget_set_sensitive(GTK_WIDGET(part->apply), TRUE);
244 gtk_widget_set_sensitive(GTK_WIDGET(part->reset), TRUE);
247 static void
248 _adg_part_link(AdgPart *part, gpointer data, GObject *widget)
250 g_assert(GTK_IS_WIDGET(widget));
251 g_object_ref(widget);
252 g_hash_table_insert(part->widgets, data, widget);
254 if (GTK_IS_SPIN_BUTTON(widget)) {
255 GtkSpinButton *spin_button = GTK_SPIN_BUTTON(widget);
256 gtk_adjustment_value_changed(gtk_spin_button_get_adjustment(spin_button));
259 g_signal_connect_swapped(widget, "changed",
260 G_CALLBACK(_adg_part_unlock), part);
263 static void
264 _adg_part_ui_to_data_double(AdgPart *part, gdouble *data)
266 GtkWidget *widget = g_hash_table_lookup(part->widgets, data);
268 g_assert(GTK_IS_WIDGET(widget));
270 *data = gtk_spin_button_get_value(GTK_SPIN_BUTTON(widget));
273 static void
274 _adg_part_data_to_ui_double(AdgPart *part, gdouble *data)
276 GtkWidget *widget = g_hash_table_lookup(part->widgets, data);
278 g_assert(GTK_IS_WIDGET(widget));
280 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), *data);
283 static void
284 _adg_part_data_to_ui(AdgPart *part)
286 _adg_part_data_to_ui_double(part, &part->A);
287 _adg_part_data_to_ui_double(part, &part->B);
288 _adg_part_data_to_ui_double(part, &part->C);
289 _adg_part_data_to_ui_double(part, &part->DHOLE);
290 _adg_part_data_to_ui_double(part, &part->LHOLE);
291 _adg_part_data_to_ui_double(part, &part->D1);
292 _adg_part_data_to_ui_double(part, &part->D2);
293 _adg_part_data_to_ui_double(part, &part->LD2);
294 _adg_part_data_to_ui_double(part, &part->D3);
295 _adg_part_data_to_ui_double(part, &part->LD3);
296 _adg_part_data_to_ui_double(part, &part->D4);
297 //_adg_part_data_to_ui_double(part, &part->D5);
298 _adg_part_data_to_ui_double(part, &part->D6);
299 //_adg_part_data_to_ui_double(part, &part->LD6);
300 _adg_part_data_to_ui_double(part, &part->D7);
301 //_adg_part_data_to_ui_double(part, &part->LD7);
302 _adg_part_lock(part);
305 static void
306 _adg_part_ui_to_data(AdgPart *part)
308 _adg_part_ui_to_data_double(part, &part->A);
309 _adg_part_ui_to_data_double(part, &part->B);
310 _adg_part_ui_to_data_double(part, &part->C);
311 _adg_part_ui_to_data_double(part, &part->DHOLE);
312 _adg_part_ui_to_data_double(part, &part->LHOLE);
313 _adg_part_ui_to_data_double(part, &part->D1);
314 _adg_part_ui_to_data_double(part, &part->D2);
315 _adg_part_ui_to_data_double(part, &part->LD2);
316 _adg_part_ui_to_data_double(part, &part->D3);
317 _adg_part_ui_to_data_double(part, &part->LD3);
318 _adg_part_ui_to_data_double(part, &part->D4);
319 //_adg_part_ui_to_data_double(part, &part->D5);
320 _adg_part_ui_to_data_double(part, &part->D6);
321 //_adg_part_ui_to_data_double(part, &part->LD6);
322 _adg_part_ui_to_data_double(part, &part->D7);
323 //_adg_part_ui_to_data_double(part, &part->LD7);
325 _adg_part_lock(part);
327 adg_model_clear(ADG_MODEL(part->shape));
328 _adg_define_shape(part->shape, part);
329 adg_model_changed(ADG_MODEL(part->shape));
331 adg_model_clear(ADG_MODEL(part->hatch));
332 _adg_define_hatch(part->hatch, part);
333 adg_model_changed(ADG_MODEL(part->hatch));
335 adg_model_clear(ADG_MODEL(part->edges));
336 adg_model_changed(ADG_MODEL(part->edges));
338 gtk_widget_queue_draw(GTK_WIDGET(part->area));
341 static AdgPart *
342 _adg_part_new(GtkBuilder *builder)
344 AdgPart *part;
346 part = g_new0(AdgPart, 1);
347 part->widgets = g_hash_table_new_full(g_direct_hash, g_direct_equal,
348 NULL, g_object_unref);
349 part->area = (AdgGtkArea *) gtk_builder_get_object(builder, "mainCanvas");
350 part->apply = (GtkButton *) gtk_builder_get_object(builder, "editApply");
351 part->reset = (GtkButton *) gtk_builder_get_object(builder, "editReset");
352 part->shape = adg_path_new();
353 part->hatch = adg_path_new();
354 part->edges = adg_edges_new_with_source(ADG_TRAIL(part->shape));
356 g_assert(ADG_GTK_IS_AREA(part->area));
357 g_assert(GTK_IS_BUTTON(part->apply));
358 g_assert(GTK_IS_BUTTON(part->reset));
360 _adg_part_link(part, &part->A, gtk_builder_get_object(builder, "editA"));
361 _adg_part_link(part, &part->B, gtk_builder_get_object(builder, "editB"));
362 _adg_part_link(part, &part->C, gtk_builder_get_object(builder, "editC"));
363 _adg_part_link(part, &part->DHOLE, gtk_builder_get_object(builder, "editDHOLE"));
364 _adg_part_link(part, &part->LHOLE, gtk_builder_get_object(builder, "editLHOLE"));
365 _adg_part_link(part, &part->D1, gtk_builder_get_object(builder, "editD1"));
366 _adg_part_link(part, &part->D2, gtk_builder_get_object(builder, "editD2"));
367 _adg_part_link(part, &part->LD2, gtk_builder_get_object(builder, "editLD2"));
368 _adg_part_link(part, &part->D3, gtk_builder_get_object(builder, "editD3"));
369 _adg_part_link(part, &part->LD3, gtk_builder_get_object(builder, "editLD3"));
370 _adg_part_link(part, &part->D4, gtk_builder_get_object(builder, "editD4"));
371 //_adg_part_link(part, &part->D5, gtk_builder_get_object(builder, "editD5"));
372 _adg_part_link(part, &part->D6, gtk_builder_get_object(builder, "editD6"));
373 //_adg_part_link(part, &part->LD6, gtk_builder_get_object(builder, "editLD6"));
374 _adg_part_link(part, &part->D7, gtk_builder_get_object(builder, "editD7"));
375 //_adg_part_link(part, &part->LD7, gtk_builder_get_object(builder, "editLD7"));
377 part->D5 = 4.5;
378 part->RD34 = 1;
379 part->LD5 = 5;
380 part->LD6 = 1;
381 part->LD7 = 0.5;
383 _adg_part_ui_to_data(part);
385 return part;
388 static void
389 _adg_part_destroy(AdgPart *part)
391 g_hash_table_destroy(part->widgets);
392 g_free(part);
395 static void
396 _adg_demo_canvas_add_sheet(AdgCanvas *canvas)
398 AdgTitleBlock *title_block;
399 AdgLogo *logo;
400 AdgMatrix map;
402 title_block = adg_title_block_new();
404 logo = adg_logo_new();
405 cairo_matrix_init_scale(&map, 2, 2);
406 adg_entity_set_global_map(ADG_ENTITY(logo), &map);
408 g_object_set(title_block,
409 "title", "SAMPLE DRAWING",
410 "author", "NtD",
411 "date", "",
412 "drawing", "TEST123",
413 "logo", logo,
414 "projection", adg_projection_new(ADG_PROJECTION_FIRST_ANGLE),
415 "scale", "NONE",
416 "size", "A4",
417 NULL);
419 adg_canvas_set_title_block(canvas, title_block);
422 static void
423 _adg_demo_canvas_add_dimensions(AdgCanvas *canvas, AdgModel *model)
425 AdgLDim *ldim;
426 AdgADim *adim;
427 AdgRDim *rdim;
429 /* NORTH */
430 adim = adg_adim_new_full_from_model(model, "-D1I", "-D1F",
431 "-D1F", "-D2I", "-D1F");
432 adg_dim_set_level(ADG_DIM(adim), 2);
433 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
435 ldim = adg_ldim_new_full_from_model(model, "-D1F", "-D3I_X", "-D3F_Y",
436 ADG_DIR_UP);
437 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
438 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
440 ldim = adg_ldim_new_full_from_model(model, "-D3I_X", "-D3F_X", "-D3F_Y",
441 ADG_DIR_UP);
442 adg_ldim_switch_extension1(ldim, FALSE);
443 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
444 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
446 ldim = adg_ldim_new_full_from_model(model, "-D6I_X", "-D67", "-East",
447 ADG_DIR_UP);
448 adg_dim_set_level(ADG_DIM(ldim), 0);
449 adg_ldim_switch_extension1(ldim, FALSE);
450 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
452 ldim = adg_ldim_new_full_from_model(model, "-D6I_X", "-D7F", "-East",
453 ADG_DIR_UP);
454 adg_dim_set_limits(ADG_DIM(ldim), "-0.06", NULL);
455 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
457 adim = adg_adim_new_full_from_model(model, "-D6I_Y", "-D6F",
458 "-D6F", "-D67", "-D6F");
459 adg_dim_set_level(ADG_DIM(adim), 2);
460 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
462 rdim = adg_rdim_new_full_from_model(model, "-RD34", "-RD34_R", "-RD34_XY");
463 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
466 /* SOUTH */
467 ldim = adg_ldim_new_full_from_model(model, "D1I", "LHOLE", "D3F_Y",
468 ADG_DIR_DOWN);
469 adg_ldim_switch_extension1(ldim, FALSE);
470 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
472 ldim = adg_ldim_new_full_from_model(model, "D4F", "D6I_X", "D4_POS",
473 ADG_DIR_DOWN);
474 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.2");
475 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
476 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
478 ldim = adg_ldim_new_full_from_model(model, "D3I_X", "D7F", "D3F_Y",
479 ADG_DIR_DOWN);
480 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
481 adg_dim_set_level(ADG_DIM(ldim), 2);
482 adg_ldim_switch_extension2(ldim, FALSE);
483 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
485 ldim = adg_ldim_new_full_from_model(model, "D1I", "D7F", "D3F_Y",
486 ADG_DIR_DOWN);
487 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
488 adg_dim_set_level(ADG_DIM(ldim), 3);
489 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
491 adim = adg_adim_new_full_from_model(model, "D4F", "D4I",
492 "D5I", "D4F", "D4F");
493 adg_dim_set_level(ADG_DIM(adim), 1.5);
494 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
496 /* EAST */
497 ldim = adg_ldim_new_full_from_model(model, "D6F", "-D6F", "East",
498 ADG_DIR_RIGHT);
499 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
500 adg_dim_set_level(ADG_DIM(ldim), 4);
501 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
502 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
504 ldim = adg_ldim_new_full_from_model(model, "D4F", "-D4F", "East",
505 ADG_DIR_RIGHT);
506 adg_dim_set_level(ADG_DIM(ldim), 3);
507 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
508 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
510 ldim = adg_ldim_new_full_from_model(model, "D5F", "-D5F", "East",
511 ADG_DIR_RIGHT);
512 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
513 adg_dim_set_level(ADG_DIM(ldim), 2);
514 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
515 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
517 ldim = adg_ldim_new_full_from_model(model, "D7F", "-D7F", "East",
518 ADG_DIR_RIGHT);
519 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
520 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
523 /* WEST */
524 ldim = adg_ldim_new_full_from_model(model, "D3I_Y", "-D3I_Y", "-West",
525 ADG_DIR_LEFT);
526 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
527 adg_dim_set_level(ADG_DIM(ldim), 4);
528 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
529 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
531 ldim = adg_ldim_new_full_from_model(model, "D1I", "-D1I", "-West",
532 ADG_DIR_LEFT);
533 adg_dim_set_limits(ADG_DIM(ldim), "+0.05", "-0.05");
534 adg_dim_set_level(ADG_DIM(ldim), 3);
535 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
536 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
538 ldim = adg_ldim_new_full_from_model(model, "D2I", "-D2I", "-West",
539 ADG_DIR_LEFT);
540 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
541 adg_dim_set_level(ADG_DIM(ldim), 2);
542 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
543 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
545 ldim = adg_ldim_new_full_from_model(model, "DHOLE", "-DHOLE", "-West",
546 ADG_DIR_LEFT);
547 adg_dim_set_value(ADG_DIM(ldim), ADG_UTF8_DIAMETER "<>");
548 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
551 static void
552 _adg_demo_canvas_add_stuff(AdgCanvas *canvas, AdgModel *model)
554 AdgToyText *toy_text;
555 AdgMatrix map;
557 toy_text = adg_toy_text_new("Rotate the mouse wheel to zoom in and out");
558 adg_entity_set_local_method(ADG_ENTITY(toy_text), ADG_MIX_DISABLED);
559 cairo_matrix_init_translate(&map, -100, 200);
560 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
561 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
563 toy_text = adg_toy_text_new("Drag with the wheel pressed to pan");
564 adg_entity_set_local_method(ADG_ENTITY(toy_text), ADG_MIX_DISABLED);
565 cairo_matrix_init_translate(&map, -100, 215);
566 adg_entity_set_global_map(ADG_ENTITY(toy_text), &map);
567 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(toy_text));
570 static AdgCanvas *
571 _adg_canvas_init(AdgCanvas *canvas, AdgPart *part)
573 AdgContainer *container;
574 AdgEntity *entity;
575 AdgMatrix map;
577 container = (AdgContainer *) canvas;
579 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part->shape)));
580 adg_container_add(container, entity);
582 entity = ADG_ENTITY(adg_hatch_new(ADG_TRAIL(part->hatch)));
583 adg_container_add(container, entity);
585 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part->edges)));
586 adg_container_add(container, entity);
588 _adg_demo_canvas_add_sheet(canvas);
589 _adg_demo_canvas_add_dimensions(canvas, ADG_MODEL(part->shape));
590 _adg_demo_canvas_add_stuff(canvas, ADG_MODEL(part->shape));
592 cairo_matrix_init_scale(&map, 7, 7);
593 adg_entity_set_local_map(ADG_ENTITY(container), &map);
595 return canvas;
598 static GtkRadioButton *
599 _adg_group_get_active(GtkRadioButton *radio_group)
601 GSList *list = gtk_radio_button_get_group(radio_group);
603 while (list) {
604 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list->data)))
605 return list->data;
607 list = list->next;
610 return NULL;
613 static void
614 _adg_save_as_response(GtkWidget *window, GtkResponseType response,
615 AdgCanvas *canvas)
617 gchar *file, *suffix;
618 GtkRadioButton *type_radio;
619 cairo_surface_t *surface = NULL;
620 void (*callback)(cairo_surface_t *, gchar *) = NULL;
622 if (response != GTK_RESPONSE_OK) {
623 gtk_widget_hide(window);
624 return;
627 file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(window));
628 if (file == NULL)
629 return;
631 type_radio = _adg_group_get_active(g_object_get_data(G_OBJECT(window),
632 "type-group"));
633 g_assert(GTK_IS_RADIO_BUTTON(type_radio));
635 suffix = gtk_widget_get_tooltip_markup(GTK_WIDGET(type_radio));
636 g_assert(suffix != NULL);
638 if (!g_str_has_suffix(file, suffix)) {
639 gchar *tmp = file;
640 file = g_strconcat(file, suffix, NULL);
641 g_free(tmp);
644 if (strcmp(suffix, ".png") == 0) {
645 #ifdef CAIRO_HAS_PNG_FUNCTIONS
646 surface = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 800, 600);
647 callback = (gpointer) cairo_surface_write_to_png;
648 #endif
649 } else if (strcmp(suffix, ".pdf") == 0) {
650 #ifdef CAIRO_HAS_PDF_SURFACE
651 #include <cairo-pdf.h>
652 surface = cairo_pdf_surface_create(file, 841, 595);
653 #endif
654 } else if (strcmp(suffix, ".ps") == 0) {
655 #ifdef CAIRO_HAS_PS_SURFACE
656 #include <cairo-ps.h>
657 surface = cairo_ps_surface_create(file, 841, 595);
658 cairo_ps_surface_dsc_comment(surface, "%%Title: " PACKAGE_STRING);
659 cairo_ps_surface_dsc_comment(surface, "%%Copyright: Copyright (C) 2006-2010 Fontana Nicola");
660 cairo_ps_surface_dsc_comment(surface, "%%Orientation: Portrait");
661 cairo_ps_surface_dsc_begin_setup(surface);
662 cairo_ps_surface_dsc_begin_page_setup(surface);
663 cairo_ps_surface_dsc_comment(surface, "%%IncludeFeature: *PageSize A4");
664 #endif
667 if (surface) {
668 cairo_t *cr = cairo_create(surface);
669 cairo_surface_destroy(surface);
670 adg_entity_render(ADG_ENTITY(canvas), cr);
671 cairo_show_page(cr);
672 if (callback)
673 callback(surface, file);
674 cairo_destroy(cr);
677 g_free(file);
678 g_free(suffix);
679 gtk_widget_hide(window);
682 static GtkWidget *
683 _adg_about_window(GtkBuilder *builder)
685 GtkWidget *window;
687 window = (GtkWidget *) gtk_builder_get_object(builder, "wndAbout");
688 g_assert(GTK_IS_ABOUT_DIALOG(window));
690 g_signal_connect(window, "response", G_CALLBACK(gtk_widget_hide), NULL);
692 return window;
696 * _adg_window_hide:
697 * @window: a #GtkWindow
699 * A convenient function that hides @window storing the current position
700 * so any subsequent call to gtk_widget_show() will hopefully reopen
701 * the window at the same position.
703 * It is useful to connect this callback to a #GtkDialog::response signal.
705 static void
706 _adg_window_hide(GtkWindow *window)
708 gint x, y;
710 g_return_if_fail(GTK_IS_WINDOW(window));
712 gtk_window_get_position(window, &x, &y);
713 gtk_widget_hide((GtkWidget *) window);
714 gtk_window_set_position(window, GTK_WIN_POS_NONE);
715 gtk_window_move(window, x, y);
718 static GtkWidget *
719 _adg_edit_window(GtkBuilder *builder, AdgPart *part)
721 GtkWidget *window;
723 window = (GtkWidget *) gtk_builder_get_object(builder, "wndEdit");
724 g_assert(GTK_IS_DIALOG(window));
726 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
728 g_signal_connect_swapped(part->apply, "clicked",
729 G_CALLBACK(_adg_part_ui_to_data), part);
730 g_signal_connect_swapped(part->reset, "clicked",
731 G_CALLBACK(_adg_part_data_to_ui), part);
732 g_signal_connect(window, "response", G_CALLBACK(_adg_window_hide), NULL);
734 return window;
737 static GtkWidget *
738 _adg_save_as_window(GtkBuilder *builder, AdgCanvas *canvas)
740 GtkWidget *window;
741 GtkWidget *type_group, *button_save;
743 window = (GtkWidget *) gtk_builder_get_object(builder, "wndSaveAs");
744 g_assert(GTK_IS_WINDOW(window));
745 type_group = (GtkWidget *) gtk_builder_get_object(builder, "saveAsPng");
746 g_assert(GTK_IS_RADIO_BUTTON(type_group));
747 button_save = (GtkWidget *) gtk_builder_get_object(builder, "saveAsSave");
748 g_assert(GTK_IS_BUTTON(button_save));
750 g_object_set_data(G_OBJECT(window), "type-group", type_group);
752 g_signal_connect(window, "response",
753 G_CALLBACK(_adg_save_as_response), canvas);
755 return window;
758 static GtkWidget *
759 _adg_main_window(GtkBuilder *builder)
761 GtkWidget *window;
762 AdgPart *part;
763 AdgCanvas *canvas;
764 GtkWidget *button_edit, *button_save_as, *button_about, *button_quit;
766 window = (GtkWidget *) gtk_builder_get_object(builder, "wndMain");
767 part = _adg_part_new(builder);
768 canvas = adg_canvas_new();
770 _adg_canvas_init(canvas, part);
771 adg_gtk_area_set_canvas(part->area, canvas);
773 g_assert(GTK_IS_WINDOW(window));
774 button_edit = (GtkWidget *) gtk_builder_get_object(builder, "mainEdit");
775 g_assert(GTK_IS_BUTTON(button_edit));
776 button_save_as = (GtkWidget *) gtk_builder_get_object(builder, "mainSaveAs");
777 g_assert(GTK_IS_BUTTON(button_save_as));
778 button_about = (GtkWidget *) gtk_builder_get_object(builder, "mainAbout");
779 g_assert(GTK_IS_BUTTON(button_about));
780 button_quit = (GtkWidget *) gtk_builder_get_object(builder, "mainQuit");
781 g_assert(GTK_IS_BUTTON(button_quit));
783 g_signal_connect_swapped(button_edit, "clicked",
784 G_CALLBACK(gtk_dialog_run),
785 _adg_edit_window(builder, part));
786 g_signal_connect_swapped(button_save_as, "clicked",
787 G_CALLBACK(gtk_dialog_run),
788 _adg_save_as_window(builder, canvas));
789 g_signal_connect_swapped(button_about, "clicked",
790 G_CALLBACK(gtk_dialog_run),
791 _adg_about_window(builder));
792 g_signal_connect(button_quit, "clicked", G_CALLBACK(gtk_main_quit), NULL);
793 g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
794 g_signal_connect_swapped(window, "destroy",
795 G_CALLBACK(_adg_part_destroy), part);
797 return window;
802 main(gint argc, gchar **argv)
804 gboolean show_extents;
805 gchar *path;
806 GtkBuilder *builder;
807 GError *error;
808 GtkWidget *main_window;
810 _adg_parse_args(&argc, &argv, &show_extents);
811 adg_switch_extents(show_extents);
813 path = demo_find_data_file("adg-demo.ui", argv[0]);
814 if (path == NULL) {
815 g_print("adg-demo.ui not found!\n");
816 return 1;
819 builder = gtk_builder_new();
820 error = NULL;
821 gtk_builder_add_from_file(builder, path, &error);
823 if (error != NULL) {
824 g_critical(error->message);
825 g_error_free(error);
826 return 2;
829 main_window = _adg_main_window(builder);
830 g_object_unref(builder);
832 gtk_widget_show_all(main_window);
833 gtk_main();
835 return 0;