1 /* gEDA - GPL Electronic Design Automation
2 * gschem - gEDA Schematic Capture
3 * Copyright (C) 1998-2010 Ales Hvezda
4 * Copyright (C) 1998-2019 gEDA Contributors (see ChangeLog for details)
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 * \file gschem_options_dockable.c
23 * \brief A dockable for editing options
38 #include "../include/gschem_options_dockable.h"
42 class_init (GschemOptionsDockableClass
*klass
);
45 create_grid_mode_widget (GschemOptionsDockable
*dockable
);
48 create_snap_mode_widget (GschemOptionsDockable
*dockable
);
51 create_net_section (GschemOptionsDockable
*dockable
);
54 create_snap_section (GschemOptionsDockable
*dockable
);
57 dispose (GObject
*object
);
60 create_widget (GschemDockable
*parent
);
63 set_options (GschemOptionsDockable
*dockable
, GschemOptions
*options
);
66 update_grid_mode_model (GschemOptionsDockable
*dockable
, GtkWidget
*button
);
69 update_grid_mode_widget (GschemOptionsDockable
*dockable
);
72 update_magnetic_net_mode_model (GschemOptionsDockable
*dockable
);
75 update_magnetic_net_mode_widget (GschemOptionsDockable
*dockable
);
78 update_net_rubber_band_mode_model (GschemOptionsDockable
*dockable
);
81 update_net_rubber_band_mode_widget (GschemOptionsDockable
*dockable
);
84 update_snap_mode_model (GschemOptionsDockable
*dockable
, GtkWidget
*button
);
87 update_snap_mode_widget (GschemOptionsDockable
*dockable
);
91 /*! \brief Get/register options dockable type.
94 gschem_options_dockable_get_type ()
96 static GType type
= 0;
99 static const GTypeInfo info
= {
100 sizeof(GschemOptionsDockableClass
),
101 NULL
, /* base_init */
102 NULL
, /* base_finalize */
103 (GClassInitFunc
) class_init
,
104 NULL
, /* class_finalize */
105 NULL
, /* class_data */
106 sizeof(GschemOptionsDockable
),
108 NULL
, /* instance_init */
111 type
= g_type_register_static (GSCHEM_TYPE_DOCKABLE
,
112 "GschemOptionsDockable",
123 * \brief Initialize the options dockable class structure
128 class_init (GschemOptionsDockableClass
*klass
)
130 GObjectClass
*object_class
;
132 g_return_if_fail (klass
!= NULL
);
134 GSCHEM_DOCKABLE_CLASS (klass
)->create_widget
= create_widget
;
136 object_class
= G_OBJECT_CLASS (klass
);
138 g_return_if_fail (object_class
!= NULL
);
140 object_class
->dispose
= dispose
;
146 * \brief Create the series of buttons that make the grid mode selection widget
148 * \param [in] dockable
149 * \return The grid mode widget
152 create_grid_mode_widget (GschemOptionsDockable
*dockable
)
157 g_return_val_if_fail (dockable
!= NULL
, NULL
);
159 box
= gtk_hbox_new (FALSE
, FALSE
);
161 for (index
=0; index
<GRID_MODE_COUNT
; index
++) {
162 dockable
->grid_radio
[index
] = gtk_toggle_button_new ();
164 gtk_box_pack_start (GTK_BOX (box
), /* box */
165 dockable
->grid_radio
[index
], /* child */
170 gtk_size_group_add_widget (dockable
->size_group
, dockable
->grid_radio
[index
]);
172 g_signal_connect_swapped (G_OBJECT (dockable
->grid_radio
[index
]),
174 G_CALLBACK (update_grid_mode_model
),
178 gtk_button_set_label (GTK_BUTTON (dockable
->grid_radio
[GRID_MODE_NONE
]),
181 gtk_button_set_label (GTK_BUTTON (dockable
->grid_radio
[GRID_MODE_DOTS
]),
184 gtk_button_set_label (GTK_BUTTON (dockable
->grid_radio
[GRID_MODE_MESH
]),
193 * \brief Create section with net tool settings
195 * \param [in] dockable
196 * \return The net section widget
199 create_net_section (GschemOptionsDockable
*dockable
)
203 GtkWidget
*editor
[2];
205 /* These widgets are shown in the same order as the options menu */
207 label
[0] = gschem_dialog_misc_create_property_label (_("Net Rubber Band Mode:"));
208 label
[1] = gschem_dialog_misc_create_property_label (_("Magnetic Net Mode:"));
210 /*! \todo These should become a GtkSwitch when updating to GTK 3.0 */
212 editor
[0] = dockable
->net_rubber_band_widget
= gtk_check_button_new_with_label (_("Enabled"));
213 editor
[1] = dockable
->magnetic_net_widget
= gtk_check_button_new_with_label (_("Enabled"));
215 table
= gschem_dialog_misc_create_property_table (label
, editor
, 2);
217 g_signal_connect_swapped (G_OBJECT (dockable
->magnetic_net_widget
),
219 G_CALLBACK (update_magnetic_net_mode_model
),
222 g_signal_connect_swapped (G_OBJECT (dockable
->net_rubber_band_widget
),
224 G_CALLBACK (update_net_rubber_band_mode_model
),
227 return gschem_dialog_misc_create_section_widget (_("<b>Net Options</b>"), table
);
232 * \brief Create section with snap and grid settings
234 * \param [in] dockable
235 * \return The snap section widget
238 create_snap_section (GschemOptionsDockable
*dockable
)
242 GtkWidget
*editor
[3];
244 label
[0] = gschem_dialog_misc_create_property_label (_("Grid Mode:"));
245 label
[1] = gschem_dialog_misc_create_property_label (_("Snap Mode:"));
246 label
[2] = gschem_dialog_misc_create_property_label (_("Grid Spacing:"));
248 editor
[0] = create_grid_mode_widget (dockable
);
249 editor
[1] = create_snap_mode_widget (dockable
);
250 editor
[2] = x_grid_size_sb_new (GSCHEM_DOCKABLE (dockable
)->w_current
);
252 table
= gschem_dialog_misc_create_property_table (label
, editor
, 3);
254 return gschem_dialog_misc_create_section_widget (_("<b>Grid Options</b>"), table
);
260 * \brief Create the series of buttons that make the snap mode selection widget
262 * \param [in] dockable
263 * \return The snap mode widget
266 create_snap_mode_widget (GschemOptionsDockable
*dockable
)
271 g_return_val_if_fail (dockable
!= NULL
, NULL
);
273 box
= gtk_hbox_new (FALSE
, FALSE
);
275 for (index
=0; index
<SNAP_STATE_COUNT
; index
++) {
276 dockable
->snap_radio
[index
] = gtk_toggle_button_new ();
278 gtk_box_pack_start (GTK_BOX (box
), /* box */
279 dockable
->snap_radio
[index
], /* child */
284 gtk_size_group_add_widget (dockable
->size_group
, dockable
->snap_radio
[index
]);
286 g_signal_connect_swapped (G_OBJECT (dockable
->snap_radio
[index
]),
288 G_CALLBACK (update_snap_mode_model
),
292 gtk_button_set_label (GTK_BUTTON (dockable
->snap_radio
[SNAP_OFF
]),
295 gtk_button_set_label (GTK_BUTTON (dockable
->snap_radio
[SNAP_GRID
]),
298 gtk_button_set_label (GTK_BUTTON (dockable
->snap_radio
[SNAP_RESNAP
]),
308 * \param [in] object The options dockable to dispose
311 dispose (GObject
*object
)
313 GschemOptionsDockable
*dockable
;
314 GschemOptionsDockableClass
*klass
;
315 GObjectClass
*parent_class
;
317 g_return_if_fail (object
!= NULL
);
319 dockable
= GSCHEM_OPTIONS_DOCKABLE (object
);
321 set_options (dockable
, NULL
);
323 //g_slist_foreach (dockable->bindings, (GFunc) g_object_unref, NULL);
324 //g_slist_free (dockable->bindings);
325 //dockable->bindings = NULL;
327 /* lastly, chain up to the parent dispose */
329 klass
= GSCHEM_OPTIONS_DOCKABLE_GET_CLASS (object
);
330 g_return_if_fail (klass
!= NULL
);
331 parent_class
= g_type_class_peek_parent (klass
);
332 g_return_if_fail (parent_class
!= NULL
);
333 parent_class
->dispose (object
);
338 * \brief Create widgets and set up property change notifications
340 * \param [in,out] parent This dockable
343 create_widget (GschemDockable
*parent
)
345 GschemOptionsDockable
*dockable
= GSCHEM_OPTIONS_DOCKABLE (parent
);
348 dockable
->size_group
= gtk_size_group_new (GTK_SIZE_GROUP_BOTH
);
350 vbox
= gtk_vbox_new (FALSE
, DIALOG_V_SPACING
);
351 gtk_container_set_border_width (GTK_CONTAINER (vbox
), DIALOG_BORDER_SPACING
);
353 gtk_box_pack_start (GTK_BOX (vbox
), /* box */
354 create_snap_section (dockable
), /* child */
359 gtk_box_pack_start (GTK_BOX (vbox
), /* box */
360 create_net_section (dockable
), /* child */
365 set_options (dockable
, parent
->w_current
->options
);
367 gtk_widget_show_all (vbox
);
374 * \brief Set the options that this dockable manipulates
376 * \param [in,out] dockable This dockable
377 * \param [in] options The options to manipulate
380 set_options (GschemOptionsDockable
*dockable
, GschemOptions
*options
)
382 if (dockable
->options
!= NULL
) {
383 g_signal_handlers_disconnect_by_func (dockable
->options
,
384 G_CALLBACK (update_snap_mode_widget
),
387 g_signal_handlers_disconnect_by_func (dockable
->options
,
388 G_CALLBACK (update_net_rubber_band_mode_widget
),
391 g_signal_handlers_disconnect_by_func (dockable
->options
,
392 G_CALLBACK (update_magnetic_net_mode_widget
),
395 g_signal_handlers_disconnect_by_func (dockable
->options
,
396 G_CALLBACK (update_grid_mode_widget
),
399 g_object_unref (dockable
->options
);
402 dockable
->options
= options
;
404 if (dockable
->options
!= NULL
) {
405 g_object_ref (dockable
->options
);
407 g_signal_connect_swapped (dockable
->options
,
409 G_CALLBACK (update_grid_mode_widget
),
412 g_signal_connect_swapped (dockable
->options
,
413 "notify::magnetic-net-mode",
414 G_CALLBACK (update_magnetic_net_mode_widget
),
417 g_signal_connect_swapped (dockable
->options
,
418 "notify::net-rubber-band-mode",
419 G_CALLBACK (update_net_rubber_band_mode_widget
),
422 g_signal_connect_swapped (dockable
->options
,
424 G_CALLBACK (update_snap_mode_widget
),
428 update_grid_mode_widget (dockable
);
429 update_magnetic_net_mode_widget (dockable
);
430 update_net_rubber_band_mode_widget (dockable
);
431 update_snap_mode_widget (dockable
);
436 * \brief Update the grid mode in the model
438 * \param [in,out] dockable This dockable
441 update_grid_mode_model (GschemOptionsDockable
*dockable
, GtkWidget
*button
)
443 g_return_if_fail (dockable
!= NULL
);
445 if (dockable
->options
!= NULL
) {
448 for (index
= 0; index
< GRID_MODE_COUNT
; index
++) {
449 if (dockable
->grid_radio
[index
] == button
) {
450 gschem_options_set_grid_mode (dockable
->options
, index
);
460 * \brief Update the grid mode widget with the current value
462 * \param [in,out] dockable This dockable
465 update_grid_mode_widget (GschemOptionsDockable
*dockable
)
467 g_return_if_fail (dockable
!= NULL
);
469 if (dockable
->options
!= NULL
) {
473 grid_mode
= gschem_options_get_grid_mode (dockable
->options
);
475 for (index
=0; index
<GRID_MODE_COUNT
; index
++) {
476 g_signal_handlers_block_by_func (G_OBJECT (dockable
->grid_radio
[index
]),
477 G_CALLBACK (update_grid_mode_model
),
481 for (index
=0; index
<GRID_MODE_COUNT
; index
++) {
482 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dockable
->grid_radio
[index
]),
483 (grid_mode
== index
));
486 for (index
=0; index
<GRID_MODE_COUNT
; index
++) {
487 g_signal_handlers_unblock_by_func (G_OBJECT (dockable
->grid_radio
[index
]),
488 G_CALLBACK (update_grid_mode_model
),
497 * \brief Update the magnetic net mode in the model
499 * \param [in,out] dockable This dockable
502 update_magnetic_net_mode_model (GschemOptionsDockable
*dockable
)
504 GschemToplevel
*w_current
;
506 g_return_if_fail (dockable
!= NULL
);
508 g_object_get (dockable
, "gschem-toplevel", &w_current
, NULL
);
510 g_return_if_fail (w_current
!= NULL
);
512 gschem_options_set_magnetic_net_mode (w_current
->options
,
513 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dockable
->magnetic_net_widget
)));
519 * \brief Update the net rubber band mode widget with the current value
521 * \param [in,out] dockable This dockable
524 update_magnetic_net_mode_widget (GschemOptionsDockable
*dockable
)
526 g_return_if_fail (dockable
!= NULL
);
528 if (dockable
->options
!= NULL
) {
529 GschemToplevel
*w_current
;
531 g_object_get (dockable
, "gschem-toplevel", &w_current
, NULL
);
533 g_return_if_fail (w_current
!= NULL
);
535 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dockable
->magnetic_net_widget
),
536 gschem_options_get_magnetic_net_mode (w_current
->options
));
542 * \brief Update the net rubber band mode in the model
544 * \param [in,out] dockable This dockable
547 update_net_rubber_band_mode_model (GschemOptionsDockable
*dockable
)
549 GschemToplevel
*w_current
;
551 g_return_if_fail (dockable
!= NULL
);
553 g_object_get (dockable
, "gschem-toplevel", &w_current
, NULL
);
555 g_return_if_fail (w_current
!= NULL
);
557 gschem_options_set_net_rubber_band_mode (w_current
->options
,
558 gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dockable
->net_rubber_band_widget
)));
564 * \brief Update the net rubber band mode widget with the current value
566 * \param [in,out] dockable This dockable
569 update_net_rubber_band_mode_widget (GschemOptionsDockable
*dockable
)
571 g_return_if_fail (dockable
!= NULL
);
573 if (dockable
->options
!= NULL
) {
574 GschemToplevel
*w_current
;
576 g_object_get (dockable
, "gschem-toplevel", &w_current
, NULL
);
578 g_return_if_fail (w_current
!= NULL
);
580 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dockable
->net_rubber_band_widget
),
581 gschem_options_get_net_rubber_band_mode (w_current
->options
));
588 * \brief Update the snap mode in the model
590 * \param [in,out] dockable This dockable
593 update_snap_mode_model (GschemOptionsDockable
*dockable
, GtkWidget
*button
)
595 g_return_if_fail (dockable
!= NULL
);
597 if (dockable
->options
!= NULL
) {
600 for (index
= 0; index
< SNAP_STATE_COUNT
; index
++) {
601 if (dockable
->snap_radio
[index
] == button
) {
602 gschem_options_set_snap_mode (dockable
->options
, index
);
612 * \brief Update the snap mode widget with the current value
614 * \param [in,out] dockable This dockable
617 update_snap_mode_widget (GschemOptionsDockable
*dockable
)
619 g_return_if_fail (dockable
!= NULL
);
621 if (dockable
->options
!= NULL
) {
623 SNAP_STATE snap_mode
;
625 snap_mode
= gschem_options_get_snap_mode (dockable
->options
);
627 for (index
=0; index
<SNAP_STATE_COUNT
; index
++) {
628 g_signal_handlers_block_by_func (G_OBJECT (dockable
->snap_radio
[index
]),
629 G_CALLBACK (update_snap_mode_model
),
633 for (index
=0; index
<SNAP_STATE_COUNT
; index
++) {
634 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dockable
->snap_radio
[index
]),
635 (snap_mode
== index
));
638 for (index
=0; index
<SNAP_STATE_COUNT
; index
++) {
639 g_signal_handlers_unblock_by_func (G_OBJECT (dockable
->snap_radio
[index
]),
640 G_CALLBACK (update_snap_mode_model
),