ADG 

ADG Git Source Tree

Root/demo/adg-demo.c

1/* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2017 Nicola Fontana <ntd at entidi.it>
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
18 */
19
20#include "demo.h"
21#include <adg.h>
22#include <string.h>
23#include <math.h>
24
25#define SQRT3 1.732050808
26#define CHAMFER 0.3
27
28
29/* Whether render the boxes to highlight the extents of every entity */
30static gboolean show_extents = FALSE;
31
32
33typedef struct _DemoPart DemoPart;
34
35struct _DemoPart {
36 /* Dimensions */
37 gdouble A;
38 gdouble B;
39 gdouble C;
40 gdouble DHOLE;
41 gdouble LHOLE;
42 gdouble D1;
43 gdouble D2;
44 gdouble D3;
45 gdouble D4;
46 gdouble D5;
47 gdouble D6;
48 gdouble D7;
49 gdouble RD34;
50 gdouble RD56;
51 gdouble LD2;
52 gdouble LD3;
53 gdouble LD5;
54 gdouble LD6;
55 gdouble LD7;
56 gboolean GROOVE;
57 gdouble ZGROOVE;
58 gdouble DGROOVE;
59 gdouble LGROOVE;
60
61 /* Metadata */
62 gchar *TITLE;
63 gchar *DRAWING;
64 gchar *AUTHOR;
65 gchar *DATE;
66
67 /* User interface widgets */
68 AdgGtkArea *area;
69 GHashTable *widgets;
70 GtkButton *apply;
71 GtkButton *reset;
72
73 /* Data models */
74 AdgPath *body;
75 AdgPath *hole;
76 AdgPath *axis;
77
78 /* Special entities */
79 AdgTitleBlock *title_block;
80 AdgEdges *edges;
81};
82
83
84static void
85_adg_version(void)
86{
87 g_print("adg-demo " PACKAGE_VERSION "\n");
88 exit(0);
89}
90
91static void
92parse_args(gint *p_argc, gchar **p_argv[])
93{
94 GOptionEntry entries[] = {
95 {"version", 'V', G_OPTION_FLAG_NO_ARG, G_OPTION_ARG_CALLBACK,
96 (gpointer) _adg_version, _("Display version information"), NULL},
97 {"show-extents", 'E', 0, G_OPTION_ARG_NONE,
98 &show_extents, _("Show the boundary boxes of every entity"), NULL},
99 {NULL}
100 };
101 GError *error;
102
103 error = NULL;
104 gtk_init_with_args(p_argc, p_argv, _("- ADG demonstration program"),
105 entries, GETTEXT_PACKAGE, &error);
106 if (error != NULL) {
107 g_error("%s", error->message);
108 g_assert_not_reached();
109 }
110}
111
112/**
113 * _adg_error:
114 * @message: a custom error message
115 * @parent_window: the parent window or %NULL
116 *
117 * Convenient function that presents an error dialog and waits the user
118 * to close this modal dialog.
119 **/
120void
121_adg_error(const gchar *message, GtkWindow *parent_window)
122{
123 GtkWidget *dialog = gtk_message_dialog_new(parent_window,
124 GTK_DIALOG_DESTROY_WITH_PARENT,
125 GTK_MESSAGE_ERROR,
126 GTK_BUTTONS_CLOSE,
127 "%s", message);
128 gtk_window_set_title(GTK_WINDOW(dialog), _("Error from adg-demo"));
129 gtk_dialog_run(GTK_DIALOG(dialog));
130 gtk_widget_destroy(dialog);
131}
132
133static void
134_adg_path_add_groove(AdgPath *path, const DemoPart *part)
135{
136 AdgModel *model;
137 CpmlPair pair;
138
139 model = ADG_MODEL(path);
140
141 pair.x = part->ZGROOVE;
142 pair.y = part->D1 / 2;
143 adg_path_line_to(path, &pair);
144 adg_model_set_named_pair(model, "DGROOVEI_X", &pair);
145
146 pair.y = part->D3 / 2;
147 adg_model_set_named_pair(model, "DGROOVEY_POS", &pair);
148
149 pair.y = part->DGROOVE / 2;
150 adg_path_line_to(path, &pair);
151 adg_model_set_named_pair(model, "DGROOVEI_Y", &pair);
152
153 pair.x += part->LGROOVE;
154 adg_path_line_to(path, &pair);
155
156 pair.y = part->D3 / 2;
157 adg_model_set_named_pair(model, "DGROOVEX_POS", &pair);
158
159 pair.y = part->D1 / 2;
160 adg_path_line_to(path, &pair);
161 adg_model_set_named_pair(model, "DGROOVEF_X", &pair);
162}
163
164
165static void
166_adg_part_define_title_block(DemoPart *part)
167{
168 g_object_set(part->title_block,
169 "title", part->TITLE,
170 "author", part->AUTHOR,
171 "date", part->DATE,
172 "drawing", part->DRAWING,
173 "logo", adg_logo_new(),
174 "projection", adg_projection_new(ADG_PROJECTION_SCHEME_FIRST_ANGLE),
175 "size", "A4",
176 NULL);
177}
178
179static void
180_adg_part_define_hole(DemoPart *part)
181{
182 AdgPath *path;
183 AdgModel *model;
184 CpmlPair pair, edge;
185
186 path = part->hole;
187 model = ADG_MODEL(path);
188
189 pair.x = part->LHOLE;
190 pair.y = 0;
191
192 adg_path_move_to(path, &pair);
193 adg_model_set_named_pair(model, "LHOLE", &pair);
194
195 pair.y = part->DHOLE / 2;
196 pair.x -= pair.y / SQRT3;
197 adg_path_line_to(path, &pair);
198 cpml_pair_copy(&edge, &pair);
199
200 pair.x = 0;
201 adg_path_line_to(path, &pair);
202 adg_model_set_named_pair(model, "DHOLE", &pair);
203
204 pair.y = (part->D1 + part->DHOLE) / 4;
205 adg_path_line_to(path, &pair);
206
207 adg_path_curve_to_explicit(path,
208 part->LHOLE / 2, part->DHOLE / 2,
209 part->LHOLE + 2, part->D1 / 2,
210 part->LHOLE + 2, 0);
211 adg_path_reflect(path, NULL);
212 adg_path_join(path);
213 adg_path_close(path);
214
215 /* No need to incomodate an AdgEdge model for two reasons:
216 * it is only a single line and it is always needed */
217 adg_path_move_to(path, &edge);
218 edge.y = -edge.y;
219 adg_path_line_to(path, &edge);
220}
221
222static void
223_adg_part_define_body(DemoPart *part)
224{
225 AdgModel *model;
226 AdgPath *path;
227 CpmlPair pair, tmp;
228 const CpmlPrimitive *primitive;
229
230 path = part->body;
231 model = ADG_MODEL(path);
232
233 pair.x = 0;
234 pair.y = part->D1 / 2;
235 adg_path_move_to(path, &pair);
236 adg_model_set_named_pair(model, "D1I", &pair);
237
238 if (part->GROOVE) {
239 _adg_path_add_groove(path, part);
240 }
241
242 pair.x = part->A - part->B - part->LD2;
243 adg_path_line_to(path, &pair);
244 adg_model_set_named_pair(model, "D1F", &pair);
245
246 pair.y = part->D3 / 2;
247 adg_model_set_named_pair(model, "D2_POS", &pair);
248
249 pair.x += (part->D1 - part->D2) / 2;
250 pair.y = part->D2 / 2;
251 adg_path_line_to(path, &pair);
252 adg_model_set_named_pair(model, "D2I", &pair);
253
254 pair.x = part->A - part->B;
255 adg_path_line_to(path, &pair);
256 adg_path_fillet(path, 0.4);
257
258 pair.x = part->A - part->B;
259 pair.y = part->D3 / 2;
260 adg_path_line_to(path, &pair);
261 adg_model_set_named_pair(model, "D3I", &pair);
262
263 pair.x = part->A;
264 adg_model_set_named_pair(model, "East", &pair);
265
266 pair.x = 0;
267 adg_model_set_named_pair(model, "West", &pair);
268
269 adg_path_chamfer(path, CHAMFER, CHAMFER);
270
271 pair.x = part->A - part->B + part->LD3;
272 pair.y = part->D3 / 2;
273 adg_path_line_to(path, &pair);
274
275 primitive = adg_path_over_primitive(path);
276 cpml_primitive_put_point(primitive, 0, &tmp);
277 adg_model_set_named_pair(model, "D3I_X", &tmp);
278
279 cpml_primitive_put_point(primitive, -1, &tmp);
280 adg_model_set_named_pair(model, "D3I_Y", &tmp);
281
282 adg_path_chamfer(path, CHAMFER, CHAMFER);
283
284 pair.y = part->D4 / 2;
285 adg_path_line_to(path, &pair);
286
287 primitive = adg_path_over_primitive(path);
288 cpml_primitive_put_point(primitive, 0, &tmp);
289 adg_model_set_named_pair(model, "D3F_Y", &tmp);
290 cpml_primitive_put_point(primitive, -1, &tmp);
291 adg_model_set_named_pair(model, "D3F_X", &tmp);
292
293 adg_path_fillet(path, part->RD34);
294
295 pair.x += part->RD34;
296 adg_model_set_named_pair(model, "D4I", &pair);
297
298 pair.x = part->A - part->C - part->LD5;
299 adg_path_line_to(path, &pair);
300 adg_model_set_named_pair(model, "D4F", &pair);
301
302 pair.y = part->D3 / 2;
303 adg_model_set_named_pair(model, "D4_POS", &pair);
304
305 primitive = adg_path_over_primitive(path);
306 cpml_primitive_put_point(primitive, 0, &tmp);
307 tmp.x += part->RD34;
308 adg_model_set_named_pair(model, "RD34", &tmp);
309
310 tmp.x -= cos(G_PI_4) * part->RD34,
311 tmp.y -= sin(G_PI_4) * part->RD34,
312 adg_model_set_named_pair(model, "RD34_R", &tmp);
313
314 tmp.x += part->RD34,
315 tmp.y += part->RD34,
316 adg_model_set_named_pair(model, "RD34_XY", &tmp);
317
318 pair.x += (part->D4 - part->D5) / 2;
319 pair.y = part->D5 / 2;
320 adg_path_line_to(path, &pair);
321 adg_model_set_named_pair(model, "D5I", &pair);
322
323 pair.x = part->A - part->C;
324 adg_path_line_to(path, &pair);
325
326 adg_path_fillet(path, 0.2);
327
328 pair.y = part->D6 / 2;
329 adg_path_line_to(path, &pair);
330
331 primitive = adg_path_over_primitive(path);
332 cpml_primitive_put_point(primitive, 0, &tmp);
333 adg_model_set_named_pair(model, "D5F", &tmp);
334
335 adg_path_fillet(path, 0.1);
336
337 pair.x += part->LD6;
338 adg_path_line_to(path, &pair);
339 adg_model_set_named_pair(model, "D6F", &pair);
340
341 primitive = adg_path_over_primitive(path);
342 cpml_primitive_put_point(primitive, 0, &tmp);
343 adg_model_set_named_pair(model, "D6I_X", &tmp);
344
345 primitive = adg_path_over_primitive(path);
346 cpml_primitive_put_point(primitive, -1, &tmp);
347 adg_model_set_named_pair(model, "D6I_Y", &tmp);
348
349 pair.x = part->A - part->LD7;
350 pair.y -= (part->C - part->LD7 - part->LD6) / SQRT3;
351 adg_path_line_to(path, &pair);
352 adg_model_set_named_pair(model, "D67", &pair);
353
354 pair.y = part->D7 / 2;
355 adg_path_line_to(path, &pair);
356
357 pair.x = part->A;
358 adg_path_line_to(path, &pair);
359 adg_model_set_named_pair(model, "D7F", &pair);
360
361 adg_path_reflect(path, NULL);
362 adg_path_join(path);
363 adg_path_close(path);
364}
365
366static void
367_adg_part_define_axis(DemoPart *part)
368{
369 AdgPath *path;
370
371 path = part->axis;
372
373 /* XXX: actually the end points can extend outside the body
374 * only in local space. The proper extension values should be
375 * expressed in global space but actually is impossible to
376 * combine local and global space in the AdgPath API.
377 */
378 adg_path_move_to_explicit(path, -1, 0);
379 adg_path_line_to_explicit(path, part->A + 1, 0);
380}
381
382static void
383_adg_part_lock(DemoPart *part)
384{
385 gtk_widget_set_sensitive(GTK_WIDGET(part->apply), FALSE);
386 gtk_widget_set_sensitive(GTK_WIDGET(part->reset), FALSE);
387}
388
389static void
390_adg_part_unlock(DemoPart *part)
391{
392 gtk_widget_set_sensitive(GTK_WIDGET(part->apply), TRUE);
393 gtk_widget_set_sensitive(GTK_WIDGET(part->reset), TRUE);
394}
395
396static void
397_adg_part_link(DemoPart *part, gpointer data, GObject *widget)
398{
399 const gchar *edit_signal;
400
401 g_assert(GTK_IS_WIDGET(widget));
402 g_object_ref(widget);
403 g_hash_table_insert(part->widgets, data, widget);
404
405 edit_signal = GTK_IS_TOGGLE_BUTTON(widget) ? "toggled" : "changed";
406 g_signal_connect_swapped(widget, edit_signal,
407 G_CALLBACK(_adg_part_unlock), part);
408}
409
410static void
411_adg_part_ui_to_boolean(DemoPart *part, gboolean *data)
412{
413 GtkWidget *widget = g_hash_table_lookup(part->widgets, data);
414
415 g_assert(GTK_IS_TOGGLE_BUTTON(widget));
416
417 *data = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
418}
419
420static void
421_adg_part_ui_to_double(DemoPart *part, gdouble *data)
422{
423 GtkWidget *widget;
424 GtkSpinButton *spin_button;
425
426 widget = g_hash_table_lookup(part->widgets, data);
427 g_assert(GTK_IS_SPIN_BUTTON(widget));
428
429 spin_button = GTK_SPIN_BUTTON(widget);
430 gtk_spin_button_update(spin_button);
431 *data = gtk_spin_button_get_value(spin_button);
432}
433
434static void
435_adg_part_ui_to_string(DemoPart *part, gchar **data)
436{
437 GtkWidget *widget = g_hash_table_lookup(part->widgets, data);
438
439 g_assert(GTK_IS_ENTRY(widget));
440
441 g_free(*data);
442 *data = g_strdup(gtk_entry_get_text(GTK_ENTRY(widget)));
443}
444
445static void
446_adg_part_boolean_to_ui(DemoPart *part, gboolean *data)
447{
448 GtkWidget *widget = g_hash_table_lookup(part->widgets, data);
449
450 g_assert(GTK_IS_TOGGLE_BUTTON(widget));
451
452 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), *data);
453}
454
455static void
456_adg_part_double_to_ui(DemoPart *part, gdouble *data)
457{
458 GtkWidget *widget = g_hash_table_lookup(part->widgets, data);
459
460 g_assert(GTK_IS_SPIN_BUTTON(widget));
461
462 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), *data);
463}
464
465static void
466_adg_part_string_to_ui(DemoPart *part, gchar **data)
467{
468 GtkWidget *widget = g_hash_table_lookup(part->widgets, data);
469
470 g_assert(GTK_IS_ENTRY(widget));
471
472 gtk_entry_set_text(GTK_ENTRY(widget), *data);
473}
474
475static void
476_adg_demo_canvas_add_dimensions(AdgCanvas *canvas, AdgModel *model)
477{
478 AdgLDim *ldim;
479 AdgADim *adim;
480 AdgRDim *rdim;
481 AdgStyle *style, *diameter;
482
483 style = adg_dress_get_fallback(ADG_DRESS_DIMENSION);
484 diameter = adg_style_clone(style);
485 adg_dim_style_set_number_format(ADG_DIM_STYLE(diameter), ADG_UTF8_DIAMETER "%g");
486
487 /* NORTH */
488 ldim = adg_ldim_new_full_from_model(model, "-D3I_X", "-D3F_X", "-D3F_Y",
489 ADG_DIR_UP);
490 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
491 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
492
493 ldim = adg_ldim_new_full_from_model(model, "-D6I_X", "-D67", "-East",
494 ADG_DIR_UP);
495 adg_dim_set_level(ADG_DIM(ldim), 0);
496 adg_ldim_switch_extension1(ldim, FALSE);
497 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
498
499 ldim = adg_ldim_new_full_from_model(model, "-D6I_X", "-D7F", "-East",
500 ADG_DIR_UP);
501 adg_dim_set_limits(ADG_DIM(ldim), "-0.06", NULL);
502 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
503
504 adim = adg_adim_new_full_from_model(model, "-D6I_Y", "-D6F",
505 "-D6F", "-D67", "-D6F");
506 adg_dim_set_level(ADG_DIM(adim), 2);
507 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
508
509 rdim = adg_rdim_new_full_from_model(model, "-RD34", "-RD34_R", "-RD34_XY");
510 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(rdim));
511
512 ldim = adg_ldim_new_full_from_model(model, "-DGROOVEI_X", "-DGROOVEF_X",
513 "-DGROOVEX_POS", ADG_DIR_UP);
514 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
515
516 ldim = adg_ldim_new_full_from_model(model, "D2I", "-D2I", "-D2_POS",
517 ADG_DIR_LEFT);
518 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
519 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
520 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
521 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
522
523 ldim = adg_ldim_new_full_from_model(model, "DGROOVEI_Y", "-DGROOVEI_Y",
524 "-DGROOVEY_POS", ADG_DIR_LEFT);
525 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
526 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
527 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
528 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
529
530 /* SOUTH */
531 adim = adg_adim_new_full_from_model(model, "D1F", "D1I", "D2I", "D1F", "D1F");
532 adg_dim_set_level(ADG_DIM(adim), 2);
533 adg_adim_switch_extension2(adim, FALSE);
534 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
535
536 ldim = adg_ldim_new_full_from_model(model, "D1I", "LHOLE", "West",
537 ADG_DIR_DOWN);
538 adg_ldim_switch_extension1(ldim, FALSE);
539 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
540
541 ldim = adg_ldim_new_full_from_model(model, "D1I", "DGROOVEI_X", "West",
542 ADG_DIR_DOWN);
543 adg_ldim_switch_extension1(ldim, FALSE);
544 adg_dim_set_level(ADG_DIM(ldim), 2);
545 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
546
547 ldim = adg_ldim_new_full_from_model(model, "D4F", "D6I_X", "D4_POS",
548 ADG_DIR_DOWN);
549 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.2");
550 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
551 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
552
553 ldim = adg_ldim_new_full_from_model(model, "D1F", "D3I_X", "D2_POS",
554 ADG_DIR_DOWN);
555 adg_dim_set_level(ADG_DIM(ldim), 2);
556 adg_ldim_switch_extension2(ldim, FALSE);
557 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
558 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
559
560 ldim = adg_ldim_new_full_from_model(model, "D3I_X", "D7F", "East",
561 ADG_DIR_DOWN);
562 adg_dim_set_limits(ADG_DIM(ldim), NULL, "+0.1");
563 adg_dim_set_level(ADG_DIM(ldim), 2);
564 adg_dim_set_outside(ADG_DIM(ldim), ADG_THREE_STATE_OFF);
565 adg_ldim_switch_extension2(ldim, FALSE);
566 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
567
568 ldim = adg_ldim_new_full_from_model(model, "D1I", "D7F", "D3F_Y",
569 ADG_DIR_DOWN);
570 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
571 adg_dim_set_level(ADG_DIM(ldim), 3);
572 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
573
574 adim = adg_adim_new_full_from_model(model, "D4F", "D4I",
575 "D5I", "D4F", "D4F");
576 adg_dim_set_level(ADG_DIM(adim), 1.5);
577 adg_adim_switch_extension2(adim, FALSE);
578 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(adim));
579
580 /* EAST */
581 ldim = adg_ldim_new_full_from_model(model, "D6F", "-D6F", "East",
582 ADG_DIR_RIGHT);
583 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
584 adg_dim_set_level(ADG_DIM(ldim), 4);
585 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
586 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
587
588 ldim = adg_ldim_new_full_from_model(model, "D4F", "-D4F", "East",
589 ADG_DIR_RIGHT);
590 adg_dim_set_level(ADG_DIM(ldim), 3);
591 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
592 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
593
594 ldim = adg_ldim_new_full_from_model(model, "D5F", "-D5F", "East",
595 ADG_DIR_RIGHT);
596 adg_dim_set_limits(ADG_DIM(ldim), "-0.1", NULL);
597 adg_dim_set_level(ADG_DIM(ldim), 2);
598 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
599 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
600
601 ldim = adg_ldim_new_full_from_model(model, "D7F", "-D7F", "East",
602 ADG_DIR_RIGHT);
603 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
604 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
605
606 /* WEST */
607 ldim = adg_ldim_new_full_from_model(model, "DHOLE", "-DHOLE", "-West",
608 ADG_DIR_LEFT);
609 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
610 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
611
612 ldim = adg_ldim_new_full_from_model(model, "D1I", "-D1I", "-West",
613 ADG_DIR_LEFT);
614 adg_dim_set_limits(ADG_DIM(ldim), "-0.05", "+0.05");
615 adg_dim_set_level(ADG_DIM(ldim), 2);
616 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
617 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
618
619 ldim = adg_ldim_new_full_from_model(model, "D3I_Y", "-D3I_Y", "-West",
620 ADG_DIR_LEFT);
621 adg_dim_set_limits(ADG_DIM(ldim), "-0.25", NULL);
622 adg_dim_set_level(ADG_DIM(ldim), 3);
623 adg_entity_set_style(ADG_ENTITY(ldim), ADG_DRESS_DIMENSION, diameter);
624 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(ldim));
625}
626
627static void
628_adg_demo_canvas_add_axis(AdgCanvas *canvas, AdgTrail *trail)
629{
630 AdgStroke *stroke = adg_stroke_new(trail);
631 adg_stroke_set_line_dress(stroke, ADG_DRESS_LINE_AXIS);
632 adg_container_add(ADG_CONTAINER(canvas), ADG_ENTITY(stroke));
633}
634
635static AdgCanvas *
636_adg_canvas_init(AdgCanvas *canvas, DemoPart *part)
637{
638 AdgContainer *container;
639 AdgEntity *entity;
640
641 container = (AdgContainer *) canvas;
642
643 adg_canvas_set_paper(canvas, GTK_PAPER_NAME_A4,
644 GTK_PAGE_ORIENTATION_LANDSCAPE);
645 adg_canvas_set_title_block(canvas, part->title_block);
646
647 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part->body)));
648 adg_container_add(container, entity);
649
650 entity = ADG_ENTITY(adg_hatch_new(ADG_TRAIL(part->hole)));
651 adg_container_add(container, entity);
652
653 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part->hole)));
654 adg_container_add(container, entity);
655
656 entity = ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part->edges)));
657 adg_container_add(container, entity);
658
659 _adg_demo_canvas_add_dimensions(canvas, ADG_MODEL(part->body));
660
661 _adg_demo_canvas_add_axis(canvas, ADG_TRAIL(part->axis));
662
663 return canvas;
664}
665
666static GtkRadioButton *
667_adg_group_get_active(GtkRadioButton *radio_group)
668{
669 GSList *list = gtk_radio_button_get_group(radio_group);
670
671 while (list) {
672 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list->data)))
673 return list->data;
674
675 list = list->next;
676 }
677
678 return NULL;
679}
680
681static void
682_adg_do_edit(DemoPart *part)
683{
684 _adg_part_ui_to_double(part, &part->A);
685 _adg_part_ui_to_double(part, &part->B);
686 _adg_part_ui_to_double(part, &part->C);
687 _adg_part_ui_to_double(part, &part->DHOLE);
688 _adg_part_ui_to_double(part, &part->LHOLE);
689 _adg_part_ui_to_double(part, &part->D1);
690 _adg_part_ui_to_double(part, &part->D2);
691 _adg_part_ui_to_double(part, &part->LD2);
692 _adg_part_ui_to_double(part, &part->D3);
693 _adg_part_ui_to_double(part, &part->LD3);
694 _adg_part_ui_to_double(part, &part->D4);
695 //_adg_part_ui_to_double(part, &part->D5);
696 _adg_part_ui_to_double(part, &part->D6);
697 //_adg_part_ui_to_double(part, &part->LD6);
698 _adg_part_ui_to_double(part, &part->D7);
699 //_adg_part_ui_to_double(part, &part->LD7);
700
701 _adg_part_ui_to_boolean(part, &part->GROOVE);
702 _adg_part_ui_to_double(part, &part->ZGROOVE);
703 _adg_part_ui_to_double(part, &part->DGROOVE);
704 _adg_part_ui_to_double(part, &part->LGROOVE);
705
706 _adg_part_ui_to_string(part, &part->TITLE);
707 _adg_part_ui_to_string(part, &part->DRAWING);
708 _adg_part_ui_to_string(part, &part->AUTHOR);
709 _adg_part_ui_to_string(part, &part->DATE);
710
711 _adg_part_lock(part);
712
713 adg_model_reset(ADG_MODEL(part->body));
714 adg_model_reset(ADG_MODEL(part->hole));
715 adg_model_reset(ADG_MODEL(part->axis));
716 adg_model_reset(ADG_MODEL(part->edges));
717
718 _adg_part_define_title_block(part);
719 _adg_part_define_body(part);
720 _adg_part_define_hole(part);
721 _adg_part_define_axis(part);
722
723 adg_model_changed(ADG_MODEL(part->body));
724 adg_model_changed(ADG_MODEL(part->hole));
725 adg_model_changed(ADG_MODEL(part->axis));
726 adg_model_changed(ADG_MODEL(part->edges));
727
728 gtk_widget_queue_draw(GTK_WIDGET(part->area));
729}
730
731static void
732_adg_do_reset(DemoPart *part)
733{
734 _adg_part_double_to_ui(part, &part->A);
735 _adg_part_double_to_ui(part, &part->B);
736 _adg_part_double_to_ui(part, &part->C);
737 _adg_part_double_to_ui(part, &part->DHOLE);
738 _adg_part_double_to_ui(part, &part->LHOLE);
739 _adg_part_double_to_ui(part, &part->D1);
740 _adg_part_double_to_ui(part, &part->D2);
741 _adg_part_double_to_ui(part, &part->LD2);
742 _adg_part_double_to_ui(part, &part->D3);
743 _adg_part_double_to_ui(part, &part->LD3);
744 _adg_part_double_to_ui(part, &part->D4);
745 //_adg_part_double_to_ui(part, &part->D5);
746 _adg_part_double_to_ui(part, &part->D6);
747 //_adg_part_double_to_ui(part, &part->LD6);
748 _adg_part_double_to_ui(part, &part->D7);
749 //_adg_part_double_to_ui(part, &part->LD7);
750
751 _adg_part_boolean_to_ui(part, &part->GROOVE);
752 _adg_part_double_to_ui(part, &part->ZGROOVE);
753 _adg_part_double_to_ui(part, &part->DGROOVE);
754 _adg_part_double_to_ui(part, &part->LGROOVE);
755
756 _adg_part_string_to_ui(part, &part->TITLE);
757 _adg_part_string_to_ui(part, &part->DRAWING);
758 _adg_part_string_to_ui(part, &part->AUTHOR);
759 _adg_part_string_to_ui(part, &part->DATE);
760
761 _adg_part_lock(part);
762}
763
764static void
765_adg_do_save_as(GtkWindow *window, GtkResponseType response, AdgCanvas *canvas)
766{
767 GtkRadioButton *type_radio;
768 gchar *file, *suffix;
769 cairo_surface_type_t type;
770 GError *error;
771
772 if (response != GTK_RESPONSE_OK) {
773 gtk_widget_hide(GTK_WIDGET(window));
774 return;
775 }
776
777 file = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(window));
778 if (file == NULL)
779 return;
780
781 type_radio = _adg_group_get_active(g_object_get_data(G_OBJECT(window),
782 "type-group"));
783 g_assert(GTK_IS_RADIO_BUTTON(type_radio));
784
785 suffix = gtk_widget_get_tooltip_markup(GTK_WIDGET(type_radio));
786 if (suffix != NULL) {
787 /* Avoid double extension on the filename */
788 if (! g_str_has_suffix(file, suffix)) {
789 gchar *tmp = file;
790 file = g_strconcat(file, suffix, NULL);
791 g_free(tmp);
792 }
793 g_free(suffix);
794 }
795
796 error = NULL;
797 type = adg_type_from_filename(file);
798
799 if (type == CAIRO_SURFACE_TYPE_XLIB) {
800 g_set_error(&error, ADG_CANVAS_ERROR, ADG_CANVAS_ERROR_SURFACE, "%s",
801 _("Requested format not supported"));
802 } else {
803 adg_canvas_export(canvas, type, file, &error);
804 }
805
806 g_free(file);
807 if (error != NULL) {
808 _adg_error(error->message, window);
809 g_error_free(error);
810 }
811
812 gtk_widget_hide(GTK_WIDGET(window));
813}
814
815static void
816_adg_print_prepare(GtkPrintOperation *operation, GtkPrintContext *context)
817{
818 gtk_print_operation_set_n_pages(operation, 1);
819}
820
821static void
822_adg_print_page(GtkPrintOperation *operation, GtkPrintContext *context,
823 gint page_nr, AdgEntity *canvas)
824{
825 cairo_t *cr = gtk_print_context_get_cairo_context(context);
826 cairo_matrix_t old_map;
827
828 adg_matrix_copy(&old_map, adg_entity_get_global_map(canvas));;
829
830 adg_entity_set_global_map(canvas, adg_matrix_identity());
831 adg_entity_render(canvas, cr);
832
833 adg_entity_set_global_map(canvas, &old_map);
834}
835
836static void
837_adg_do_print(GtkWidget *button, AdgCanvas *canvas)
838{
839 static GtkPrintSettings *settings = NULL;
840 GtkWindow *window;
841 GtkPrintOperation *operation;
842 GtkPageSetup *page_setup;
843 GError *error;
844
845 window = (GtkWindow *) gtk_widget_get_toplevel(button);
846 operation = gtk_print_operation_new();
847 page_setup = adg_canvas_get_page_setup(canvas);
848 error = NULL;
849
850 if (settings)
851 gtk_print_operation_set_print_settings(operation, settings);
852 if (page_setup)
853 gtk_print_operation_set_default_page_setup(operation, page_setup);
854
855 g_signal_connect(operation, "begin-print",
856 G_CALLBACK(_adg_print_prepare), NULL);
857 g_signal_connect(operation, "draw-page",
858 G_CALLBACK(_adg_print_page), canvas);
859
860 gtk_print_operation_set_use_full_page(operation, FALSE);
861 gtk_print_operation_set_unit(operation, GTK_UNIT_POINTS);
862#if GTK_CHECK_VERSION(2, 18, 0)
863 gtk_print_operation_set_embed_page_setup(operation, TRUE);
864#endif
865
866 switch (gtk_print_operation_run(operation,
867 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
868 window, &error)) {
869
870 case GTK_PRINT_OPERATION_RESULT_APPLY:
871 if (settings)
872 g_object_unref(settings);
873 settings = gtk_print_operation_get_print_settings(operation);
874 if (settings)
875 g_object_ref(settings);
876 break;
877
878 default:
879 break;
880 }
881
882 g_object_unref(operation);
883
884 if (error)
885 _adg_error(error->message, window);
886}
887
888static gboolean
889_adg_button_press(AdgGtkArea *area, GdkEventButton *event)
890{
891 AdgCanvas *canvas;
892
893 if (event->button != 1 && event->button != 3)
894 return FALSE;
895
896 canvas = adg_gtk_area_get_canvas(area);
897 g_return_val_if_fail(ADG_IS_CANVAS(canvas), FALSE);
898
899 if (event->button == 1) {
900 /* Restore the original zoom */
901 adg_gtk_area_reset(area);
902 } else if (event->button == 3) {
903 adg_canvas_autoscale(canvas);
904 gtk_widget_queue_draw((GtkWidget *) area);
905 }
906
907 return FALSE;
908}
909
910static DemoPart *
911_adg_part_new(GtkBuilder *builder)
912{
913 DemoPart *part;
914 GObject *object, *toggle_object;
915
916 part = g_new0(DemoPart, 1);
917 part->widgets = g_hash_table_new_full(g_direct_hash, g_direct_equal,
918 NULL, g_object_unref);
919 part->area = (AdgGtkArea *) gtk_builder_get_object(builder, "mainCanvas");
920 part->apply = (GtkButton *) gtk_builder_get_object(builder, "btnApply");
921 part->reset = (GtkButton *) gtk_builder_get_object(builder, "btnReset");
922 part->body = adg_path_new();
923 part->hole = adg_path_new();
924 part->axis = adg_path_new();
925 part->title_block = adg_title_block_new();
926 part->edges = adg_edges_new_with_source(ADG_TRAIL(part->body));
927
928 g_assert(ADG_GTK_IS_AREA(part->area));
929 g_assert(GTK_IS_BUTTON(part->apply));
930 g_assert(GTK_IS_BUTTON(part->reset));
931
932 _adg_part_link(part, &part->A, gtk_builder_get_object(builder, "editA"));
933 _adg_part_link(part, &part->B, gtk_builder_get_object(builder, "editB"));
934 _adg_part_link(part, &part->C, gtk_builder_get_object(builder, "editC"));
935 _adg_part_link(part, &part->D1, gtk_builder_get_object(builder, "editD1"));
936 _adg_part_link(part, &part->D2, gtk_builder_get_object(builder, "editD2"));
937 _adg_part_link(part, &part->LD2, gtk_builder_get_object(builder, "editLD2"));
938 _adg_part_link(part, &part->D3, gtk_builder_get_object(builder, "editD3"));
939 _adg_part_link(part, &part->LD3, gtk_builder_get_object(builder, "editLD3"));
940 _adg_part_link(part, &part->D4, gtk_builder_get_object(builder, "editD4"));
941 //_adg_part_link(part, &part->D5, gtk_builder_get_object(builder, "editD5"));
942 _adg_part_link(part, &part->D6, gtk_builder_get_object(builder, "editD6"));
943 //_adg_part_link(part, &part->LD6, gtk_builder_get_object(builder, "editLD6"));
944 _adg_part_link(part, &part->D7, gtk_builder_get_object(builder, "editD7"));
945 //_adg_part_link(part, &part->LD7, gtk_builder_get_object(builder, "editLD7"));
946 _adg_part_link(part, &part->DHOLE, gtk_builder_get_object(builder, "editDHOLE"));
947 _adg_part_link(part, &part->LHOLE, gtk_builder_get_object(builder, "editLHOLE"));
948
949 g_signal_connect(part->area, "button-press-event",
950 G_CALLBACK(_adg_button_press), NULL);
951
952 toggle_object = gtk_builder_get_object(builder, "editGROOVE");
953 _adg_part_link(part, &part->GROOVE, toggle_object);
954
955 object = gtk_builder_get_object(builder, "editZGROOVE");
956 _adg_part_link(part, &part->ZGROOVE, object);
957 g_signal_connect(toggle_object, "toggled",
958 G_CALLBACK(adg_gtk_toggle_button_sensitivize), object);
959 object = gtk_builder_get_object(builder, "editZGROOVELabel");
960 g_signal_connect(toggle_object, "toggled",
961 G_CALLBACK(adg_gtk_toggle_button_sensitivize), object);
962
963 object = gtk_builder_get_object(builder, "editDGROOVE");
964 _adg_part_link(part, &part->DGROOVE, object);
965 g_signal_connect(toggle_object, "toggled",
966 G_CALLBACK(adg_gtk_toggle_button_sensitivize), object);
967 object = gtk_builder_get_object(builder, "editDGROOVELabel");
968 g_signal_connect(toggle_object, "toggled",
969 G_CALLBACK(adg_gtk_toggle_button_sensitivize), object);
970
971 object = gtk_builder_get_object(builder, "editLGROOVE");
972 _adg_part_link(part, &part->LGROOVE, object);
973 g_signal_connect(toggle_object, "toggled",
974 G_CALLBACK(adg_gtk_toggle_button_sensitivize), object);
975 object = gtk_builder_get_object(builder, "editLGROOVELabel");
976 g_signal_connect(toggle_object, "toggled",
977 G_CALLBACK(adg_gtk_toggle_button_sensitivize), object);
978
979 _adg_part_link(part, &part->TITLE, gtk_builder_get_object(builder, "editTITLE"));
980 _adg_part_link(part, &part->DRAWING, gtk_builder_get_object(builder, "editDRAWING"));
981 _adg_part_link(part, &part->AUTHOR, gtk_builder_get_object(builder, "editAUTHOR"));
982 _adg_part_link(part, &part->DATE, gtk_builder_get_object(builder, "editDATE"));
983
984 part->D5 = 4.5;
985 part->RD34 = 1;
986 part->LD5 = 5;
987 part->LD6 = 1;
988 part->LD7 = 0.5;
989
990 _adg_do_edit(part);
991
992 return part;
993}
994
995static void
996_adg_part_destroy(DemoPart *part)
997{
998 g_hash_table_destroy(part->widgets);
999 g_free(part);
1000}
1001
1002static GtkWidget *
1003_adg_help_window(GtkBuilder *builder)
1004{
1005 GtkWidget *window;
1006
1007 window = (GtkWidget *) gtk_builder_get_object(builder, "wndHelp");
1008 g_assert(GTK_IS_MESSAGE_DIALOG(window));
1009 g_signal_connect(window, "response", G_CALLBACK(gtk_widget_hide), NULL);
1010
1011 return window;
1012}
1013
1014static GtkWidget *
1015_adg_about_window(GtkBuilder *builder)
1016{
1017 GtkWidget *window;
1018 GList *icon_list, *last_node;
1019
1020 window = (GtkWidget *) gtk_builder_get_object(builder, "wndAbout");
1021 g_assert(GTK_IS_ABOUT_DIALOG(window));
1022 g_signal_connect(window, "response", G_CALLBACK(gtk_widget_hide), NULL);
1023
1024 icon_list = gtk_window_get_default_icon_list();
1025 last_node = g_list_last(icon_list);
1026 if (last_node != NULL) {
1027 /* The last icon is supposed to be the largest one:
1028 * check adg_gtk_use_default_icons() implementation. */
1029 GdkPixbuf *last_icon = last_node->data;
1030 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(window), last_icon);
1031 }
1032 g_list_free(icon_list);
1033
1034 return window;
1035}
1036
1037static GtkWidget *
1038_adg_edit_window(GtkBuilder *builder, DemoPart *part)
1039{
1040 GtkWidget *window;
1041
1042 window = (GtkWidget *) gtk_builder_get_object(builder, "wndEdit");
1043 g_assert(GTK_IS_DIALOG(window));
1044
1045 gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_MOUSE);
1046
1047 g_signal_connect_swapped(part->apply, "clicked",
1048 G_CALLBACK(_adg_do_edit), part);
1049 g_signal_connect_swapped(part->reset, "clicked",
1050 G_CALLBACK(_adg_do_reset), part);
1051 g_signal_connect(window, "response",
1052 G_CALLBACK(adg_gtk_window_hide_here), NULL);
1053
1054 return window;
1055}
1056
1057static GtkWidget *
1058_adg_save_as_window(GtkBuilder *builder, AdgCanvas *canvas)
1059{
1060 GtkWidget *window;
1061 GtkWidget *type_group;
1062
1063 window = (GtkWidget *) gtk_builder_get_object(builder, "wndSaveAs");
1064 g_assert(GTK_IS_WINDOW(window));
1065 type_group = (GtkWidget *) gtk_builder_get_object(builder, "saveAsPng");
1066 g_assert(GTK_IS_RADIO_BUTTON(type_group));
1067
1068 g_object_set_data(G_OBJECT(window), "type-group", type_group);
1069
1070 /* Set the default destination file */
1071 if (GTK_IS_FILE_CHOOSER(window)) {
1072 GtkFileChooser *file_chooser;
1073 const gchar *dir;
1074
1075 file_chooser = (GtkFileChooser *) window;
1076
1077#if GLIB_CHECK_VERSION(2, 14, 0)
1078 dir = g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS);
1079#else
1080 dir = NULL;
1081#endif
1082
1083 if (dir == NULL)
1084 dir = g_get_home_dir();
1085
1086 gtk_file_chooser_set_current_folder(file_chooser, dir);
1087 gtk_file_chooser_set_current_name(file_chooser, "adg-demo");
1088 }
1089
1090 g_signal_connect(window, "response", G_CALLBACK(_adg_do_save_as), canvas);
1091
1092 return window;
1093}
1094
1095static GtkWidget *
1096_adg_main_window(GtkBuilder *builder)
1097{
1098 GtkWidget *window;
1099 DemoPart *part;
1100 AdgCanvas *canvas;
1101 GtkWidget *button_edit, *button_save_as, *button_print;
1102 GtkWidget *button_help, *button_about, *button_quit;
1103
1104 if (is_installed) {
1105#ifdef G_OS_WIN32
1106 gchar *icondir = g_build_filename(basedir, PKGDATADIR, NULL);
1107 adg_gtk_use_default_icons(icondir);
1108 g_free(icondir);
1109#else
1110 adg_gtk_use_default_icons(PKGDATADIR);
1111#endif
1112 } else {
1113 adg_gtk_use_default_icons(SRCDIR);
1114 }
1115
1116 window = (GtkWidget *) gtk_builder_get_object(builder, "wndMain");
1117 part = _adg_part_new(builder);
1118 canvas = adg_canvas_new();
1119
1120 _adg_canvas_init(canvas, part);
1121 adg_gtk_area_set_canvas(part->area, canvas);
1122 adg_canvas_autoscale(canvas);
1123
1124 button_help = (GtkWidget *) gtk_builder_get_object(builder, "mainHelp");
1125 g_assert(GTK_IS_BUTTON(button_help));
1126 button_about = (GtkWidget *) gtk_builder_get_object(builder, "mainAbout");
1127 g_assert(GTK_IS_BUTTON(button_about));
1128 g_assert(GTK_IS_WINDOW(window));
1129 button_edit = (GtkWidget *) gtk_builder_get_object(builder, "mainEdit");
1130 g_assert(GTK_IS_BUTTON(button_edit));
1131 button_save_as = (GtkWidget *) gtk_builder_get_object(builder, "mainSaveAs");
1132 g_assert(GTK_IS_BUTTON(button_save_as));
1133 button_print = (GtkWidget *) gtk_builder_get_object(builder, "mainPrint");
1134 g_assert(GTK_IS_BUTTON(button_print));
1135 button_quit = (GtkWidget *) gtk_builder_get_object(builder, "mainQuit");
1136 g_assert(GTK_IS_BUTTON(button_quit));
1137
1138 g_signal_connect_swapped(button_help, "clicked",
1139 G_CALLBACK(gtk_dialog_run),
1140 _adg_help_window(builder));
1141 g_signal_connect_swapped(button_about, "clicked",
1142 G_CALLBACK(gtk_dialog_run),
1143 _adg_about_window(builder));
1144 g_signal_connect_swapped(button_edit, "clicked",
1145 G_CALLBACK(gtk_dialog_run),
1146 _adg_edit_window(builder, part));
1147 g_signal_connect_swapped(button_save_as, "clicked",
1148 G_CALLBACK(gtk_dialog_run),
1149 _adg_save_as_window(builder, canvas));
1150 g_signal_connect(button_print, "clicked",
1151 G_CALLBACK(_adg_do_print), canvas);
1152 g_signal_connect(button_quit, "clicked", G_CALLBACK(gtk_main_quit), NULL);
1153 g_signal_connect(window, "delete-event", G_CALLBACK(gtk_main_quit), NULL);
1154 g_signal_connect_swapped(window, "destroy",
1155 G_CALLBACK(_adg_part_destroy), part);
1156
1157 return window;
1158}
1159
1160
1161int
1162main(gint argc, gchar **argv)
1163{
1164 gchar *path;
1165 GtkBuilder *builder;
1166 GError *error;
1167 GtkWidget *main_window;
1168
1169 _demo_init(argc, argv);
1170 parse_args(&argc, &argv);
1171 adg_switch_extents(show_extents);
1172
1173 path = _demo_file("adg-demo.ui");
1174 if (path == NULL) {
1175 g_printerr(_("adg-demo.ui not found!\n"));
1176 return 1;
1177 }
1178
1179 builder = gtk_builder_new();
1180 error = NULL;
1181
1182 gtk_builder_set_translation_domain(builder, GETTEXT_PACKAGE);
1183 gtk_builder_add_from_file(builder, path, &error);
1184 g_free(path);
1185
1186 if (error != NULL) {
1187 g_critical("%s", error->message);
1188 g_error_free(error);
1189 return 2;
1190 }
1191
1192 main_window = _adg_main_window(builder);
1193 g_object_unref(builder);
1194
1195 gtk_widget_show_all(main_window);
1196 gtk_main();
1197
1198 return 0;
1199}

Archive Download this file