1 /* ADG - Automatic Drawing Generation
2 * Copyright (C) 2007-2021 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 */
78 /* Special entities */
79 AdgTitleBlock
*title_block
;
87 g_print("adg-demo " PACKAGE_VERSION
"\n");
92 parse_args(gint
*p_argc
, gchar
**p_argv
[])
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
},
104 gtk_init_with_args(p_argc
, p_argv
, _("- ADG demonstration program"),
105 entries
, GETTEXT_PACKAGE
, &error
);
107 g_error("%s", error
->message
);
108 g_assert_not_reached();
114 * @message: a custom error message
115 * @parent_window: the parent window or %NULL
117 * Convenient function that presents an error dialog and waits the user
118 * to close this modal dialog.
121 _adg_error(const gchar
*message
, GtkWindow
*parent_window
)
123 GtkWidget
*dialog
= gtk_message_dialog_new(parent_window
,
124 GTK_DIALOG_DESTROY_WITH_PARENT
,
128 gtk_window_set_title(GTK_WINDOW(dialog
), _("Error from adg-demo"));
129 gtk_dialog_run(GTK_DIALOG(dialog
));
130 gtk_widget_destroy(dialog
);
134 _adg_path_add_groove(AdgPath
*path
, const DemoPart
*part
)
139 model
= ADG_MODEL(path
);
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
);
146 pair
.y
= part
->D3
/ 2;
147 adg_model_set_named_pair(model
, "DGROOVEY_POS", &pair
);
149 pair
.y
= part
->DGROOVE
/ 2;
150 adg_path_line_to(path
, &pair
);
151 adg_model_set_named_pair(model
, "DGROOVEI_Y", &pair
);
153 pair
.x
+= part
->LGROOVE
;
154 adg_path_line_to(path
, &pair
);
156 pair
.y
= part
->D3
/ 2;
157 adg_model_set_named_pair(model
, "DGROOVEX_POS", &pair
);
159 pair
.y
= part
->D1
/ 2;
160 adg_path_line_to(path
, &pair
);
161 adg_model_set_named_pair(model
, "DGROOVEF_X", &pair
);
166 _adg_part_define_title_block(DemoPart
*part
)
168 g_object_set(part
->title_block
,
169 "title", part
->TITLE
,
170 "author", part
->AUTHOR
,
172 "drawing", part
->DRAWING
,
173 "logo", adg_logo_new(),
174 "projection", adg_projection_new(ADG_PROJECTION_SCHEME_FIRST_ANGLE
),
180 _adg_part_define_hole(DemoPart
*part
)
187 model
= ADG_MODEL(path
);
189 pair
.x
= part
->LHOLE
;
192 adg_path_move_to(path
, &pair
);
193 adg_model_set_named_pair(model
, "LHOLE", &pair
);
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
);
201 adg_path_line_to(path
, &pair
);
202 adg_model_set_named_pair(model
, "DHOLE", &pair
);
204 pair
.y
= (part
->D1
+ part
->DHOLE
) / 4;
205 adg_path_line_to(path
, &pair
);
207 adg_path_curve_to_explicit(path
,
208 part
->LHOLE
/ 2, part
->DHOLE
/ 2,
209 part
->LHOLE
+ 2, part
->D1
/ 2,
211 adg_path_reflect(path
, NULL
);
213 adg_path_close(path
);
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
);
219 adg_path_line_to(path
, &edge
);
223 _adg_part_define_body(DemoPart
*part
)
228 const CpmlPrimitive
*primitive
;
231 model
= ADG_MODEL(path
);
234 pair
.y
= part
->D1
/ 2;
235 adg_path_move_to(path
, &pair
);
236 adg_model_set_named_pair(model
, "D1I", &pair
);
239 _adg_path_add_groove(path
, part
);
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
);
246 pair
.y
= part
->D3
/ 2;
247 adg_model_set_named_pair(model
, "D2_POS", &pair
);
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
);
254 pair
.x
= part
->A
- part
->B
;
255 adg_path_line_to(path
, &pair
);
256 adg_path_fillet(path
, 0.4);
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
);
264 adg_model_set_named_pair(model
, "East", &pair
);
267 adg_model_set_named_pair(model
, "West", &pair
);
269 adg_path_chamfer(path
, CHAMFER
, CHAMFER
);
271 pair
.x
= part
->A
- part
->B
+ part
->LD3
;
272 pair
.y
= part
->D3
/ 2;
273 adg_path_line_to(path
, &pair
);
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
);
279 cpml_primitive_put_point(primitive
, -1, &tmp
);
280 adg_model_set_named_pair(model
, "D3I_Y", &tmp
);
282 adg_path_chamfer(path
, CHAMFER
, CHAMFER
);
284 pair
.y
= part
->D4
/ 2;
285 adg_path_line_to(path
, &pair
);
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
);
293 adg_path_fillet(path
, part
->RD34
);
295 pair
.x
+= part
->RD34
;
296 adg_model_set_named_pair(model
, "D4I", &pair
);
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
);
302 pair
.y
= part
->D3
/ 2;
303 adg_model_set_named_pair(model
, "D4_POS", &pair
);
305 primitive
= adg_path_over_primitive(path
);
306 cpml_primitive_put_point(primitive
, 0, &tmp
);
308 adg_model_set_named_pair(model
, "RD34", &tmp
);
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
);
316 adg_model_set_named_pair(model
, "RD34_XY", &tmp
);
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
);
323 pair
.x
= part
->A
- part
->C
;
324 adg_path_line_to(path
, &pair
);
326 adg_path_fillet(path
, 0.2);
328 pair
.y
= part
->D6
/ 2;
329 adg_path_line_to(path
, &pair
);
331 primitive
= adg_path_over_primitive(path
);
332 cpml_primitive_put_point(primitive
, 0, &tmp
);
333 adg_model_set_named_pair(model
, "D5F", &tmp
);
335 adg_path_fillet(path
, 0.1);
338 adg_path_line_to(path
, &pair
);
339 adg_model_set_named_pair(model
, "D6F", &pair
);
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
);
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
);
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
);
354 pair
.y
= part
->D7
/ 2;
355 adg_path_line_to(path
, &pair
);
358 adg_path_line_to(path
, &pair
);
359 adg_model_set_named_pair(model
, "D7F", &pair
);
361 adg_path_reflect(path
, NULL
);
363 adg_path_close(path
);
367 _adg_part_define_axis(DemoPart
*part
)
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.
378 adg_path_move_to_explicit(path
, -1, 0);
379 adg_path_line_to_explicit(path
, part
->A
+ 1, 0);
383 _adg_part_lock(DemoPart
*part
)
385 gtk_widget_set_sensitive(GTK_WIDGET(part
->apply
), FALSE
);
386 gtk_widget_set_sensitive(GTK_WIDGET(part
->reset
), FALSE
);
390 _adg_part_unlock(DemoPart
*part
)
392 gtk_widget_set_sensitive(GTK_WIDGET(part
->apply
), TRUE
);
393 gtk_widget_set_sensitive(GTK_WIDGET(part
->reset
), TRUE
);
397 _adg_part_link(DemoPart
*part
, gpointer data
, GObject
*widget
)
399 const gchar
*edit_signal
;
401 g_assert(GTK_IS_WIDGET(widget
));
402 g_object_ref(widget
);
403 g_hash_table_insert(part
->widgets
, data
, widget
);
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
);
411 _adg_part_ui_to_boolean(DemoPart
*part
, gboolean
*data
)
413 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
415 g_assert(GTK_IS_TOGGLE_BUTTON(widget
));
417 *data
= gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget
));
421 _adg_part_ui_to_double(DemoPart
*part
, gdouble
*data
)
424 GtkSpinButton
*spin_button
;
426 widget
= g_hash_table_lookup(part
->widgets
, data
);
427 g_assert(GTK_IS_SPIN_BUTTON(widget
));
429 spin_button
= GTK_SPIN_BUTTON(widget
);
430 gtk_spin_button_update(spin_button
);
431 *data
= gtk_spin_button_get_value(spin_button
);
435 _adg_part_ui_to_string(DemoPart
*part
, gchar
**data
)
437 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
439 g_assert(GTK_IS_ENTRY(widget
));
442 *data
= g_strdup(gtk_entry_get_text(GTK_ENTRY(widget
)));
446 _adg_part_boolean_to_ui(DemoPart
*part
, gboolean
*data
)
448 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
450 g_assert(GTK_IS_TOGGLE_BUTTON(widget
));
452 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget
), *data
);
456 _adg_part_double_to_ui(DemoPart
*part
, gdouble
*data
)
458 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
460 g_assert(GTK_IS_SPIN_BUTTON(widget
));
462 gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget
), *data
);
466 _adg_part_string_to_ui(DemoPart
*part
, gchar
**data
)
468 GtkWidget
*widget
= g_hash_table_lookup(part
->widgets
, data
);
470 g_assert(GTK_IS_ENTRY(widget
));
472 gtk_entry_set_text(GTK_ENTRY(widget
), *data
);
476 _adg_demo_canvas_add_dimensions(AdgCanvas
*canvas
, AdgModel
*model
)
481 AdgStyle
*style
, *diameter
;
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");
488 ldim
= adg_ldim_new_full_from_model(model
, "-D3I_X", "-D3F_X", "-D3F_Y",
490 adg_dim_set_outside(ADG_DIM(ldim
), ADG_THREE_STATE_OFF
);
491 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
493 ldim
= adg_ldim_new_full_from_model(model
, "-D6I_X", "-D67", "-East",
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
));
499 ldim
= adg_ldim_new_full_from_model(model
, "-D6I_X", "-D7F", "-East",
501 adg_dim_set_limits(ADG_DIM(ldim
), "-0.06", NULL
);
502 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
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
));
509 rdim
= adg_rdim_new_full_from_model(model
, "-RD34", "-RD34_R", "-RD34_XY");
510 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(rdim
));
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
));
516 ldim
= adg_ldim_new_full_from_model(model
, "D2I", "-D2I", "-D2_POS",
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
));
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
));
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
));
536 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "LHOLE", "West",
538 adg_ldim_switch_extension1(ldim
, FALSE
);
539 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
541 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "DGROOVEI_X", "West",
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
));
547 ldim
= adg_ldim_new_full_from_model(model
, "D4F", "D6I_X", "D4_POS",
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
));
553 ldim
= adg_ldim_new_full_from_model(model
, "D1F", "D3I_X", "D2_POS",
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
));
560 ldim
= adg_ldim_new_full_from_model(model
, "D3I_X", "D7F", "East",
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
));
568 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "D7F", "D3F_Y",
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
));
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
));
581 ldim
= adg_ldim_new_full_from_model(model
, "D6F", "-D6F", "East",
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
));
588 ldim
= adg_ldim_new_full_from_model(model
, "D4F", "-D4F", "East",
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
));
594 ldim
= adg_ldim_new_full_from_model(model
, "D5F", "-D5F", "East",
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
));
601 ldim
= adg_ldim_new_full_from_model(model
, "D7F", "-D7F", "East",
603 adg_entity_set_style(ADG_ENTITY(ldim
), ADG_DRESS_DIMENSION
, diameter
);
604 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
607 ldim
= adg_ldim_new_full_from_model(model
, "DHOLE", "-DHOLE", "-West",
609 adg_entity_set_style(ADG_ENTITY(ldim
), ADG_DRESS_DIMENSION
, diameter
);
610 adg_container_add(ADG_CONTAINER(canvas
), ADG_ENTITY(ldim
));
612 ldim
= adg_ldim_new_full_from_model(model
, "D1I", "-D1I", "-West",
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
));
619 ldim
= adg_ldim_new_full_from_model(model
, "D3I_Y", "-D3I_Y", "-West",
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
));
628 _adg_demo_canvas_add_axis(AdgCanvas
*canvas
, AdgTrail
*trail
)
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
));
636 _adg_canvas_init(AdgCanvas
*canvas
, DemoPart
*part
)
638 AdgContainer
*container
;
641 container
= (AdgContainer
*) canvas
;
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
);
647 entity
= ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part
->body
)));
648 adg_container_add(container
, entity
);
650 entity
= ADG_ENTITY(adg_hatch_new(ADG_TRAIL(part
->hole
)));
651 adg_container_add(container
, entity
);
653 entity
= ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part
->hole
)));
654 adg_container_add(container
, entity
);
656 entity
= ADG_ENTITY(adg_stroke_new(ADG_TRAIL(part
->edges
)));
657 adg_container_add(container
, entity
);
659 _adg_demo_canvas_add_dimensions(canvas
, ADG_MODEL(part
->body
));
661 _adg_demo_canvas_add_axis(canvas
, ADG_TRAIL(part
->axis
));
666 static GtkRadioButton
*
667 _adg_group_get_active(GtkRadioButton
*radio_group
)
669 GSList
*list
= gtk_radio_button_get_group(radio_group
);
672 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(list
->data
)))
682 _adg_do_edit(DemoPart
*part
)
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);
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
);
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
);
711 _adg_part_lock(part
);
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
));
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
);
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
));
728 gtk_widget_queue_draw(GTK_WIDGET(part
->area
));
732 _adg_do_reset(DemoPart
*part
)
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);
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
);
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
);
761 _adg_part_lock(part
);
765 _adg_do_save_as(GtkWindow
*window
, GtkResponseType response
, AdgCanvas
*canvas
)
767 GtkRadioButton
*type_radio
;
768 gchar
*file
, *suffix
;
769 cairo_surface_type_t type
;
772 if (response
!= GTK_RESPONSE_OK
) {
773 gtk_widget_hide(GTK_WIDGET(window
));
777 file
= gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(window
));
781 type_radio
= _adg_group_get_active(g_object_get_data(G_OBJECT(window
),
783 g_assert(GTK_IS_RADIO_BUTTON(type_radio
));
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
)) {
790 file
= g_strconcat(file
, suffix
, NULL
);
797 type
= adg_type_from_filename(file
);
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"));
803 adg_canvas_export(canvas
, type
, file
, &error
);
808 _adg_error(error
->message
, window
);
812 gtk_widget_hide(GTK_WIDGET(window
));
816 _adg_print_prepare(GtkPrintOperation
*operation
, GtkPrintContext
*context
)
818 gtk_print_operation_set_n_pages(operation
, 1);
822 _adg_print_page(GtkPrintOperation
*operation
, GtkPrintContext
*context
,
823 gint page_nr
, AdgEntity
*canvas
)
825 cairo_t
*cr
= gtk_print_context_get_cairo_context(context
);
826 cairo_matrix_t old_map
;
828 adg_matrix_copy(&old_map
, adg_entity_get_global_map(canvas
));;
830 adg_entity_set_global_map(canvas
, adg_matrix_identity());
831 adg_entity_render(canvas
, cr
);
833 adg_entity_set_global_map(canvas
, &old_map
);
837 _adg_do_print(GtkWidget
*button
, AdgCanvas
*canvas
)
839 static GtkPrintSettings
*settings
= NULL
;
841 GtkPrintOperation
*operation
;
842 GtkPageSetup
*page_setup
;
845 window
= (GtkWindow
*) gtk_widget_get_toplevel(button
);
846 operation
= gtk_print_operation_new();
847 page_setup
= adg_canvas_get_page_setup(canvas
);
851 gtk_print_operation_set_print_settings(operation
, settings
);
853 gtk_print_operation_set_default_page_setup(operation
, page_setup
);
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
);
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
);
866 switch (gtk_print_operation_run(operation
,
867 GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG
,
870 case GTK_PRINT_OPERATION_RESULT_APPLY
:
872 g_object_unref(settings
);
873 settings
= gtk_print_operation_get_print_settings(operation
);
875 g_object_ref(settings
);
882 g_object_unref(operation
);
885 _adg_error(error
->message
, window
);
889 _adg_button_press(AdgGtkArea
*area
, GdkEventButton
*event
)
893 if (event
->button
!= 1 && event
->button
!= 3)
896 canvas
= adg_gtk_area_get_canvas(area
);
897 g_return_val_if_fail(ADG_IS_CANVAS(canvas
), FALSE
);
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
);
911 _adg_part_new(GtkBuilder
*builder
)
914 GObject
*object
, *toggle_object
;
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
));
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
));
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"));
949 g_signal_connect(part
->area
, "button-press-event",
950 G_CALLBACK(_adg_button_press
), NULL
);
952 toggle_object
= gtk_builder_get_object(builder
, "editGROOVE");
953 _adg_part_link(part
, &part
->GROOVE
, toggle_object
);
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
);
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
);
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
);
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"));
996 _adg_part_destroy(DemoPart
*part
)
998 g_hash_table_destroy(part
->widgets
);
1003 _adg_help_window(GtkBuilder
*builder
)
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
);
1015 _adg_about_window(GtkBuilder
*builder
)
1018 GList
*icon_list
, *last_node
;
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
);
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
);
1032 g_list_free(icon_list
);
1038 _adg_edit_window(GtkBuilder
*builder
, DemoPart
*part
)
1042 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndEdit");
1043 g_assert(GTK_IS_DIALOG(window
));
1045 gtk_window_set_position(GTK_WINDOW(window
), GTK_WIN_POS_MOUSE
);
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
);
1058 _adg_save_as_window(GtkBuilder
*builder
, AdgCanvas
*canvas
)
1061 GtkWidget
*type_group
;
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
));
1068 g_object_set_data(G_OBJECT(window
), "type-group", type_group
);
1070 /* Set the default destination file */
1071 if (GTK_IS_FILE_CHOOSER(window
)) {
1072 GtkFileChooser
*file_chooser
;
1075 file_chooser
= (GtkFileChooser
*) window
;
1077 #if GLIB_CHECK_VERSION(2, 14, 0)
1078 dir
= g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS
);
1084 dir
= g_get_home_dir();
1086 gtk_file_chooser_set_current_folder(file_chooser
, dir
);
1087 gtk_file_chooser_set_current_name(file_chooser
, "adg-demo");
1090 g_signal_connect(window
, "response", G_CALLBACK(_adg_do_save_as
), canvas
);
1096 _adg_main_window(GtkBuilder
*builder
)
1102 GtkWidget
*button_edit
, *button_save_as
, *button_print
;
1103 GtkWidget
*button_help
, *button_about
, *button_quit
;
1105 path
= _demo_file("icons");
1106 adg_gtk_use_default_icons(path
);
1109 window
= (GtkWidget
*) gtk_builder_get_object(builder
, "wndMain");
1110 part
= _adg_part_new(builder
);
1111 canvas
= adg_canvas_new();
1113 _adg_canvas_init(canvas
, part
);
1114 adg_gtk_area_set_canvas(part
->area
, canvas
);
1115 adg_canvas_autoscale(canvas
);
1117 button_help
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainHelp");
1118 g_assert(GTK_IS_BUTTON(button_help
));
1119 button_about
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainAbout");
1120 g_assert(GTK_IS_BUTTON(button_about
));
1121 g_assert(GTK_IS_WINDOW(window
));
1122 button_edit
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainEdit");
1123 g_assert(GTK_IS_BUTTON(button_edit
));
1124 button_save_as
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainSaveAs");
1125 g_assert(GTK_IS_BUTTON(button_save_as
));
1126 button_print
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainPrint");
1127 g_assert(GTK_IS_BUTTON(button_print
));
1128 button_quit
= (GtkWidget
*) gtk_builder_get_object(builder
, "mainQuit");
1129 g_assert(GTK_IS_BUTTON(button_quit
));
1131 g_signal_connect_swapped(button_help
, "clicked",
1132 G_CALLBACK(gtk_dialog_run
),
1133 _adg_help_window(builder
));
1134 g_signal_connect_swapped(button_about
, "clicked",
1135 G_CALLBACK(gtk_dialog_run
),
1136 _adg_about_window(builder
));
1137 g_signal_connect_swapped(button_edit
, "clicked",
1138 G_CALLBACK(gtk_dialog_run
),
1139 _adg_edit_window(builder
, part
));
1140 g_signal_connect_swapped(button_save_as
, "clicked",
1141 G_CALLBACK(gtk_dialog_run
),
1142 _adg_save_as_window(builder
, canvas
));
1143 g_signal_connect(button_print
, "clicked",
1144 G_CALLBACK(_adg_do_print
), canvas
);
1145 g_signal_connect(button_quit
, "clicked", G_CALLBACK(gtk_main_quit
), NULL
);
1146 g_signal_connect(window
, "delete-event", G_CALLBACK(gtk_main_quit
), NULL
);
1147 g_signal_connect_swapped(window
, "destroy",
1148 G_CALLBACK(_adg_part_destroy
), part
);
1155 main(gint argc
, gchar
**argv
)
1158 GtkBuilder
*builder
;
1160 GtkWidget
*main_window
;
1162 _demo_init(argc
, argv
);
1163 parse_args(&argc
, &argv
);
1164 adg_switch_extents(show_extents
);
1166 path
= _demo_file("adg-demo.ui");
1168 g_printerr(_("adg-demo.ui not found!\n"));
1172 builder
= gtk_builder_new();
1175 /* Ensure AdgGtkLayout (referenced by adg-demo.ui) is registered
1176 * to possibly avoid an "Invalid object type" error */
1177 g_type_ensure(ADG_GTK_TYPE_LAYOUT
);
1179 gtk_builder_set_translation_domain(builder
, GETTEXT_PACKAGE
);
1180 gtk_builder_add_from_file(builder
, path
, &error
);
1183 if (error
!= NULL
) {
1184 g_critical("%s", error
->message
);
1185 g_error_free(error
);
1189 main_window
= _adg_main_window(builder
);
1190 g_object_unref(builder
);
1192 gtk_widget_show_all(main_window
);