1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007,2008,2009,2010,2011,2012,2013 Nicola Fontana <ntd at entidi.it>
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.
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.
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.
25 #define SQRT3 1.732050808
29 /* Whether render the boxes to highlight the extents of every entity */
30 static gboolean show_extents
= FALSE
;
33 typedef struct _DemoPart DemoPart
;
67 /* User interface widgets */
76 AdgPath
*hatch_contour
;
79 /* Special entities */
80 AdgTitleBlock
*title_block
;
88 g_print("adg-demo " PACKAGE_VERSION
"\n");
93 parse_args(gint
*p_argc
, gchar
**p_argv
[])
95 GOptionEntry entries
[] = {
96 {"version", 'V', G_OPTION_FLAG_NO_ARG
, G_OPTION_ARG_CALLBACK
,
97 (gpointer
) _adg_version
, _("Display version information"), NULL
},
98 {"show-extents", 'E', 0, G_OPTION_ARG_NONE
,
99 &show_extents
, _("Show the boundary boxes of every entity"), NULL
},
105 gtk_init_with_args(p_argc
, p_argv
, _("- ADG demonstration program"),
106 entries
, GETTEXT_PACKAGE
, &error
);
108 g_error("%s", error
->message
);
109 g_assert_not_reached();
115 * @message: a custom error message
116 * @parent_window: the parent window or %NULL
118 * Convenient function that presents an error dialog and waits the user
119 * to close this modal dialog.
122 _adg_error(const gchar
*message
, GtkWindow
*parent_window
)
124 GtkWidget
*dialog
= gtk_message_dialog_new(parent_window
,
125 GTK_DIALOG_DESTROY_WITH_PARENT
,
129 gtk_window_set_title(GTK_WINDOW(dialog
), _("Error from adg-demo"));
130 gtk_dialog_run(GTK_DIALOG(dialog
));
131 gtk_widget_destroy(dialog
);
135 _adg_path_add_hole(AdgPath
*path
, const DemoPart
*part
)
140 model
= ADG_MODEL(path
);
141 pair
.x
= part
->LHOLE
;
144 adg_path_move_to(path
, &pair
);
145 adg_model_set_named_pair(model
, "LHOLE", &pair
);
147 pair
.y
= part
->DHOLE
/ 2;
148 pair
.x
-= pair
.y
/ SQRT3
;
149 adg_path_line_to(path
, &pair
);
152 adg_path_line_to(path
, &pair
);
153 adg_model_set_named_pair(model
, "DHOLE", &pair
);
157 _adg_path_add_rail(AdgPath
*path
, const DemoPart
*part
, gdouble to_x
)
162 model
= ADG_MODEL(path
);
164 pair
.y
= part
->D1
/ 2;
166 adg_path_line_to(path
, &pair
);
167 adg_model_set_named_pair(model
, "D1I", &pair
);
169 if (part
->GROOVE
&& to_x
> part
->ZGROOVE
) {
170 pair
.x
= part
->ZGROOVE
;
171 adg_path_line_to(path
, &pair
);
172 adg_model_set_named_pair(model
, "DGROOVEI_X", &pair
);
174 pair
.y
= part
->D3
/ 2;
175 adg_model_set_named_pair(model
, "DGROOVEY_POS", &pair
);
177 pair
.y
= part
->DGROOVE
/ 2;
178 adg_path_line_to(path
, &pair
);
179 adg_model_set_named_pair(model
, "DGROOVEI_Y", &pair
);
181 pair
.x
+= part
->LGROOVE
;
182 adg_path_line_to(path
, &pair
);
184 pair
.y
= part
->D3
/ 2;
185 adg_model_set_named_pair(model
, "DGROOVEX_POS", &pair
);
187 pair
.y
= part
->D1
/ 2;
188 adg_path_line_to(path
, &pair
);
189 adg_model_set_named_pair(model
, "DGROOVEF_X", &pair
);
193 adg_path_line_to(path
, &pair
);
194 adg_model_set_named_pair(model
, "D1F", &pair
);
199 _adg_part_define_title_block(DemoPart
*part
)
201 g_object_set(part
->title_block
,
202 "title", part
->TITLE
,
203 "author", part
->AUTHOR
,
205 "drawing", part
->DRAWING
,
206 "logo", adg_logo_new(),
207 "projection", adg_projection_new(ADG_PROJECTION_SCHEME_FIRST_ANGLE
),
214 _adg_part_define_hatch(DemoPart
*part
)
221 pair
.y
= (part
->D1
+ part
->DHOLE
) / 4;
223 _adg_path_add_hole(path
, part
);
224 adg_path_line_to(path
, &pair
);
225 adg_path_curve_to_explicit(path
,
226 part
->LHOLE
/ 2, part
->DHOLE
/ 2,
227 part
->LHOLE
+ 2, part
->D1
/ 2,
229 adg_path_reflect(path
, NULL
);
230 adg_path_close(path
);
232 path
= part
->hatch_contour
;
233 adg_path_move_to(path
, &pair
);
234 adg_path_curve_to_explicit(path
,
235 part
->LHOLE
/ 2, part
->DHOLE
/ 2,
236 part
->LHOLE
+ 2, part
->D1
/ 2,
238 adg_path_reflect(path
, NULL
);
242 _adg_part_define_shape(DemoPart
*part
)
247 const CpmlPrimitive
*primitive
;
250 model
= ADG_MODEL(path
);
251 pair
.x
= part
->A
- part
->B
- part
->LD2
;
252 pair
.y
= part
->D3
/ 2;
253 adg_model_set_named_pair(model
, "D2_POS", &pair
);
255 _adg_path_add_hole(path
, part
);
256 _adg_path_add_rail(path
, part
, pair
.x
);
258 pair
.x
+= (part
->D1
- part
->D2
) / 2;
259 pair
.y
= part
->D2
/ 2;
260 adg_path_line_to(path
, &pair
);
261 adg_model_set_named_pair(model
, "D2I", &pair
);
263 pair
.x
= part
->A
- part
->B
;
264 adg_path_line_to(path
, &pair
);
265 adg_path_fillet(path
, 0.4);
267 pair
.x
= part
->A
- part
->B
;
268 pair
.y
= part
->D3
/ 2;
269 adg_path_line_to(path
, &pair
);
270 adg_model_set_named_pair(model
, "D3I", &pair
);
273 adg_model_set_named_pair(model
, "East", &pair
);
276 adg_model_set_named_pair(model
, "West", &pair
);
278 adg_path_chamfer(path
, CHAMFER
, CHAMFER
);
280 pair
.x
= part
->A
- part
->B
+ part
->LD3
;
281 pair
.y
= part
->D3
/ 2;
282 adg_path_line_to(path
, &pair
);
284 primitive
= adg_path_over_primitive(path
);
285 cpml_primitive_put_point(primitive
, 0, &tmp
);
286 adg_model_set_named_pair(model
, "D3I_X", &tmp
);
288 cpml_primitive_put_point(primitive
, -1, &tmp
);
289 adg_model_set_named_pair(model
, "D3I_Y", &tmp
);
291 adg_path_chamfer(path
, CHAMFER
, CHAMFER
);
293 pair
.y
= part
->D4
/ 2;
294 adg_path_line_to(path
, &pair
);
296 primitive
= adg_path_over_primitive(path
);
297 cpml_primitive_put_point(primitive
, 0, &tmp
);
298 adg_model_set_named_pair(model
, "D3F_Y", &tmp
);
299 cpml_primitive_put_point(primitive
, -1, &tmp
);
300 adg_model_set_named_pair(model
, "D3F_X", &tmp
);
302 adg_path_fillet(path
, part
->RD34
);
304 pair
.x
+= part
->RD34
;
305 adg_model_set_named_pair(model
, "D4I", &pair
);
307 pair
.x
= part
->A
- part
->C
- part
->LD5
;
308 adg_path_line_to(path
, &pair
);
309 adg_model_set_named_pair(model
, "D4F", &pair
);
311 pair
.y
= part
->D3
/ 2;
312 adg_model_set_named_pair(model
, "D4_POS", &pair
);
314 primitive
= adg_path_over_primitive(path
);
315 cpml_primitive_put_point(primitive
, 0, &tmp
);
317 adg_model_set_named_pair(model
, "RD34", &tmp
);
319 tmp
.x
-= cos(G_PI_4
) * part
->RD34
,
320 tmp
.y
-= sin(G_PI_4
) * part
->RD34
,
321 adg_model_set_named_pair(model
, "RD34_R", &tmp
);
325 adg_model_set_named_pair(model
, "RD34_XY", &tmp
);
327 pair
.x
+= (part
->D4
- part
->D5
) / 2;
328 pair
.y
= part
->D5
/ 2;
329 adg_path_line_to(path
, &pair
);
330 adg_model_set_named_pair(model
, "D5I", &pair
);
332 pair
.x
= part
->A
- part
->C
;
333 adg_path_line_to(path
, &pair
);
335 adg_path_fillet(path
, 0.2);
337 pair
.y
= part
->D6
/ 2;
338 adg_path_line_to(path
, &pair
);
340 primitive
= adg_path_over_primitive(path
);
341 cpml_primitive_put_point(primitive
, 0, &tmp
);
342 adg_model_set_named_pair(model
, "D5F", &tmp
);
344 adg_path_fillet(path
, 0.1);
347 adg_path_line_to(path
, &pair
);
348 adg_model_set_named_pair(model
, "D6F", &pair
);
350 primitive
= adg_path_over_primitive(path
);
351 cpml_primitive_put_point(primitive
, 0, &tmp
);
352 adg_model_set_named_pair(model
, "D6I_X", &tmp
);
354 primitive
= adg_path_over_primitive(path
);
355 cpml_primitive_put_point(primitive
, -1, &tmp
);
356 adg_model_set_named_pair(model
, "D6I_Y", &tmp
);
358 pair
.x
= part
->A
- part
->LD7
;
359 pair
.y
-= (part
->C
- part
->LD7
- part
->LD6
) / SQRT3
;
360 adg_path_line_to(path
, &pair
);
361 adg_model_set_named_pair(model
, "D67", &pair
);
363 pair
.y
= part
->D7
/ 2;
364 adg_path_line_to(path
, &pair
);
367 adg_path_line_to(path
, &pair
);
368 adg_model_set_named_pair(model
, "D7F", &pair
);
370 adg_path_reflect(path
, NULL
);
371 adg_path_close(path
);
375 _adg_part_define_axis(DemoPart
*part
)
381 /* XXX: actually the end points can extend outside the shape
382 * only in local space. The proper extension values should be
383 * expressed in global space but actually is impossible to
384 * combine local and global space in the AdgPath API.
386 adg_path_move_to_explicit(path
, -1, 0);
387 adg_path_line_to_explicit(path
, part
->A
+ 1, 0);
391 _adg_part_lock(DemoPart
*part
)
393 gtk_widget_set_sensitive(GTK_WIDGET(part
->apply
), FALSE
);
394 gtk_widget_set_sensitive(GTK_WIDGET(part
->reset
), FALSE
);
398 _adg_part_unlock(DemoPart
*part
)
400 gtk_widget_set_sensitive(GTK_WIDGET(part
->apply
), TRUE
);
401 gtk_widget_set_sensitive(GTK_WIDGET(part
->reset
), TRUE
);
405 _adg_part_link(DemoPart
*part
, gpointer data
, GObject
*widget
)
407 const gchar
*edit_signal
;
409 g_assert(GTK_IS_WIDGET(widget
));
410 g_object_ref(widget
);
411 g_hash_table_insert(part
->widgets
, data
, widget
);
413 if (GTK_IS_SPIN_BUTTON(widget
)) {
414 GtkSpinButton
*spin_button
= GTK_SPIN_BUTTON(widget
);
415 gtk_adjustment_value_changed(gtk_spin_button_get_adjustment(spin_button
));
418 edit_signal
= GTK_IS_TOGGLE_BUTTON(widget
) ? "toggled" : "changed";
419 g_signal_connect_swapped(widget
, edit_signal
,
420 G_CALLBACK(_adg_part_unlock
), part
);
424 _adg_part_ui_to_boolean(DemoPart
*part
, gboolean
*data
)
426 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
428 g_assert(GTK_IS_TOGGLE_BUTTON(widget
));
430 *data
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
434 _adg_part_ui_to_double(DemoPart
*part
, gdouble
*data
)
437 GtkSpinButton
*spin_button
;
439 widget
= g_hash_table_lookup(part
->widgets
, data
);
440 g_assert(GTK_IS_SPIN_BUTTON(widget
));
442 spin_button
= GTK_SPIN_BUTTON(widget
);
443 gtk_spin_button_update(spin_button
);
444 *data
= gtk_spin_button_get_value(spin_button
);
448 _adg_part_ui_to_string(DemoPart
*part
, gchar
**data
)
450 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
452 g_assert(GTK_IS_ENTRY(widget
));
455 *data
= g_strdup(gtk_entry_get_text(GTK_ENTRY(widget
)));
459 _adg_part_boolean_to_ui(DemoPart
*part
, gboolean
*data
)
461 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
463 g_assert(GTK_IS_TOGGLE_BUTTON(widget
));
465 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), *data
);
469 _adg_part_double_to_ui(DemoPart
*part
, gdouble
*data
)
471 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
473 g_assert(GTK_IS_SPIN_BUTTON(widget
));
475 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget
), *data
);
479 _adg_part_string_to_ui(DemoPart
*part
, gchar
**data
)
481 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
483 g_assert(GTK_IS_ENTRY(widget
));
485 gtk_entry_set_text(GTK_ENTRY(widget
), *data
);
489 _adg_demo_canvas_add_dimensions(AdgCanvas
*canvas
, AdgModel
*model
)
496 ldim
= adg_ldim_new_full_from_model(model
, "-D3I_X", "-D3F_X", "-D3F_Y",
498 adg_dim_set_outside(ADG_DIM(ldim
), ADG_THREE_STATE_OFF
);
499 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
501 ldim
= adg_ldim_new_full_from_model(model
, "-D6I_X", "-D67", "-East",
503 adg_dim_set_level(ADG_DIM(ldim
), 0);
504 adg_ldim_switch_extension1(ldim
, FALSE
);
505 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
507 ldim
= adg_ldim_new_full_from_model(model
, "-D6I_X", "-D7F", "-East",
509 adg_dim_set_limits(ADG_DIM(ldim
), "-0.06", NULL
);
510 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
512 adim
= adg_adim_new_full_from_model(model
, "-D6I_Y", "-D6F",
513 "-D6F", "-D67", "-D6F");
514 adg_dim_set_level(ADG_DIM(adim
), 2);
515 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(adim
));
517 rdim
= adg_rdim_new_full_from_model(model
, "-RD34", "-RD34_R", "-RD34_XY");
518 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(rdim
));
520 ldim
= adg_ldim_new_full_from_model(model
, "-DGROOVEI_X", "-DGROOVEF_X",
521 "-DGROOVEX_POS", ADG_DIR_UP
);
522 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
524 ldim
= adg_ldim_new_full_from_model(model
, "D2I", "-D2I", "-D2_POS",
526 adg_dim_set_limits(ADG_DIM(ldim
), "-0.1", NULL
);
527 adg_dim_set_outside(ADG_DIM(ldim
), ADG_THREE_STATE_OFF
);
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
, "DGROOVEI_Y", "-DGROOVEI_Y",
532 "-DGROOVEY_POS", ADG_DIR_LEFT
);
533 adg_dim_set_limits(ADG_DIM(ldim
), "-0.1", NULL
);
534 adg_dim_set_outside(ADG_DIM(ldim
), ADG_THREE_STATE_OFF
);
535 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
536 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
539 adim
= adg_adim_new_full_from_model(model
, "D1F", "D1I", "D2I", "D1F", "D1F");
540 adg_dim_set_level(ADG_DIM(adim
), 2);
541 adg_adim_switch_extension2(adim
, FALSE
);
542 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(adim
));
544 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "LHOLE", "West",
546 adg_ldim_switch_extension1(ldim
, FALSE
);
547 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
549 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "DGROOVEI_X", "West",
551 adg_ldim_switch_extension1(ldim
, FALSE
);
552 adg_dim_set_level(ADG_DIM(ldim
), 2);
553 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
555 ldim
= adg_ldim_new_full_from_model(model
, "D4F", "D6I_X", "D4_POS",
557 adg_dim_set_limits(ADG_DIM(ldim
), NULL
, "+0.2");
558 adg_dim_set_outside(ADG_DIM(ldim
), ADG_THREE_STATE_OFF
);
559 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
561 ldim
= adg_ldim_new_full_from_model(model
, "D1F", "D3I_X", "D2_POS",
563 adg_dim_set_level(ADG_DIM(ldim
), 2);
564 adg_ldim_switch_extension2(ldim
, FALSE
);
565 adg_dim_set_outside(ADG_DIM(ldim
), ADG_THREE_STATE_OFF
);
566 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
568 ldim
= adg_ldim_new_full_from_model(model
, "D3I_X", "D7F", "East",
570 adg_dim_set_limits(ADG_DIM(ldim
), NULL
, "+0.1");
571 adg_dim_set_level(ADG_DIM(ldim
), 2);
572 adg_dim_set_outside(ADG_DIM(ldim
), ADG_THREE_STATE_OFF
);
573 adg_ldim_switch_extension2(ldim
, FALSE
);
574 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
576 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "D7F", "D3F_Y",
578 adg_dim_set_limits(ADG_DIM(ldim
), "-0.05", "+0.05");
579 adg_dim_set_level(ADG_DIM(ldim
), 3);
580 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
582 adim
= adg_adim_new_full_from_model(model
, "D4F", "D4I",
583 "D5I", "D4F", "D4F");
584 adg_dim_set_level(ADG_DIM(adim
), 1.5);
585 adg_adim_switch_extension2(adim
, FALSE
);
586 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(adim
));
589 ldim
= adg_ldim_new_full_from_model(model
, "D6F", "-D6F", "East",
591 adg_dim_set_limits(ADG_DIM(ldim
), "-0.1", NULL
);
592 adg_dim_set_level(ADG_DIM(ldim
), 4);
593 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
594 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
596 ldim
= adg_ldim_new_full_from_model(model
, "D4F", "-D4F", "East",
598 adg_dim_set_level(ADG_DIM(ldim
), 3);
599 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
600 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
602 ldim
= adg_ldim_new_full_from_model(model
, "D5F", "-D5F", "East",
604 adg_dim_set_limits(ADG_DIM(ldim
), "-0.1", NULL
);
605 adg_dim_set_level(ADG_DIM(ldim
), 2);
606 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
607 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
609 ldim
= adg_ldim_new_full_from_model(model
, "D7F", "-D7F", "East",
611 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
612 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
615 ldim
= adg_ldim_new_full_from_model(model
, "DHOLE", "-DHOLE", "-West",
617 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
618 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
620 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "-D1I", "-West",
622 adg_dim_set_limits(ADG_DIM(ldim
), "-0.05", "+0.05");
623 adg_dim_set_level(ADG_DIM(ldim
), 2);
624 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
625 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
627 ldim
= adg_ldim_new_full_from_model(model
, "D3I_Y", "-D3I_Y", "-West",
629 adg_dim_set_limits(ADG_DIM(ldim
), "-0.25", NULL
);
630 adg_dim_set_level(ADG_DIM(ldim
), 3);
631 adg_dim_set_value(ADG_DIM(ldim
), ADG_UTF8_DIAMETER
"<>");
632 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
636 _adg_demo_canvas_add_axis(AdgCanvas
*canvas
, AdgTrail
*trail
)
638 AdgStroke
*stroke
= adg_stroke_new(trail
);
639 adg_stroke_set_line_dress(stroke
, ADG_DRESS_LINE_AXIS
);
640 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(stroke
));
644 _adg_canvas_init(AdgCanvas
*canvas
, DemoPart
*part
)
646 AdgContainer
*container
;
649 container
= (AdgContainer
*) canvas
;
651 adg_canvas_set_paper(canvas
, GTK_PAPER_NAME_A4
,
652 GTK_PAGE_ORIENTATION_LANDSCAPE
);
653 adg_canvas_set_title_block(canvas
, part
->title_block
);
655 entity
= ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part
->shape
)));
656 adg_container_add(container
, entity
);
658 entity
= ADG_ENTITY(adg_hatch_new(ADG_TRAIL(part
->hatch
)));
659 adg_container_add(container
, entity
);
661 entity
= ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part
->hatch_contour
)));
662 adg_container_add(container
, entity
);
664 entity
= ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part
->edges
)));
665 adg_container_add(container
, entity
);
667 _adg_demo_canvas_add_dimensions(canvas
, ADG_MODEL(part
->shape
));
669 _adg_demo_canvas_add_axis(canvas
, ADG_TRAIL(part
->axis
));
674 static GtkRadioButton
*
675 _adg_group_get_active(GtkRadioButton
*radio_group
)
677 GSList
*list
= gtk_radio_button_get_group(radio_group
);
680 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list
->data
)))
690 _adg_do_edit(DemoPart
*part
)
692 _adg_part_ui_to_double(part
, &part
->A
);
693 _adg_part_ui_to_double(part
, &part
->B
);
694 _adg_part_ui_to_double(part
, &part
->C
);
695 _adg_part_ui_to_double(part
, &part
->DHOLE
);
696 _adg_part_ui_to_double(part
, &part
->LHOLE
);
697 _adg_part_ui_to_double(part
, &part
->D1
);
698 _adg_part_ui_to_double(part
, &part
->D2
);
699 _adg_part_ui_to_double(part
, &part
->LD2
);
700 _adg_part_ui_to_double(part
, &part
->D3
);
701 _adg_part_ui_to_double(part
, &part
->LD3
);
702 _adg_part_ui_to_double(part
, &part
->D4
);
703 //_adg_part_ui_to_double(part, &part->D5);
704 _adg_part_ui_to_double(part
, &part
->D6
);
705 //_adg_part_ui_to_double(part, &part->LD6);
706 _adg_part_ui_to_double(part
, &part
->D7
);
707 //_adg_part_ui_to_double(part, &part->LD7);
709 _adg_part_ui_to_boolean(part
, &part
->GROOVE
);
710 _adg_part_ui_to_double(part
, &part
->ZGROOVE
);
711 _adg_part_ui_to_double(part
, &part
->DGROOVE
);
712 _adg_part_ui_to_double(part
, &part
->LGROOVE
);
714 _adg_part_ui_to_string(part
, &part
->TITLE
);
715 _adg_part_ui_to_string(part
, &part
->DRAWING
);
716 _adg_part_ui_to_string(part
, &part
->AUTHOR
);
717 _adg_part_ui_to_string(part
, &part
->DATE
);
719 _adg_part_lock(part
);
721 adg_model_reset(ADG_MODEL(part
->shape
));
722 adg_model_reset(ADG_MODEL(part
->hatch
));
723 adg_model_reset(ADG_MODEL(part
->hatch_contour
));
724 adg_model_reset(ADG_MODEL(part
->axis
));
725 adg_model_reset(ADG_MODEL(part
->edges
));
727 _adg_part_define_title_block(part
);
728 _adg_part_define_shape(part
);
729 _adg_part_define_hatch(part
);
730 _adg_part_define_axis(part
);
732 adg_model_changed(ADG_MODEL(part
->shape
));
733 adg_model_changed(ADG_MODEL(part
->hatch
));
734 adg_model_changed(ADG_MODEL(part
->hatch_contour
));
735 adg_model_changed(ADG_MODEL(part
->axis
));
736 adg_model_changed(ADG_MODEL(part
->edges
));
738 gtk_widget_queue_draw(GTK_WIDGET(part
->area
));
742 _adg_do_reset(DemoPart
*part
)
744 _adg_part_double_to_ui(part
, &part
->A
);
745 _adg_part_double_to_ui(part
, &part
->B
);
746 _adg_part_double_to_ui(part
, &part
->C
);
747 _adg_part_double_to_ui(part
, &part
->DHOLE
);
748 _adg_part_double_to_ui(part
, &part
->LHOLE
);
749 _adg_part_double_to_ui(part
, &part
->D1
);
750 _adg_part_double_to_ui(part
, &part
->D2
);
751 _adg_part_double_to_ui(part
, &part
->LD2
);
752 _adg_part_double_to_ui(part
, &part
->D3
);
753 _adg_part_double_to_ui(part
, &part
->LD3
);
754 _adg_part_double_to_ui(part
, &part
->D4
);
755 //_adg_part_double_to_ui(part, &part->D5);
756 _adg_part_double_to_ui(part
, &part
->D6
);
757 //_adg_part_double_to_ui(part, &part->LD6);
758 _adg_part_double_to_ui(part
, &part
->D7
);
759 //_adg_part_double_to_ui(part, &part->LD7);
761 _adg_part_boolean_to_ui(part
, &part
->GROOVE
);
762 _adg_part_double_to_ui(part
, &part
->ZGROOVE
);
763 _adg_part_double_to_ui(part
, &part
->DGROOVE
);
764 _adg_part_double_to_ui(part
, &part
->LGROOVE
);
766 _adg_part_string_to_ui(part
, &part
->TITLE
);
767 _adg_part_string_to_ui(part
, &part
->DRAWING
);
768 _adg_part_string_to_ui(part
, &part
->AUTHOR
);
769 _adg_part_string_to_ui(part
, &part
->DATE
);
771 _adg_part_lock(part
);
775 _adg_do_save_as(GtkWindow
*window
, GtkResponseType response
, AdgCanvas
*canvas
)
777 GtkRadioButton
*type_radio
;
778 gchar
*file
, *suffix
;
779 cairo_surface_t
*surface
;
781 if (response
!= GTK_RESPONSE_OK
) {
782 gtk_widget_hide(GTK_WIDGET(window
));
786 file
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(window
));
790 type_radio
= _adg_group_get_active(g_object_get_data(G_OBJECT(window
),
792 g_assert(GTK_IS_RADIO_BUTTON(type_radio
));
793 suffix
= gtk_widget_get_tooltip_markup(GTK_WIDGET(type_radio
));
794 g_assert(suffix
!= NULL
);
796 if (!g_str_has_suffix(file
, suffix
)) {
798 file
= g_strconcat(file
, suffix
, NULL
);
802 #ifdef CAIRO_HAS_PNG_FUNCTIONS
803 if (strcmp(suffix
, ".png") == 0) {
804 surface
= cairo_image_surface_create(CAIRO_FORMAT_RGB24
, 800, 600);
807 #ifdef CAIRO_HAS_SVG_SURFACE
808 if (strcmp(suffix
, ".svg") == 0) {
809 #include <cairo-svg.h>
810 surface
= cairo_svg_surface_create(file
, 841, 595);
813 #ifdef CAIRO_HAS_PDF_SURFACE
814 if (strcmp(suffix
, ".pdf") == 0) {
815 #include <cairo-pdf.h>
816 surface
= cairo_pdf_surface_create(file
, 841, 595);
819 #ifdef CAIRO_HAS_PS_SURFACE
820 if (strcmp(suffix
, ".ps") == 0) {
821 #include <cairo-ps.h>
822 surface
= cairo_ps_surface_create(file
, 841, 595);
823 cairo_ps_surface_dsc_comment(surface
, "%%Title: " PACKAGE_STRING
);
824 cairo_ps_surface_dsc_comment(surface
, "%%Copyright: Copyleft (C) 2006-2013 Fontana Nicola");
825 cairo_ps_surface_dsc_comment(surface
, "%%Orientation: Landscape");
826 cairo_ps_surface_dsc_begin_setup(surface
);
827 cairo_ps_surface_dsc_begin_page_setup(surface
);
828 cairo_ps_surface_dsc_comment(surface
, "%%IncludeFeature: *PageSize A4");
832 _adg_error(_("Requested format not supported"), window
);
838 cairo_status_t status
;
840 cr
= cairo_create(surface
);
841 cairo_surface_destroy(surface
);
842 adg_entity_render(ADG_ENTITY(canvas
), cr
);
844 if (cairo_surface_get_type(surface
) == CAIRO_SURFACE_TYPE_IMAGE
) {
845 status
= cairo_surface_write_to_png(surface
, file
);
848 status
= cairo_status(cr
);
853 if (status
!= CAIRO_STATUS_SUCCESS
)
854 _adg_error(cairo_status_to_string(status
), window
);
859 gtk_widget_hide(GTK_WIDGET(window
));
863 _adg_print_prepare(GtkPrintOperation
*operation
, GtkPrintContext
*context
)
865 gtk_print_operation_set_n_pages(operation
, 1);
869 _adg_print_page(GtkPrintOperation
*operation
, GtkPrintContext
*context
,
870 gint page_nr
, AdgEntity
*canvas
)
872 cairo_t
*cr
= gtk_print_context_get_cairo_context(context
);
873 cairo_matrix_t old_map
;
875 adg_matrix_copy(&old_map
, adg_entity_get_global_map(canvas
));;
877 adg_entity_set_global_map(canvas
, adg_matrix_identity());
878 adg_entity_render(canvas
, cr
);
880 adg_entity_set_global_map(canvas
, &old_map
);
884 _adg_do_print(GtkWidget
*button
, AdgCanvas
*canvas
)
886 static GtkPrintSettings
*settings
= NULL
;
888 GtkPrintOperation
*operation
;
889 GtkPageSetup
*page_setup
;
892 window
= (GtkWindow
*) gtk_widget_get_toplevel(button
);
893 operation
= gtk_print_operation_new();
894 page_setup
= g_object_get_data(G_OBJECT(canvas
), "_adg_page_setup");
898 gtk_print_operation_set_print_settings(operation
, settings
);
900 gtk_print_operation_set_default_page_setup(operation
, page_setup
);
902 g_signal_connect(operation
, "begin-print",
903 G_CALLBACK(_adg_print_prepare
), NULL
);
904 g_signal_connect(operation
, "draw-page",
905 G_CALLBACK(_adg_print_page
), canvas
);
907 gtk_print_operation_set_use_full_page(operation
, FALSE
);
908 gtk_print_operation_set_unit(operation
, GTK_UNIT_POINTS
);
909 #if GTK_CHECK_VERSION(2, 18, 0)
910 gtk_print_operation_set_embed_page_setup(operation
, TRUE
);
913 switch (gtk_print_operation_run(operation
,
914 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
,
917 case GTK_PRINT_OPERATION_RESULT_APPLY
:
919 g_object_unref(settings
);
920 settings
= gtk_print_operation_get_print_settings(operation
);
922 g_object_ref(settings
);
929 g_object_unref(operation
);
932 _adg_error(error
->message
, window
);
936 _adg_button_press(AdgGtkArea
*area
, GdkEventButton
*event
)
940 if (event
->button
!= 1 && event
->button
!= 3)
943 canvas
= adg_gtk_area_get_canvas(area
);
944 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), FALSE
);
946 if (event
->button
== 1) {
947 /* Restore the original zoom */
948 adg_gtk_area_reset(area
);
949 } else if (event
->button
== 3) {
950 adg_canvas_autoscale(canvas
);
951 gtk_widget_queue_draw((GtkWidget
*) area
);
958 _adg_part_new(GtkBuilder
*builder
)
961 GObject
*object
, *toggle_object
;
963 part
= g_new0(DemoPart
, 1);
964 part
->widgets
= g_hash_table_new_full(g_direct_hash
, g_direct_equal
,
965 NULL
, g_object_unref
);
966 part
->area
= (AdgGtkArea
*) gtk_builder_get_object(builder
, "mainCanvas");
967 part
->apply
= (GtkButton
*) gtk_builder_get_object(builder
, "btnApply");
968 part
->reset
= (GtkButton
*) gtk_builder_get_object(builder
, "btnReset");
969 part
->shape
= adg_path_new();
970 part
->hatch
= adg_path_new();
971 part
->hatch_contour
= adg_path_new();
972 part
->axis
= adg_path_new();
973 part
->title_block
= adg_title_block_new();
974 part
->edges
= adg_edges_new_with_source(ADG_TRAIL(part
->shape
));
976 g_assert(ADG_GTK_IS_AREA(part
->area
));
977 g_assert(GTK_IS_BUTTON(part
->apply
));
978 g_assert(GTK_IS_BUTTON(part
->reset
));
980 _adg_part_link(part
, &part
->A
, gtk_builder_get_object(builder
, "editA"));
981 _adg_part_link(part
, &part
->B
, gtk_builder_get_object(builder
, "editB"));
982 _adg_part_link(part
, &part
->C
, gtk_builder_get_object(builder
, "editC"));
983 _adg_part_link(part
, &part
->D1
, gtk_builder_get_object(builder
, "editD1"));
984 _adg_part_link(part
, &part
->D2
, gtk_builder_get_object(builder
, "editD2"));
985 _adg_part_link(part
, &part
->LD2
, gtk_builder_get_object(builder
, "editLD2"));
986 _adg_part_link(part
, &part
->D3
, gtk_builder_get_object(builder
, "editD3"));
987 _adg_part_link(part
, &part
->LD3
, gtk_builder_get_object(builder
, "editLD3"));
988 _adg_part_link(part
, &part
->D4
, gtk_builder_get_object(builder
, "editD4"));
989 //_adg_part_link(part, &part->D5, gtk_builder_get_object(builder, "editD5"));
990 _adg_part_link(part
, &part
->D6
, gtk_builder_get_object(builder
, "editD6"));
991 //_adg_part_link(part, &part->LD6, gtk_builder_get_object(builder, "editLD6"));
992 _adg_part_link(part
, &part
->D7
, gtk_builder_get_object(builder
, "editD7"));
993 //_adg_part_link(part, &part->LD7, gtk_builder_get_object(builder, "editLD7"));
994 _adg_part_link(part
, &part
->DHOLE
, gtk_builder_get_object(builder
, "editDHOLE"));
995 _adg_part_link(part
, &part
->LHOLE
, gtk_builder_get_object(builder
, "editLHOLE"));
997 g_signal_connect(part
->area
, "button-press-event",
998 G_CALLBACK(_adg_button_press
), NULL
);
1000 toggle_object
= gtk_builder_get_object(builder
, "GROOVE");
1001 _adg_part_link(part
, &part
->GROOVE
, toggle_object
);
1003 object
= gtk_builder_get_object(builder
, "editZGROOVE");
1004 _adg_part_link(part
, &part
->ZGROOVE
, object
);
1005 g_signal_connect(toggle_object
, "toggled",
1006 G_CALLBACK(adg_gtk_toggle_button_sensitivize
), object
);
1007 object
= gtk_builder_get_object(builder
, "editZGROOVELabel");
1008 g_signal_connect(toggle_object
, "toggled",
1009 G_CALLBACK(adg_gtk_toggle_button_sensitivize
), object
);
1011 object
= gtk_builder_get_object(builder
, "editDGROOVE");
1012 _adg_part_link(part
, &part
->DGROOVE
, object
);
1013 g_signal_connect(toggle_object
, "toggled",
1014 G_CALLBACK(adg_gtk_toggle_button_sensitivize
), object
);
1015 object
= gtk_builder_get_object(builder
, "editDGROOVELabel");
1016 g_signal_connect(toggle_object
, "toggled",
1017 G_CALLBACK(adg_gtk_toggle_button_sensitivize
), object
);
1019 object
= gtk_builder_get_object(builder
, "editLGROOVE");
1020 _adg_part_link(part
, &part
->LGROOVE
, object
);
1021 g_signal_connect(toggle_object
, "toggled",
1022 G_CALLBACK(adg_gtk_toggle_button_sensitivize
), object
);
1023 object
= gtk_builder_get_object(builder
, "editLGROOVELabel");
1024 g_signal_connect(toggle_object
, "toggled",
1025 G_CALLBACK(adg_gtk_toggle_button_sensitivize
), object
);
1027 _adg_part_link(part
, &part
->TITLE
, gtk_builder_get_object(builder
, "txtTitle"));
1028 _adg_part_link(part
, &part
->DRAWING
, gtk_builder_get_object(builder
, "txtDrawing"));
1029 _adg_part_link(part
, &part
->AUTHOR
, gtk_builder_get_object(builder
, "txtAuthor"));
1030 _adg_part_link(part
, &part
->DATE
, gtk_builder_get_object(builder
, "txtDate"));
1044 _adg_part_destroy(DemoPart
*part
)
1046 g_hash_table_destroy(part
->widgets
);
1051 _adg_about_window(GtkBuilder
*builder
)
1054 GList
*icon_list
, *last_node
;
1056 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndAbout");
1057 g_assert(GTK_IS_ABOUT_DIALOG(window
));
1058 g_signal_connect(window
, "response", G_CALLBACK(gtk_widget_hide
), NULL
);
1060 icon_list
= gtk_window_get_default_icon_list();
1061 last_node
= g_list_last(icon_list
);
1062 if (last_node
!= NULL
) {
1063 /* The last icon is supposed to be the largest one:
1064 * check adg_gtk_use_default_icons() implementation. */
1065 GdkPixbuf
*last_icon
= last_node
->data
;
1066 gtk_about_dialog_set_logo(GTK_ABOUT_DIALOG(window
), last_icon
);
1068 g_list_free(icon_list
);
1074 _adg_edit_window(GtkBuilder
*builder
, DemoPart
*part
)
1078 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndEdit");
1079 g_assert(GTK_IS_DIALOG(window
));
1081 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_MOUSE
);
1083 g_signal_connect_swapped(part
->apply
, "clicked",
1084 G_CALLBACK(_adg_do_edit
), part
);
1085 g_signal_connect_swapped(part
->reset
, "clicked",
1086 G_CALLBACK(_adg_do_reset
), part
);
1087 g_signal_connect(window
, "response",
1088 G_CALLBACK(adg_gtk_window_hide_here
), NULL
);
1094 _adg_save_as_window(GtkBuilder
*builder
, AdgCanvas
*canvas
)
1097 GtkWidget
*type_group
;
1099 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndSaveAs");
1100 g_assert(GTK_IS_WINDOW(window
));
1101 type_group
= (GtkWidget
*) gtk_builder_get_object(builder
, "saveAsPng");
1102 g_assert(GTK_IS_RADIO_BUTTON(type_group
));
1104 g_object_set_data(G_OBJECT(window
), "type-group", type_group
);
1106 /* Set the default destination file */
1107 if (GTK_IS_FILE_CHOOSER(window
)) {
1108 GtkFileChooser
*file_chooser
;
1111 file_chooser
= (GtkFileChooser
*) window
;
1113 #if GLIB_CHECK_VERSION(2, 14, 0)
1114 dir
= g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS
);
1120 dir
= g_get_home_dir();
1122 gtk_file_chooser_set_current_folder(file_chooser
, dir
);
1123 gtk_file_chooser_set_current_name(file_chooser
, "adg-demo");
1126 g_signal_connect(window
, "response", G_CALLBACK(_adg_do_save_as
), canvas
);
1132 _adg_main_window(GtkBuilder
*builder
)
1137 GtkWidget
*button_edit
, *button_save_as
, *button_print
;
1138 GtkWidget
*button_about
, *button_quit
;
1142 gchar
*icondir
= g_build_filename(basedir
, PKGDATADIR
, NULL
);
1143 adg_gtk_use_default_icons(icondir
);
1146 adg_gtk_use_default_icons(PKGDATADIR
);
1149 adg_gtk_use_default_icons(SRCDIR
);
1152 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndMain");
1153 part
= _adg_part_new(builder
);
1154 canvas
= adg_canvas_new();
1156 _adg_canvas_init(canvas
, part
);
1157 adg_gtk_area_set_canvas(part
->area
, canvas
);
1158 adg_canvas_autoscale(canvas
);
1160 g_assert(GTK_IS_WINDOW(window
));
1161 button_edit
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainEdit");
1162 g_assert(GTK_IS_BUTTON(button_edit
));
1163 button_save_as
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainSaveAs");
1164 g_assert(GTK_IS_BUTTON(button_save_as
));
1165 button_print
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainPrint");
1166 g_assert(GTK_IS_BUTTON(button_print
));
1167 button_about
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainAbout");
1168 g_assert(GTK_IS_BUTTON(button_about
));
1169 button_quit
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainQuit");
1170 g_assert(GTK_IS_BUTTON(button_quit
));
1172 g_signal_connect_swapped(button_about
, "clicked",
1173 G_CALLBACK(gtk_dialog_run
),
1174 _adg_about_window(builder
));
1175 g_signal_connect_swapped(button_edit
, "clicked",
1176 G_CALLBACK(gtk_dialog_run
),
1177 _adg_edit_window(builder
, part
));
1178 g_signal_connect_swapped(button_save_as
, "clicked",
1179 G_CALLBACK(gtk_dialog_run
),
1180 _adg_save_as_window(builder
, canvas
));
1181 g_signal_connect(button_print
, "clicked",
1182 G_CALLBACK(_adg_do_print
), canvas
);
1183 g_signal_connect(button_quit
, "clicked", G_CALLBACK(gtk_main_quit
), NULL
);
1184 g_signal_connect(window
, "delete-event", G_CALLBACK(gtk_main_quit
), NULL
);
1185 g_signal_connect_swapped(window
, "destroy",
1186 G_CALLBACK(_adg_part_destroy
), part
);
1193 main(gint argc
, gchar
**argv
)
1196 GtkBuilder
*builder
;
1198 GtkWidget
*main_window
;
1200 _demo_init(argc
, argv
);
1201 parse_args(&argc
, &argv
);
1202 adg_switch_extents(show_extents
);
1204 path
= _demo_file("adg-demo.ui");
1206 g_printerr(_("adg-demo.ui not found!\n"));
1210 builder
= gtk_builder_new();
1213 gtk_builder_set_translation_domain(builder
, GETTEXT_PACKAGE
);
1214 gtk_builder_add_from_file(builder
, path
, &error
);
1217 if (error
!= NULL
) {
1218 g_critical("%s", error
->message
);
1219 g_error_free(error
);
1223 main_window
= _adg_main_window(builder
);
1224 g_object_unref(builder
);
1226 gtk_widget_show_all(main_window
);