1 /* Dia -- an diagram creation/manipulation program
2 * Copyright (C) 1998 Alexander Larsson
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program 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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 #undef GTK_DISABLE_DEPRECATED /* GtkOptionMenu, ... */
27 #include "diaarrowchooser.h"
28 #include "dialinechooser.h"
29 #include "persistence.h"
30 #include "dia-lib-icons.h"
36 #include <pango/pango.h>
39 #include <gdk/gdkkeysyms.h>
41 #include "diagtkfontsel.h"
43 /************* DiaSizeSelector: ***************/
44 /* A widget that selects two sizes, width and height, optionally keeping
45 * aspect ratio. When created, aspect ratio is locked, but the user can
46 * unlock it. The current users do not store aspect ratio, so we have
47 * to give a good default.
49 struct _DiaSizeSelector
52 GtkSpinButton
*width
, *height
;
53 GtkToggleButton
*aspect_locked
;
55 GtkAdjustment
*last_adjusted
;
58 struct _DiaSizeSelectorClass
60 GtkHBoxClass parent_class
;
64 dia_size_selector_unrealize(GtkWidget
*widget
)
66 (* GTK_WIDGET_CLASS (gtk_type_class(gtk_hbox_get_type ()))->unrealize
) (widget
);
70 dia_size_selector_class_init (DiaSizeSelectorClass
*class)
72 GtkObjectClass
*object_class
;
73 GtkWidgetClass
*widget_class
;
75 object_class
= (GtkObjectClass
*) class;
76 widget_class
= (GtkWidgetClass
*) class;
77 widget_class
->unrealize
= dia_size_selector_unrealize
;
81 dia_size_selector_adjust_width(DiaSizeSelector
*ss
)
84 gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(ss
->height
));
85 gtk_spin_button_set_value(GTK_SPIN_BUTTON(ss
->width
), height
*ss
->ratio
);
89 dia_size_selector_adjust_height(DiaSizeSelector
*ss
)
92 gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(ss
->width
));
93 gtk_spin_button_set_value(GTK_SPIN_BUTTON(ss
->height
), width
/ss
->ratio
);
97 dia_size_selector_ratio_callback(GtkAdjustment
*limits
, gpointer userdata
)
99 static gboolean in_progress
;
100 DiaSizeSelector
*ss
= DIA_SIZE_SELECTOR(userdata
);
102 ss
->last_adjusted
= limits
;
104 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ss
->aspect_locked
))
108 if (in_progress
) return;
111 if (limits
== gtk_spin_button_get_adjustment(GTK_SPIN_BUTTON(ss
->width
))) {
112 dia_size_selector_adjust_height(ss
);
114 dia_size_selector_adjust_width(ss
);
120 /** Update the ratio of this DSS to be the ratio of width to height.
121 * If height is 0, ratio becomes 0.0.
124 dia_size_selector_set_ratio(DiaSizeSelector
*ss
, real width
, real height
)
127 ss
->ratio
= width
/height
;
133 dia_size_selector_lock_pressed(GtkWidget
*widget
, gpointer data
)
135 DiaSizeSelector
*ss
= DIA_SIZE_SELECTOR(data
);
137 dia_size_selector_set_ratio(ss
,
138 gtk_spin_button_get_value(GTK_SPIN_BUTTON(ss
->width
)),
139 gtk_spin_button_get_value(GTK_SPIN_BUTTON(ss
->height
)));
142 /* Possible args: Init width, init height, digits */
145 dia_size_selector_init (DiaSizeSelector
*ss
)
150 /* Here's where we set up the real thing */
151 adj
= GTK_ADJUSTMENT(gtk_adjustment_new(1.0, 0.01, 10,
153 ss
->width
= GTK_SPIN_BUTTON(gtk_spin_button_new(adj
, 1.0, 2));
154 gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(ss
->width
), TRUE
);
155 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(ss
->width
), TRUE
);
156 gtk_box_pack_start(GTK_BOX(ss
), GTK_WIDGET(ss
->width
), FALSE
, TRUE
, 0);
157 gtk_widget_show(GTK_WIDGET(ss
->width
));
159 adj
= GTK_ADJUSTMENT(gtk_adjustment_new(1.0, 0.01, 10,
161 ss
->height
= GTK_SPIN_BUTTON(gtk_spin_button_new(adj
, 1.0, 2));
162 gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(ss
->height
), TRUE
);
163 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(ss
->height
), TRUE
);
164 gtk_box_pack_start(GTK_BOX(ss
), GTK_WIDGET(ss
->height
), FALSE
, TRUE
, 0);
165 gtk_widget_show(GTK_WIDGET(ss
->height
));
167 /* Replace label with images */
168 /* should make sure they're both unallocated when the widget dies.
169 * That should happen in the "destroy" handler, where both should
172 GTK_TOGGLE_BUTTON(dia_toggle_button_new_with_icons
173 (dia_unbroken_chain_icon
,
174 dia_broken_chain_icon
));
176 gtk_container_set_border_width(GTK_CONTAINER(ss
->aspect_locked
), 0);
178 gtk_box_pack_start(GTK_BOX(ss
), GTK_WIDGET(ss
->aspect_locked
), FALSE
, TRUE
, 0);
179 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ss
->aspect_locked
), TRUE
);
180 gtk_widget_show(GTK_WIDGET(ss
->aspect_locked
));
182 gtk_signal_connect (GTK_OBJECT (ss
->aspect_locked
), "clicked",
183 (GtkSignalFunc
) dia_size_selector_lock_pressed
,
185 /* Make sure that the aspect ratio stays the same */
186 g_signal_connect(GTK_OBJECT(gtk_spin_button_get_adjustment(ss
->width
)),
188 G_CALLBACK(dia_size_selector_ratio_callback
), (gpointer
)ss
);
189 g_signal_connect(GTK_OBJECT(gtk_spin_button_get_adjustment(ss
->height
)),
191 G_CALLBACK(dia_size_selector_ratio_callback
), (gpointer
)ss
);
195 dia_size_selector_get_type (void)
197 static GtkType dss_type
= 0;
200 static const GtkTypeInfo dss_info
= {
202 sizeof (DiaSizeSelector
),
203 sizeof (DiaSizeSelectorClass
),
204 (GtkClassInitFunc
) dia_size_selector_class_init
,
205 (GtkObjectInitFunc
) dia_size_selector_init
,
208 (GtkClassInitFunc
) NULL
,
211 dss_type
= gtk_type_unique (gtk_hbox_get_type (), &dss_info
);
219 dia_size_selector_new (real width
, real height
)
223 wid
= GTK_WIDGET ( gtk_type_new (dia_size_selector_get_type ()));
224 dia_size_selector_set_size(DIA_SIZE_SELECTOR(wid
), width
, height
);
229 dia_size_selector_set_size(DiaSizeSelector
*ss
, real width
, real height
)
231 gtk_spin_button_set_value(GTK_SPIN_BUTTON(ss
->width
), width
);
232 gtk_spin_button_set_value(GTK_SPIN_BUTTON(ss
->height
), height
);
234 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ss->aspect_locked),
235 fabs(width - height) < 0.000001);
237 dia_size_selector_set_ratio(ss
, width
, height
);
241 dia_size_selector_set_locked(DiaSizeSelector
*ss
, gboolean locked
)
243 if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ss
->aspect_locked
))
245 dia_size_selector_set_ratio(ss
,
246 gtk_spin_button_get_value(GTK_SPIN_BUTTON(ss
->width
)),
247 gtk_spin_button_get_value(GTK_SPIN_BUTTON(ss
->height
)));
249 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ss
->aspect_locked
), locked
);
253 dia_size_selector_get_size(DiaSizeSelector
*ss
, real
*width
, real
*height
)
255 *width
= gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(ss
->width
));
256 *height
= gtk_spin_button_get_value_as_float(GTK_SPIN_BUTTON(ss
->height
));
257 return gtk_toggle_button_get_active(ss
->aspect_locked
);
260 /************* DiaFontSelector: ***************/
262 struct _DiaFontSelector
266 GtkOptionMenu
*font_omenu
;
267 GtkOptionMenu
*style_omenu
;
271 struct _DiaFontSelectorClass
273 GtkHBoxClass parent_class
;
277 /* New and improved font selector: Contains the three standard fonts
278 * and an 'Other fonts...' entry that opens the font dialog. The fonts
279 * selected in the font dialog are persistently added to the menu.
294 static void dia_font_selector_fontmenu_callback(DiaDynamicMenu
*button
,
295 const gchar
*fontname
,
297 static void dia_font_selector_set_styles(DiaFontSelector
*fs
,
299 DiaFontStyle dia_style
);
300 static void dia_font_selector_set_style_menu(DiaFontSelector
*fs
,
301 PangoFontFamily
*pff
,
302 DiaFontStyle dia_style
);
305 dia_font_selector_class_init (DiaFontSelectorClass
*class)
307 GtkObjectClass
*object_class
;
309 object_class
= (GtkObjectClass
*) class;
313 dia_font_selector_sort_fonts(const void *p1
, const void *p2
)
315 const gchar
*n1
= pango_font_family_get_name(PANGO_FONT_FAMILY(*(void**)p1
));
316 const gchar
*n2
= pango_font_family_get_name(PANGO_FONT_FAMILY(*(void**)p2
));
317 return g_strcasecmp(n1
, n2
);
321 replace_ampersands(gchar
* string
)
323 gchar
** pieces
= g_strsplit(string
, "&", -1);
324 gchar
* escaped
= g_strjoinv("&", pieces
);
330 dia_font_selector_create_string_item(DiaDynamicMenu
*ddm
, gchar
*string
)
332 GtkWidget
*item
= gtk_menu_item_new_with_label(string
);
333 if (strchr(string
, '&')) {
334 gchar
*escaped
= replace_ampersands(string
);
335 gchar
*label
= g_strdup_printf("<span face=\"%s\" size=\"medium\">%s</span>",
337 gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(item
))), label
);
341 gchar
*label
= g_strdup_printf("<span face=\"%s\" size=\"medium\">%s</span>",
343 gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(item
))), label
);
350 dia_font_selector_init (DiaFontSelector
*fs
)
355 PangoFontFamily
**families
;
357 GList
*fontnames
= NULL
;
359 pango_context_list_families (dia_font_get_context(),
360 &families
, &n_families
);
361 qsort(families
, n_families
, sizeof(PangoFontFamily
*),
362 dia_font_selector_sort_fonts
);
363 /* Doing it the slow way until I find a better way */
364 for (i
= 0; i
< n_families
; i
++) {
365 fontnames
= g_list_append(fontnames
,
366 g_strdup(pango_font_family_get_name(families
[i
])));
372 (dia_dynamic_menu_new_listbased(dia_font_selector_create_string_item
,
373 dia_font_selector_fontmenu_callback
,
378 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(fs
->font_omenu
),
380 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(fs
->font_omenu
),
382 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(fs
->font_omenu
),
384 gtk_widget_show(GTK_WIDGET(fs
->font_omenu
));
386 /* Now build the style menu button */
387 omenu
= gtk_option_menu_new();
388 fs
->style_omenu
= GTK_OPTION_MENU(omenu
);
389 menu
= gtk_menu_new ();
390 fs
->style_menu
= GTK_MENU(menu
);
391 gtk_option_menu_set_menu (GTK_OPTION_MENU (fs
->style_omenu
), menu
);
393 gtk_widget_show(menu
);
394 gtk_widget_show(omenu
);
396 gtk_box_pack_start_defaults(GTK_BOX(fs
), GTK_WIDGET(fs
->font_omenu
));
397 gtk_box_pack_start_defaults(GTK_BOX(fs
), GTK_WIDGET(fs
->style_omenu
));
401 dia_font_selector_get_type (void)
403 static GtkType dfs_type
= 0;
406 static const GtkTypeInfo dfs_info
= {
408 sizeof (DiaFontSelector
),
409 sizeof (DiaFontSelectorClass
),
410 (GtkClassInitFunc
) dia_font_selector_class_init
,
411 (GtkObjectInitFunc
) dia_font_selector_init
,
414 (GtkClassInitFunc
) NULL
417 dfs_type
= gtk_type_unique (gtk_hbox_get_type (), &dfs_info
);
424 dia_font_selector_new ()
426 return GTK_WIDGET ( gtk_type_new (dia_font_selector_get_type ()));
429 static PangoFontFamily
*
430 dia_font_selector_get_family_from_name(GtkWidget
*widget
, const gchar
*fontname
)
432 PangoFontFamily
**families
;
435 pango_context_list_families (dia_font_get_context(),
436 &families
, &n_families
);
437 /* Doing it the slow way until I find a better way */
438 for (i
= 0; i
< n_families
; i
++) {
439 if (!(g_strcasecmp(pango_font_family_get_name(families
[i
]), fontname
))) {
440 PangoFontFamily
*fam
= families
[i
];
445 g_warning(_("Couldn't find font family for %s\n"), fontname
);
451 dia_font_selector_fontmenu_callback(DiaDynamicMenu
*ddm
, const gchar
*fontname
, gpointer data
)
453 DiaFontSelector
*fs
= DIAFONTSELECTOR(data
);
454 dia_font_selector_set_styles(fs
, fontname
, -1);
457 static char *style_labels
[] = {
462 "Ultralight-Oblique",
485 dia_font_selector_set_style_menu(DiaFontSelector
*fs
,
486 PangoFontFamily
*pff
,
487 DiaFontStyle dia_style
)
490 PangoFontFace
**faces
= NULL
;
492 GtkWidget
*menu
= NULL
;
494 int menu_item_nr
= 0;
495 GSList
*group
= NULL
;
497 menu
= gtk_menu_new ();
498 pango_font_family_list_faces(pff
, &faces
, &nfaces
);
500 for (i
= 0; i
< nfaces
; i
++) {
501 PangoFontDescription
*pfd
= pango_font_face_describe(faces
[i
]);
502 PangoStyle style
= pango_font_description_get_style(pfd
);
503 PangoWeight weight
= pango_font_description_get_weight(pfd
);
505 * This is a quick and dirty way to pick the styles present,
506 * sort them and avoid duplicates.
507 * We set a bit for each style present, bit (weight*3+style)
508 * From style_labels, we pick #(weight*3+style)
509 * where weight and style are the Dia types.
511 /* Account for DIA_WEIGHT_NORMAL hack */
512 int weightnr
= (weight
-200)/100;
513 if (weightnr
< 2) weightnr
++;
514 else if (weightnr
== 2) weightnr
= 0;
515 stylebits
|= 1 << (3*weightnr
+ style
);
516 pango_font_description_free(pfd
);
521 if (stylebits
== 0) {
522 g_warning ("'%s' has no style!",
523 pango_font_family_get_name (pff
) ? pango_font_family_get_name (pff
) : "(null font)");
526 for (i
= DIA_FONT_NORMAL
; i
<= (DIA_FONT_HEAVY
| DIA_FONT_ITALIC
); i
+=4) {
529 * bad hack continued ...
531 int weight
= DIA_FONT_STYLE_GET_WEIGHT(i
) >> 4;
532 int slant
= DIA_FONT_STYLE_GET_SLANT(i
) >> 2;
533 if (DIA_FONT_STYLE_GET_SLANT(i
) > DIA_FONT_ITALIC
) continue;
534 if (!(stylebits
& (1 << (3*weight
+ slant
)))) continue;
535 menuitem
= gtk_radio_menu_item_new_with_label (group
, style_labels
[3*weight
+slant
]);
536 group
= gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(menuitem
));
537 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(i
));
538 if (dia_style
== i
) {
539 select
= menu_item_nr
;
542 gtk_menu_append (GTK_MENU (menu
), menuitem
);
543 gtk_widget_show (menuitem
);
545 gtk_widget_show(menu
);
546 gtk_option_menu_remove_menu(fs
->style_omenu
);
547 gtk_option_menu_set_menu(fs
->style_omenu
, menu
);
548 fs
->style_menu
= GTK_MENU(menu
);
549 gtk_option_menu_set_history(GTK_OPTION_MENU(fs
->style_omenu
), select
);
550 gtk_menu_set_active(fs
->style_menu
, select
);
551 gtk_widget_set_sensitive(GTK_WIDGET(fs
->style_omenu
), menu_item_nr
> 1);
552 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(gtk_menu_get_active(fs
->style_menu
)), TRUE
);
556 dia_font_selector_set_styles(DiaFontSelector
*fs
,
557 const gchar
*name
, DiaFontStyle dia_style
)
559 PangoFontFamily
*pff
;
560 pff
= dia_font_selector_get_family_from_name(GTK_WIDGET(fs
), name
);
561 dia_font_selector_set_style_menu(fs
, pff
, dia_style
);
566 /** Set a string to be used for preview in the GTK font selector dialog.
567 * The start of this string will be copied.
568 * This function is now obsolete.
571 dia_font_selector_set_preview(DiaFontSelector
*fs
, gchar
*text
) {
574 /** Set the current font to be shown in the font selector.
577 dia_font_selector_set_font(DiaFontSelector
*fs
, DiaFont
*font
)
579 const gchar
*fontname
= dia_font_get_family(font
);
580 /* side effect: adds fontname to presistence list */
581 dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(fs
->font_omenu
), fontname
);
582 dia_font_selector_set_styles(fs
, fontname
, dia_font_get_style (font
));
586 dia_font_selector_get_font(DiaFontSelector
*fs
)
593 fontname
= dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(fs
->font_omenu
));
594 menuitem
= gtk_menu_get_active(fs
->style_menu
);
595 if (!menuitem
) /* FIXME: should not happen ??? (but does if we don't have added a style) */
598 style
= GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(menuitem
)));
599 font
= dia_font_new(fontname
, style
, 1.0);
604 /************* DiaAlignmentSelector: ***************/
605 struct _DiaAlignmentSelector
609 GtkMenu
*alignment_menu
;
612 struct _DiaAlignmentSelectorClass
614 GtkOptionMenuClass parent_class
;
618 dia_alignment_selector_class_init (DiaAlignmentSelectorClass
*class)
620 GtkObjectClass
*object_class
;
622 object_class
= (GtkObjectClass
*) class;
626 dia_alignment_selector_init (DiaAlignmentSelector
*fs
)
633 menu
= gtk_menu_new ();
634 fs
->alignment_menu
= GTK_MENU(menu
);
638 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Left"));
639 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(ALIGN_LEFT
));
640 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
641 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
642 gtk_widget_show (menuitem
);
644 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Center"));
645 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(ALIGN_CENTER
));
646 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
647 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
648 gtk_widget_show (menuitem
);
650 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Right"));
651 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(ALIGN_RIGHT
));
652 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
653 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
654 gtk_widget_show (menuitem
);
656 gtk_menu_set_active(GTK_MENU (menu
), DEFAULT_ALIGNMENT
);
657 gtk_option_menu_set_menu (GTK_OPTION_MENU (fs
), menu
);
661 dia_alignment_selector_get_type (void)
663 static GtkType dfs_type
= 0;
666 static const GtkTypeInfo dfs_info
= {
667 "DiaAlignmentSelector",
668 sizeof (DiaAlignmentSelector
),
669 sizeof (DiaAlignmentSelectorClass
),
670 (GtkClassInitFunc
) dia_alignment_selector_class_init
,
671 (GtkObjectInitFunc
) dia_alignment_selector_init
,
674 (GtkClassInitFunc
) NULL
,
677 dfs_type
= gtk_type_unique (gtk_option_menu_get_type (), &dfs_info
);
684 dia_alignment_selector_new ()
686 return GTK_WIDGET ( gtk_type_new (dia_alignment_selector_get_type ()));
691 dia_alignment_selector_get_alignment(DiaAlignmentSelector
*fs
)
696 menuitem
= gtk_menu_get_active(fs
->alignment_menu
);
697 align
= gtk_object_get_user_data(GTK_OBJECT(menuitem
));
699 return GPOINTER_TO_INT(align
);
703 dia_alignment_selector_set_alignment (DiaAlignmentSelector
*as
,
706 gtk_menu_set_active(GTK_MENU (as
->alignment_menu
), align
);
707 gtk_option_menu_set_history (GTK_OPTION_MENU(as
), align
);
710 /************* DiaLineStyleSelector: ***************/
711 struct _DiaLineStyleSelector
715 GtkOptionMenu
*omenu
;
716 GtkMenu
*linestyle_menu
;
717 GtkLabel
*lengthlabel
;
718 GtkSpinButton
*dashlength
;
722 struct _DiaLineStyleSelectorClass
724 GtkVBoxClass parent_class
;
728 dia_line_style_selector_class_init (DiaLineStyleSelectorClass
*class)
730 GtkObjectClass
*object_class
;
732 object_class
= (GtkObjectClass
*) class;
736 set_linestyle_sensitivity(DiaLineStyleSelector
*fs
)
740 if (!fs
->linestyle_menu
) return;
741 menuitem
= gtk_menu_get_active(fs
->linestyle_menu
);
742 state
= (GPOINTER_TO_INT(gtk_object_get_user_data(GTK_OBJECT(menuitem
)))
745 gtk_widget_set_sensitive(GTK_WIDGET(fs
->lengthlabel
), state
);
746 gtk_widget_set_sensitive(GTK_WIDGET(fs
->dashlength
), state
);
750 linestyle_type_change_callback(GtkObject
*as
, gboolean arg1
, gpointer data
)
752 set_linestyle_sensitivity(DIALINESTYLESELECTOR(as
));
756 dia_line_style_selector_init (DiaLineStyleSelector
*fs
)
760 GtkWidget
*menuitem
, *ln
;
768 menu
= gtk_option_menu_new();
769 fs
->omenu
= GTK_OPTION_MENU(menu
);
771 menu
= gtk_menu_new ();
772 fs
->linestyle_menu
= GTK_MENU(menu
);
776 for (i
= 0; i
<= LINESTYLE_DOTTED
; i
++) {
777 menuitem
= gtk_menu_item_new();
778 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(i
));
779 ln
= dia_line_preview_new(i
);
780 gtk_container_add(GTK_CONTAINER(menuitem
), ln
);
782 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
783 gtk_widget_show(menuitem
);
786 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Solid"));
787 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(LINESTYLE_SOLID
));
788 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
789 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
790 gtk_widget_show (menuitem
);
792 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Dashed"));
793 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(LINESTYLE_DASHED
));
794 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
795 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
796 gtk_widget_show (menuitem
);
798 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Dash-Dot"));
799 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(LINESTYLE_DASH_DOT
));
800 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
801 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
802 gtk_widget_show (menuitem
);
804 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Dash-Dot-Dot"));
805 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(LINESTYLE_DASH_DOT_DOT
));
806 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
807 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
808 gtk_widget_show (menuitem
);
810 menuitem
= gtk_radio_menu_item_new_with_label (group
, _("Dotted"));
811 gtk_object_set_user_data(GTK_OBJECT(menuitem
), GINT_TO_POINTER(LINESTYLE_DOTTED
));
812 group
= gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem
));
813 gtk_menu_shell_append (GTK_MENU_SHELL (menu
), menuitem
);
814 gtk_widget_show (menuitem
);
817 gtk_menu_set_active(GTK_MENU (menu
), DEFAULT_LINESTYLE
);
818 gtk_option_menu_set_menu (GTK_OPTION_MENU (fs
->omenu
), menu
);
819 gtk_signal_connect_object(GTK_OBJECT(menu
), "selection-done",
820 GTK_SIGNAL_FUNC(linestyle_type_change_callback
),
823 gtk_box_pack_start(GTK_BOX(fs
), GTK_WIDGET(fs
->omenu
), FALSE
, TRUE
, 0);
824 gtk_widget_show(GTK_WIDGET(fs
->omenu
));
826 box
= gtk_hbox_new(FALSE
,0);
827 /* fs->sizebox = GTK_HBOX(box); */
829 label
= gtk_label_new(_("Dash length: "));
830 fs
->lengthlabel
= GTK_LABEL(label
);
831 gtk_box_pack_start_defaults(GTK_BOX(box
), label
);
832 gtk_widget_show(label
);
834 adj
= (GtkAdjustment
*)gtk_adjustment_new(0.1, 0.00, 10.0, 0.1, 1.0, 1.0);
835 length
= gtk_spin_button_new(adj
, DEFAULT_LINESTYLE_DASHLEN
, 2);
836 gtk_spin_button_set_wrap(GTK_SPIN_BUTTON(length
), TRUE
);
837 gtk_spin_button_set_numeric(GTK_SPIN_BUTTON(length
), TRUE
);
838 fs
->dashlength
= GTK_SPIN_BUTTON(length
);
839 gtk_box_pack_start_defaults(GTK_BOX (box
), length
);
840 gtk_widget_show (length
);
842 set_linestyle_sensitivity(fs
);
843 gtk_box_pack_start_defaults(GTK_BOX(fs
), box
);
844 gtk_widget_show(box
);
849 dia_line_style_selector_get_type (void)
851 static GtkType dfs_type
= 0;
854 static const GtkTypeInfo dfs_info
= {
855 "DiaLineStyleSelector",
856 sizeof (DiaLineStyleSelector
),
857 sizeof (DiaLineStyleSelectorClass
),
858 (GtkClassInitFunc
) dia_line_style_selector_class_init
,
859 (GtkObjectInitFunc
) dia_line_style_selector_init
,
862 (GtkClassInitFunc
) NULL
,
865 dfs_type
= gtk_type_unique (gtk_vbox_get_type (), &dfs_info
);
872 dia_line_style_selector_new ()
874 return GTK_WIDGET ( gtk_type_new (dia_line_style_selector_get_type ()));
879 dia_line_style_selector_get_linestyle(DiaLineStyleSelector
*fs
,
880 LineStyle
*ls
, real
*dl
)
885 menuitem
= gtk_menu_get_active(fs
->linestyle_menu
);
886 align
= gtk_object_get_user_data(GTK_OBJECT(menuitem
));
887 *ls
= GPOINTER_TO_INT(align
);
889 *dl
= gtk_spin_button_get_value(fs
->dashlength
);
894 dia_line_style_selector_set_linestyle (DiaLineStyleSelector
*as
,
895 LineStyle linestyle
, real dashlength
)
897 gtk_menu_set_active(GTK_MENU (as
->linestyle_menu
), linestyle
);
898 gtk_option_menu_set_history (GTK_OPTION_MENU(as
->omenu
), linestyle
);
899 /* TODO restore this later */
900 /* gtk_check_menu_item_set_active (GTK_CHECK_MENU_ITEM(gtk_menu_get_active(GTK_MENU(as->linestyle_menu))), TRUE);*/
901 set_linestyle_sensitivity(DIALINESTYLESELECTOR(as
));
902 gtk_spin_button_set_value(GTK_SPIN_BUTTON(as
->dashlength
), dashlength
);
907 /************* DiaColorSelector: ***************/
910 dia_color_selector_create_string_item(DiaDynamicMenu
*ddm
, gchar
*string
)
912 GtkWidget
*item
= gtk_menu_item_new_with_label(string
);
914 sscanf(string
, "#%2x%2x%2x", &r
, &g
, &b
);
916 /* See http://web.umr.edu/~rhall/commentary/color_readability.htm for
917 * explanation of this formula */
918 if (r
*299+g
*587+b
*114 > 500 * 256) {
919 gchar
*label
= g_strdup_printf("<span foreground=\"black\" background=\"%s\">%s</span>", string
, string
);
920 gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(item
))), label
);
923 gchar
*label
= g_strdup_printf("<span foreground=\"white\" background=\"%s\">%s</span>", string
, string
);
924 gtk_label_set_markup(GTK_LABEL(gtk_bin_get_child(GTK_BIN(item
))), label
);
932 dia_color_selector_more_ok(GtkWidget
*ok
, gpointer userdata
)
934 DiaDynamicMenu
*ddm
= g_object_get_data(G_OBJECT(userdata
), "ddm");
935 GtkWidget
*colorsel
= GTK_WIDGET(userdata
);
939 gtk_color_selection_get_current_color(
941 GTK_COLOR_SELECTION_DIALOG(colorsel
)->colorsel
),
944 entry
= g_strdup_printf("#%02X%02X%02X", gcol
.red
/256, gcol
.green
/256, gcol
.blue
/256);
945 dia_dynamic_menu_select_entry(ddm
, entry
);
948 gtk_widget_destroy(colorsel
);
952 dia_color_selector_activate(DiaDynamicMenu
*ddm
, const gchar
*entry
, gpointer data
)
957 dia_color_selector_more_callback(GtkWidget
*widget
, gpointer userdata
)
959 GtkColorSelectionDialog
*dialog
= GTK_COLOR_SELECTION_DIALOG (gtk_color_selection_dialog_new(_("Select color")));
960 DiaDynamicMenu
*ddm
= DIA_DYNAMIC_MENU(userdata
);
961 GtkColorSelection
*colorsel
= GTK_COLOR_SELECTION(dialog
->colorsel
);
962 GString
*palette
= g_string_new ("");
964 gchar
*old_color
= dia_dynamic_menu_get_entry(ddm
);
965 /* Force history to the old place */
966 dia_dynamic_menu_select_entry(ddm
, old_color
);
968 if (ddm
->default_entries
!= NULL
) {
971 gboolean advance
= TRUE
;
973 for (tmplist
= ddm
->default_entries
;
974 tmplist
!= NULL
|| advance
;
975 tmplist
= g_list_next(tmplist
)) {
979 /* handle both lists */
980 if (!tmplist
&& advance
) {
982 tmplist
= persistent_list_get_glist(ddm
->persistent_name
);
986 spec
= (gchar
*)tmplist
->data
;
988 gdk_color_parse (spec
, &color
);
990 /* the easy way if the Gtk Team would decide to make it public */
991 gtk_color_selection_set_palette_color (colorsel
, index
, &color
);
993 g_string_append (palette
, spec
);
994 g_string_append (palette
, ":");
996 if (0 == strcmp (spec
, old_color
)) {
997 gtk_color_selection_set_previous_color (colorsel
, &color
);
998 gtk_color_selection_set_current_color (colorsel
, &color
);
1004 g_object_set (gtk_widget_get_settings (GTK_WIDGET (colorsel
)), "gtk-color-palette", palette
->str
, NULL
);
1005 gtk_color_selection_set_has_palette (colorsel
, TRUE
);
1006 g_string_free (palette
, TRUE
);
1009 gtk_widget_hide(dialog
->help_button
);
1011 gtk_signal_connect (GTK_OBJECT (dialog
->ok_button
), "clicked",
1012 (GtkSignalFunc
) dia_color_selector_more_ok
,
1014 gtk_signal_connect_object(GTK_OBJECT (dialog
->cancel_button
), "clicked",
1015 (GtkSignalFunc
) gtk_widget_destroy
,
1016 GTK_OBJECT(dialog
));
1017 g_object_set_data(G_OBJECT(dialog
), "ddm", ddm
);
1019 gtk_widget_show(GTK_WIDGET(dialog
));
1023 dia_color_selector_new ()
1025 GtkWidget
*otheritem
= gtk_menu_item_new_with_label(_("More colors..."));
1026 GtkWidget
*ddm
= dia_dynamic_menu_new(dia_color_selector_create_string_item
,
1027 dia_color_selector_activate
,
1029 GTK_MENU_ITEM(otheritem
),
1031 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm
),
1033 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm
),
1035 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm
),
1037 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm
),
1039 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(ddm
),
1041 g_signal_connect(G_OBJECT(otheritem
), "activate",
1042 G_CALLBACK(dia_color_selector_more_callback
), ddm
);
1043 gtk_widget_show(otheritem
);
1049 dia_color_selector_get_color(GtkWidget
*widget
, Color
*color
)
1051 gchar
*entry
= dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(widget
));
1054 sscanf(entry
, "#%2x%2x%2x", &r
, &g
, &b
);
1056 color
->red
= r
/ 255.0;
1057 color
->green
= g
/ 255.0;
1058 color
->blue
= b
/ 255.0;
1062 dia_color_selector_set_color (GtkWidget
*widget
,
1065 gint red
, green
, blue
;
1067 red
= color
->red
* 255;
1068 green
= color
->green
* 255;
1069 blue
= color
->blue
* 255;
1070 if (color
->red
> 1.0 || color
->green
> 1.0 || color
->blue
> 1.0) {
1071 printf("Color out of range: r %f, g %f, b %f\n",
1072 color
->red
, color
->green
, color
->blue
);
1073 red
= MIN(red
, 255);
1074 green
= MIN(green
, 255);
1075 blue
= MIN(blue
, 255);
1077 entry
= g_strdup_printf("#%02X%02X%02X", red
, green
, blue
);
1078 dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(widget
), entry
);
1083 /************* DiaArrowSelector: ***************/
1084 struct _DiaArrowSelector
1089 GtkLabel
*sizelabel
;
1090 DiaSizeSelector
*size
;
1092 GtkOptionMenu
*omenu
;
1095 struct _DiaArrowSelectorClass
1097 GtkVBoxClass parent_class
;
1101 dia_arrow_selector_class_init (DiaArrowSelectorClass
*class)
1106 set_size_sensitivity(DiaArrowSelector
*as
)
1109 gchar
*entryname
= dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(as
->omenu
));
1111 state
= (entryname
!= NULL
) && (0 != g_strcasecmp(entryname
, "None"));
1114 gtk_widget_set_sensitive(GTK_WIDGET(as
->sizelabel
), state
);
1115 gtk_widget_set_sensitive(GTK_WIDGET(as
->size
), state
);
1119 arrow_type_change_callback(DiaDynamicMenu
*ddm
, const gchar
*name
, gpointer userdata
)
1121 set_size_sensitivity(DIA_ARROW_SELECTOR(userdata
));
1125 create_arrow_menu_item(DiaDynamicMenu
*ddm
, gchar
*name
)
1127 ArrowType atype
= arrow_type_from_name(name
);
1128 GtkWidget
*item
= gtk_menu_item_new();
1129 GtkWidget
*preview
= dia_arrow_preview_new(atype
, FALSE
);
1131 gtk_widget_show(preview
);
1132 gtk_container_add(GTK_CONTAINER(item
), preview
);
1133 gtk_widget_show(item
);
1138 dia_arrow_selector_init (DiaArrowSelector
*as
,
1146 GList
*arrow_names
= get_arrow_names();
1147 omenu
= dia_dynamic_menu_new_listbased(create_arrow_menu_item
,
1148 arrow_type_change_callback
, as
,
1152 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(omenu
), "None");
1153 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(omenu
), "Lines");
1154 dia_dynamic_menu_add_default_entry(DIA_DYNAMIC_MENU(omenu
), "Filled Concave");
1155 as
->omenu
= GTK_OPTION_MENU(omenu
);
1156 gtk_box_pack_start(GTK_BOX(as
), omenu
, FALSE
, TRUE
, 0);
1157 gtk_widget_show(omenu
);
1159 box
= gtk_hbox_new(FALSE
,0);
1160 as
->sizebox
= GTK_HBOX(box
);
1162 label
= gtk_label_new(_("Size: "));
1163 as
->sizelabel
= GTK_LABEL(label
);
1164 gtk_box_pack_start_defaults(GTK_BOX(box
), label
);
1165 gtk_widget_show(label
);
1167 size
= dia_size_selector_new(0.0, 0.0);
1168 as
->size
= DIA_SIZE_SELECTOR(size
);
1169 gtk_box_pack_start_defaults(GTK_BOX(box
), size
);
1170 gtk_widget_show(size
);
1172 set_size_sensitivity(as
);
1173 gtk_box_pack_start_defaults(GTK_BOX(as
), box
);
1175 gtk_widget_show(box
);
1180 dia_arrow_selector_get_type (void)
1182 static GType dfs_type
= 0;
1185 static const GTypeInfo dfs_info
= {
1186 /* sizeof (DiaArrowSelector),*/
1187 sizeof (DiaArrowSelectorClass
),
1188 (GBaseInitFunc
) NULL
,
1189 (GBaseFinalizeFunc
) NULL
,
1190 (GClassInitFunc
) dia_arrow_selector_class_init
,
1191 NULL
, /* class_finalize */
1192 NULL
, /* class_data */
1193 sizeof (DiaArrowSelector
),
1194 0, /* n_preallocs */
1195 (GInstanceInitFunc
)dia_arrow_selector_init
, /* init */
1197 (GtkObjectInitFunc) dia_arrow_selector_init,
1200 (GtkClassInitFunc) NULL,
1204 dfs_type
= g_type_register_static (GTK_TYPE_VBOX
,
1213 dia_arrow_selector_new ()
1215 return GTK_WIDGET ( g_object_new (DIA_TYPE_ARROW_SELECTOR
, NULL
));
1220 dia_arrow_selector_get_arrow(DiaArrowSelector
*as
)
1223 gchar
*arrowname
= dia_dynamic_menu_get_entry(DIA_DYNAMIC_MENU(as
->omenu
));
1225 at
.type
= arrow_type_from_name(arrowname
);
1227 dia_size_selector_get_size(as
->size
, &at
.width
, &at
.length
);
1232 dia_arrow_selector_set_arrow (DiaArrowSelector
*as
,
1235 dia_dynamic_menu_select_entry(DIA_DYNAMIC_MENU(as
->omenu
),
1236 arrow_types
[arrow_index_from_type(arrow
.type
)].name
);
1237 set_size_sensitivity(as
);
1238 dia_size_selector_set_size(DIA_SIZE_SELECTOR(as
->size
), arrow
.width
, arrow
.length
);
1241 /************* DiaFileSelector: ***************/
1242 struct _DiaFileSelector
1247 GtkFileSelection
*dialog
;
1248 gchar
*sys_filename
;
1251 struct _DiaFileSelectorClass
1253 GtkHBoxClass parent_class
;
1257 dia_file_selector_unrealize(GtkWidget
*widget
)
1259 DiaFileSelector
*fs
= DIAFILESELECTOR(widget
);
1261 if (fs
->dialog
!= NULL
) {
1262 gtk_widget_destroy(GTK_WIDGET(fs
->dialog
));
1265 if (fs
->sys_filename
) {
1266 g_free(fs
->sys_filename
);
1267 fs
->sys_filename
= NULL
;
1270 (* GTK_WIDGET_CLASS (gtk_type_class(gtk_hbox_get_type ()))->unrealize
) (widget
);
1274 dia_file_selector_class_init (DiaFileSelectorClass
*class)
1276 GtkObjectClass
*object_class
;
1277 GtkWidgetClass
*widget_class
;
1279 object_class
= (GtkObjectClass
*) class;
1280 widget_class
= (GtkWidgetClass
*) class;
1281 widget_class
->unrealize
= dia_file_selector_unrealize
;
1285 dia_file_selector_ok(GtkWidget
*widget
, gpointer data
)
1288 GtkFileSelection
*dialog
= GTK_FILE_SELECTION(data
);
1289 DiaFileSelector
*fs
=
1290 DIAFILESELECTOR(gtk_object_get_user_data(GTK_OBJECT(dialog
)));
1291 utf8
= g_filename_to_utf8(gtk_file_selection_get_filename(dialog
),
1292 -1, NULL
, NULL
, NULL
);
1293 gtk_entry_set_text(GTK_ENTRY(fs
->entry
), utf8
);
1295 gtk_widget_hide(GTK_WIDGET(dialog
));
1299 dia_file_selector_browse_pressed(GtkWidget
*widget
, gpointer data
)
1301 GtkFileSelection
*dialog
;
1302 DiaFileSelector
*fs
= DIAFILESELECTOR(data
);
1305 if (fs
->dialog
== NULL
) {
1306 dialog
= fs
->dialog
=
1307 GTK_FILE_SELECTION(gtk_file_selection_new(_("Select image file")));
1309 if (dialog
->help_button
!= NULL
)
1310 gtk_widget_hide(dialog
->help_button
);
1312 gtk_signal_connect (GTK_OBJECT (dialog
->ok_button
), "clicked",
1313 (GtkSignalFunc
) dia_file_selector_ok
,
1316 gtk_signal_connect (GTK_OBJECT (fs
->dialog
), "destroy",
1317 GTK_SIGNAL_FUNC (gtk_widget_destroyed
),
1320 gtk_signal_connect_object(GTK_OBJECT (dialog
->cancel_button
), "clicked",
1321 (GtkSignalFunc
) gtk_widget_hide
,
1322 GTK_OBJECT(dialog
));
1324 gtk_object_set_user_data(GTK_OBJECT(dialog
), fs
);
1327 filename
= g_filename_from_utf8(gtk_entry_get_text(fs
->entry
), -1, NULL
, NULL
, NULL
);
1328 gtk_file_selection_set_filename(fs
->dialog
, filename
);
1331 gtk_widget_show(GTK_WIDGET(fs
->dialog
));
1335 dia_file_selector_init (DiaFileSelector
*fs
)
1337 /* Here's where we set up the real thing */
1339 fs
->sys_filename
= NULL
;
1340 fs
->entry
= GTK_ENTRY(gtk_entry_new());
1341 gtk_box_pack_start(GTK_BOX(fs
), GTK_WIDGET(fs
->entry
), FALSE
, TRUE
, 0);
1342 gtk_widget_show(GTK_WIDGET(fs
->entry
));
1343 fs
->browse
= GTK_BUTTON(gtk_button_new_with_label(_("Browse")));
1344 gtk_box_pack_start(GTK_BOX(fs
), GTK_WIDGET(fs
->browse
), FALSE
, TRUE
, 0);
1345 gtk_signal_connect (GTK_OBJECT (fs
->browse
), "clicked",
1346 (GtkSignalFunc
) dia_file_selector_browse_pressed
,
1348 gtk_widget_show(GTK_WIDGET(fs
->browse
));
1353 dia_file_selector_get_type (void)
1355 static GtkType dfs_type
= 0;
1358 static const GtkTypeInfo dfs_info
= {
1360 sizeof (DiaFileSelector
),
1361 sizeof (DiaFileSelectorClass
),
1362 (GtkClassInitFunc
) dia_file_selector_class_init
,
1363 (GtkObjectInitFunc
) dia_file_selector_init
,
1366 (GtkClassInitFunc
) NULL
,
1369 dfs_type
= gtk_type_unique (gtk_hbox_get_type (), &dfs_info
);
1377 dia_file_selector_new ()
1379 return GTK_WIDGET ( gtk_type_new (dia_file_selector_get_type ()));
1383 dia_file_selector_set_file(DiaFileSelector
*fs
, gchar
*file
)
1385 /* filename is in system encoding */
1386 gchar
*utf8
= g_filename_to_utf8(file
, -1, NULL
, NULL
, NULL
);
1387 gtk_entry_set_text(GTK_ENTRY(fs
->entry
), utf8
);
1392 dia_file_selector_get_file(DiaFileSelector
*fs
)
1394 /* let it behave like gtk_file_selector_get_file */
1395 g_free(fs
->sys_filename
);
1396 fs
->sys_filename
= g_filename_from_utf8(gtk_entry_get_text(GTK_ENTRY(fs
->entry
)),
1397 -1, NULL
, NULL
, NULL
);
1398 return fs
->sys_filename
;
1401 /************* DiaUnitSpinner: ***************/
1403 /** A Spinner that allows a 'favored' unit to display in. External access
1404 * to the value still happens in cm, but display is in the favored unit.
1405 * Internally, the value is kept in the favored unit to a) allow proper
1406 * limits, and b) avoid rounding problems while editing.
1409 typedef struct _DiaUnitDef DiaUnitDef
;
1410 struct _DiaUnitDef
{
1416 /* from gnome-libs/libgnome/gnome-paper.c */
1417 static const DiaUnitDef units
[] =
1419 /* XXX does anyone *really* measure paper size in feet? meters? */
1421 /* human name, abreviation, points per unit */
1422 { "Feet", "ft", 864 },
1423 { "Meter", "m", 2834.6457 },
1424 { "Decimeter", "dm", 283.46457 },
1425 { "Millimeter", "mm", 2.8346457 },
1426 { "Point", "pt", 1. },
1427 { "Centimeter", "cm", 28.346457 },
1428 { "Inch", "in", 72 },
1429 { "Pica", "pi", 12 },
1433 static GtkObjectClass
*parent_class
;
1434 static GtkObjectClass
*entry_class
;
1436 static void dia_unit_spinner_class_init(DiaUnitSpinnerClass
*class);
1437 static void dia_unit_spinner_init(DiaUnitSpinner
*self
);
1440 dia_unit_spinner_get_type(void)
1442 static GtkType us_type
= 0;
1445 static const GtkTypeInfo us_info
= {
1447 sizeof(DiaUnitSpinner
),
1448 sizeof(DiaUnitSpinnerClass
),
1449 (GtkClassInitFunc
) dia_unit_spinner_class_init
,
1450 (GtkObjectInitFunc
) dia_unit_spinner_init
,
1453 (GtkClassInitFunc
) NULL
,
1455 us_type
= gtk_type_unique(gtk_spin_button_get_type(), &us_info
);
1460 /** Updates the spinner display to show digits and units */
1462 dia_unit_spinner_value_changed(GtkAdjustment
*adjustment
,
1463 DiaUnitSpinner
*spinner
)
1466 GtkSpinButton
*sbutton
= GTK_SPIN_BUTTON(spinner
);
1468 g_snprintf(buf
, sizeof(buf
), "%0.*f%s", sbutton
->digits
, adjustment
->value
,
1469 units
[spinner
->unit_num
].unit
);
1470 gtk_entry_set_text(GTK_ENTRY(spinner
), buf
);
1473 static void dia_unit_spinner_set_value_direct(DiaUnitSpinner
*self
, gfloat val
);
1474 static gint
dia_unit_spinner_focus_out(GtkWidget
*widget
, GdkEventFocus
*ev
);
1475 static gint
dia_unit_spinner_button_press(GtkWidget
*widget
,GdkEventButton
*ev
);
1476 static gint
dia_unit_spinner_key_press(GtkWidget
*widget
, GdkEventKey
*event
);
1477 static void dia_unit_spinner_activate(GtkEntry
*editable
);
1480 dia_unit_spinner_class_init(DiaUnitSpinnerClass
*class)
1482 GtkObjectClass
*object_class
;
1483 GtkWidgetClass
*widget_class
;
1484 GtkEntryClass
*editable_class
;
1486 object_class
= (GtkObjectClass
*)class;
1487 widget_class
= (GtkWidgetClass
*)class;
1488 editable_class
= (GtkEntryClass
*)class;
1490 widget_class
->focus_out_event
= dia_unit_spinner_focus_out
;
1491 widget_class
->button_press_event
= dia_unit_spinner_button_press
;
1492 widget_class
->key_press_event
= dia_unit_spinner_key_press
;
1493 editable_class
->activate
= dia_unit_spinner_activate
;
1495 parent_class
= gtk_type_class(GTK_TYPE_SPIN_BUTTON
);
1496 entry_class
= gtk_type_class(GTK_TYPE_ENTRY
);
1500 dia_unit_spinner_init(DiaUnitSpinner
*self
)
1502 /* change over to our own print function that appends the unit name on the
1504 if (self
->parent
.adjustment
) {
1505 gtk_signal_disconnect_by_data(GTK_OBJECT(self
->parent
.adjustment
),
1507 g_signal_connect(GTK_OBJECT(self
->parent
.adjustment
), "value_changed",
1508 G_CALLBACK(dia_unit_spinner_value_changed
),
1512 self
->unit_num
= DIA_UNIT_CENTIMETER
;
1516 dia_unit_spinner_new(GtkAdjustment
*adjustment
, guint digits
, DiaUnit adj_unit
)
1518 DiaUnitSpinner
*self
= gtk_type_new(dia_unit_spinner_get_type());
1520 self
->unit_num
= adj_unit
;
1522 gtk_spin_button_configure(GTK_SPIN_BUTTON(self
), adjustment
, 0.0, digits
);
1525 gtk_signal_disconnect_by_data(GTK_OBJECT(adjustment
),
1527 g_signal_connect(GTK_OBJECT(adjustment
), "value_changed",
1528 G_CALLBACK(dia_unit_spinner_value_changed
),
1530 dia_unit_spinner_set_value(self
, adjustment
->value
);
1532 /* Don't know any better, hopefully it'll be set later. */
1533 dia_unit_spinner_set_value(self
, 1.0);
1536 return GTK_WIDGET(self
);
1539 /** Set the value (in cm).
1542 dia_unit_spinner_set_value(DiaUnitSpinner
*self
, gfloat val
)
1544 dia_unit_spinner_set_value_direct(self
, val
/
1545 (units
[self
->unit_num
].factor
/ units
[DIA_UNIT_CENTIMETER
].factor
));
1548 /** Set the value (in preferred units) */
1550 dia_unit_spinner_set_value_direct(DiaUnitSpinner
*self
, gfloat val
)
1552 GtkSpinButton
*sbutton
= GTK_SPIN_BUTTON(self
);
1554 if (val
< sbutton
->adjustment
->lower
)
1555 val
= sbutton
->adjustment
->lower
;
1556 else if (val
> sbutton
->adjustment
->upper
)
1557 val
= sbutton
->adjustment
->upper
;
1558 sbutton
->adjustment
->value
= val
;
1559 dia_unit_spinner_value_changed(sbutton
->adjustment
, self
);
1562 /** Get the value (in cm) */
1564 dia_unit_spinner_get_value(DiaUnitSpinner
*self
)
1566 GtkSpinButton
*sbutton
= GTK_SPIN_BUTTON(self
);
1568 return sbutton
->adjustment
->value
*
1569 (units
[self
->unit_num
].factor
/ units
[DIA_UNIT_CENTIMETER
].factor
);
1573 dia_unit_spinner_update(DiaUnitSpinner
*self
)
1575 gfloat val
, factor
= 1.0;
1576 gchar
*extra
= NULL
;
1578 val
= g_strtod(gtk_entry_get_text(GTK_ENTRY(self
)), &extra
);
1580 /* get rid of extra white space after number */
1581 while (*extra
&& g_ascii_isspace(*extra
)) extra
++;
1585 for (i
= 0; units
[i
].name
!= NULL
; i
++)
1586 if (!g_strcasecmp(units
[i
].unit
, extra
)) {
1587 factor
= units
[i
].factor
/ units
[self
->unit_num
].factor
;
1591 /* convert to prefered units */
1593 dia_unit_spinner_set_value_direct(self
, val
);
1597 dia_unit_spinner_focus_out(GtkWidget
*widget
, GdkEventFocus
*event
)
1599 if (GTK_ENTRY (widget
)->editable
)
1600 dia_unit_spinner_update(DIA_UNIT_SPINNER(widget
));
1601 return GTK_WIDGET_CLASS(entry_class
)->focus_out_event(widget
, event
);
1605 dia_unit_spinner_button_press(GtkWidget
*widget
, GdkEventButton
*event
)
1607 dia_unit_spinner_update(DIA_UNIT_SPINNER(widget
));
1608 return GTK_WIDGET_CLASS(parent_class
)->button_press_event(widget
, event
);
1612 dia_unit_spinner_key_press(GtkWidget
*widget
, GdkEventKey
*event
)
1614 gint key
= event
->keyval
;
1616 if (GTK_ENTRY (widget
)->editable
&&
1617 (key
== GDK_Up
|| key
== GDK_Down
||
1618 key
== GDK_Page_Up
|| key
== GDK_Page_Down
))
1619 dia_unit_spinner_update (DIA_UNIT_SPINNER(widget
));
1620 return GTK_WIDGET_CLASS(parent_class
)->key_press_event(widget
, event
);
1624 dia_unit_spinner_activate(GtkEntry
*editable
)
1626 if (editable
->editable
)
1627 dia_unit_spinner_update(DIA_UNIT_SPINNER(editable
));
1631 /* ************************ Dynamic menus ************************ */
1633 static void dia_dynamic_menu_class_init(DiaDynamicMenuClass
*class);
1634 static void dia_dynamic_menu_init(DiaDynamicMenu
*self
);
1635 static void dia_dynamic_menu_create_sublist(DiaDynamicMenu
*ddm
,
1637 DDMCreateItemFunc create
);
1638 static void dia_dynamic_menu_create_menu(DiaDynamicMenu
*ddm
);
1639 static void dia_dynamic_menu_destroy(GtkObject
*object
);
1642 dia_dynamic_menu_get_type(void)
1644 static GtkType us_type
= 0;
1647 static const GtkTypeInfo us_info
= {
1649 sizeof(DiaDynamicMenu
),
1650 sizeof(DiaDynamicMenuClass
),
1651 (GtkClassInitFunc
) dia_dynamic_menu_class_init
,
1652 (GtkObjectInitFunc
) dia_dynamic_menu_init
,
1655 (GtkClassInitFunc
) NULL
,
1657 us_type
= gtk_type_unique(gtk_option_menu_get_type(), &us_info
);
1663 dia_dynamic_menu_class_init(DiaDynamicMenuClass
*class)
1665 GtkObjectClass
*object_class
= (GtkObjectClass
*)class;
1667 object_class
->destroy
= dia_dynamic_menu_destroy
;
1671 dia_dynamic_menu_init(DiaDynamicMenu
*self
)
1676 dia_dynamic_menu_destroy(GtkObject
*object
)
1678 DiaDynamicMenu
*ddm
= DIA_DYNAMIC_MENU(object
);
1679 GtkObjectClass
*parent_class
= GTK_OBJECT_CLASS(g_type_class_peek_parent(GTK_OBJECT_GET_CLASS(object
)));
1682 g_free(ddm
->active
);
1685 if (parent_class
->destroy
)
1686 (* parent_class
->destroy
) (object
);
1689 /** Create a new dynamic menu. The entries are represented with
1691 * @param create A function that creates menuitems from gpointers.
1692 * @param otheritem A menuitem that can be selected by the user to
1693 * add more entries, for instance making a dialog box or a submenu.
1694 * @param persist A string naming this menu for persistence purposes, or NULL.
1696 * @return A new menu
1699 dia_dynamic_menu_new(DDMCreateItemFunc create
,
1700 DDMCallbackFunc activate
, gpointer userdata
,
1701 GtkMenuItem
*otheritem
, gchar
*persist
)
1703 DiaDynamicMenu
*ddm
;
1705 g_assert(persist
!= NULL
);
1707 ddm
= DIA_DYNAMIC_MENU ( gtk_type_new (dia_dynamic_menu_get_type ()));
1709 ddm
->create_func
= create
;
1710 ddm
->activate_func
= activate
;
1711 ddm
->userdata
= userdata
;
1712 ddm
->other_item
= otheritem
;
1713 ddm
->persistent_name
= persist
;
1716 persistence_register_list(persist
);
1718 dia_dynamic_menu_create_menu(ddm
);
1720 return GTK_WIDGET(ddm
);
1723 /** Select the given entry, adding it if necessary */
1725 dia_dynamic_menu_select_entry(DiaDynamicMenu
*ddm
, const gchar
*name
)
1727 gint add_result
= dia_dynamic_menu_add_entry(ddm
, name
);
1728 if (add_result
== 0) {
1731 for (tmp
= ddm
->default_entries
; tmp
!= NULL
;
1732 tmp
= g_list_next(tmp
), i
++) {
1733 if (!g_strcasecmp(tmp
->data
, name
))
1734 gtk_option_menu_set_history(GTK_OPTION_MENU(ddm
), i
);
1736 /* Not there after all? */
1738 if (ddm
->default_entries
!= NULL
)
1739 gtk_option_menu_set_history(GTK_OPTION_MENU(ddm
),
1740 g_list_length(ddm
->default_entries
)+1);
1742 gtk_option_menu_set_history(GTK_OPTION_MENU(ddm
), 0);
1744 if (ddm
->activate_func
!= NULL
) {
1745 (ddm
->activate_func
)(ddm
, name
, ddm
->userdata
);
1750 dia_dynamic_menu_activate(GtkWidget
*item
, gpointer userdata
)
1752 DiaDynamicMenu
*ddm
= DIA_DYNAMIC_MENU(userdata
);
1753 gchar
*name
= g_object_get_data(G_OBJECT(item
), "ddm_name");
1754 dia_dynamic_menu_select_entry(ddm
, name
);
1758 dia_dynamic_menu_create_string_item(DiaDynamicMenu
*ddm
, gchar
*string
)
1760 GtkWidget
*item
= gtk_menu_item_new_with_label(string
);
1764 /** Utility function for dynamic menus that are entirely based on the
1765 * labels in the menu.
1768 dia_dynamic_menu_new_stringbased(GtkMenuItem
*otheritem
,
1769 DDMCallbackFunc activate
,
1773 GtkWidget
*ddm
= dia_dynamic_menu_new(dia_dynamic_menu_create_string_item
,
1775 otheritem
, persist
);
1779 /** Utility function for dynamic menus that are based on a submenu with
1780 * many entries. This is useful for allowing the user to get a smaller
1781 * subset menu out of a set too large to be easily handled by a menu.
1784 dia_dynamic_menu_new_listbased(DDMCreateItemFunc create
,
1785 DDMCallbackFunc activate
,
1787 gchar
*other_label
, GList
*items
,
1790 GtkWidget
*item
= gtk_menu_item_new_with_label(other_label
);
1791 GtkWidget
*ddm
= dia_dynamic_menu_new(create
, activate
, userdata
,
1792 GTK_MENU_ITEM(item
), persist
);
1793 dia_dynamic_menu_create_sublist(DIA_DYNAMIC_MENU(ddm
), items
, create
);
1795 gtk_widget_show(item
);
1799 /** Utility function for dynamic menus that allow selection from a large
1800 * number of strings.
1803 dia_dynamic_menu_new_stringlistbased(gchar
*other_label
,
1805 DDMCallbackFunc activate
,
1809 return dia_dynamic_menu_new_listbased(dia_dynamic_menu_create_string_item
,
1811 other_label
, items
, persist
);
1815 dia_dynamic_menu_create_sublist(DiaDynamicMenu
*ddm
,
1816 GList
*items
, DDMCreateItemFunc create
)
1818 GtkWidget
*item
= GTK_WIDGET(ddm
->other_item
);
1820 GtkWidget
*submenu
= gtk_menu_new();
1822 for (; items
!= NULL
; items
= g_list_next(items
)) {
1823 GtkWidget
*submenuitem
= (create
)(ddm
, items
->data
);
1824 /* Set callback function to cause addition of item */
1825 gtk_menu_shell_append(GTK_MENU_SHELL(submenu
), submenuitem
);
1826 g_object_set_data(G_OBJECT(submenuitem
), "ddm_name", items
->data
);
1827 g_signal_connect(submenuitem
, "activate",
1828 G_CALLBACK(dia_dynamic_menu_activate
), ddm
);
1829 gtk_widget_show(submenuitem
);
1832 gtk_menu_item_set_submenu(GTK_MENU_ITEM(item
), submenu
);
1833 gtk_widget_show(submenu
);
1836 /** Add a new default entry to this menu.
1837 * The default entries are always shown, also after resets, above the
1838 * other entries. Possible uses are standard fonts or common colors.
1839 * The entry is added at the end of the default entries section.
1840 * Do not add too many default entries.
1842 * @param ddm A dynamic menu to add the entry to.
1843 * @param entry An entry for the menu.
1846 dia_dynamic_menu_add_default_entry(DiaDynamicMenu
*ddm
, const gchar
*entry
)
1848 ddm
->default_entries
= g_list_append(ddm
->default_entries
, g_strdup(entry
));
1850 dia_dynamic_menu_create_menu(ddm
);
1853 /** Set the number of columns this menu uses (default 1)
1854 * @param cols Desired # of columns (>= 1)
1857 dia_dynamic_menu_set_columns(DiaDynamicMenu
*ddm
, gint cols
)
1861 dia_dynamic_menu_create_menu(ddm
);
1864 /** Add a new entry to this menu. The placement depends on what sorting
1865 * system has been chosen with dia_dynamic_menu_set_sorting_method().
1867 * @param ddm A dynamic menu to add the entry to.
1868 * @param entry An entry for the menu.
1870 * @returns 0 if the entry was one of the default entries.
1871 * 1 if the entry was already there.
1872 * 2 if the entry got added.
1875 dia_dynamic_menu_add_entry(DiaDynamicMenu
*ddm
, const gchar
*entry
)
1880 g_free(ddm
->active
);
1881 ddm
->active
= g_strdup(entry
);
1883 for (tmp
= ddm
->default_entries
; tmp
!= NULL
; tmp
= g_list_next(tmp
)) {
1884 if (!g_strcasecmp(tmp
->data
, entry
))
1887 existed
= persistent_list_add(ddm
->persistent_name
, entry
);
1889 dia_dynamic_menu_create_menu(ddm
);
1894 /** Returns the currently selected entry.
1895 * @returns The name of the entry that is currently selected. This
1896 * string should be freed by the caller. */
1898 dia_dynamic_menu_get_entry(DiaDynamicMenu
*ddm
)
1900 return g_strdup(ddm
->active
);
1903 /** Rebuild the actual menu of a DDM.
1904 * Ignores columns for now.
1907 dia_dynamic_menu_create_menu(DiaDynamicMenu
*ddm
)
1914 g_object_ref(G_OBJECT(ddm
->other_item
));
1915 menu
= gtk_option_menu_get_menu(GTK_OPTION_MENU(ddm
));
1917 gtk_container_remove(GTK_CONTAINER(menu
), GTK_WIDGET(ddm
->other_item
));
1918 gtk_container_foreach(GTK_CONTAINER(menu
),
1919 (GtkCallback
)gtk_widget_destroy
, NULL
);
1920 gtk_option_menu_remove_menu(GTK_OPTION_MENU(ddm
));
1923 menu
= gtk_menu_new();
1925 if (ddm
->default_entries
!= NULL
) {
1926 for (tmplist
= ddm
->default_entries
; tmplist
!= NULL
; tmplist
= g_list_next(tmplist
)) {
1927 GtkWidget
*item
= (ddm
->create_func
)(ddm
, tmplist
->data
);
1928 g_object_set_data(G_OBJECT(item
), "ddm_name", tmplist
->data
);
1929 g_signal_connect(G_OBJECT(item
), "activate",
1930 G_CALLBACK(dia_dynamic_menu_activate
), ddm
);
1931 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1932 gtk_widget_show(item
);
1934 sep
= gtk_separator_menu_item_new();
1935 gtk_widget_show(sep
);
1936 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), sep
);
1939 for (tmplist
= persistent_list_get_glist(ddm
->persistent_name
);
1940 tmplist
!= NULL
; tmplist
= g_list_next(tmplist
)) {
1941 GtkWidget
*item
= (ddm
->create_func
)(ddm
, tmplist
->data
);
1942 g_object_set_data(G_OBJECT(item
), "ddm_name", tmplist
->data
);
1943 g_signal_connect(G_OBJECT(item
), "activate",
1944 G_CALLBACK(dia_dynamic_menu_activate
), ddm
);
1945 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1946 gtk_widget_show(item
);
1948 sep
= gtk_separator_menu_item_new();
1949 gtk_widget_show(sep
);
1950 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), sep
);
1952 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), GTK_WIDGET(ddm
->other_item
));
1953 g_object_unref(G_OBJECT(ddm
->other_item
));
1954 /* Eventually reset item here */
1955 gtk_widget_show(menu
);
1957 item
= gtk_menu_item_new_with_label(_("Reset menu"));
1958 gtk_menu_shell_append(GTK_MENU_SHELL(menu
), item
);
1959 g_signal_connect(G_OBJECT(item
), "activate", G_CALLBACK(dia_dynamic_menu_reset
), ddm
);
1960 gtk_widget_show(item
);
1962 gtk_option_menu_set_menu(GTK_OPTION_MENU(ddm
), menu
);
1964 gtk_option_menu_set_history(GTK_OPTION_MENU(ddm
), 0);
1967 /** Select the method used for sorting the non-default entries.
1968 * @param ddm A dynamic menu
1969 * @param sort The way the non-default entries in the menu should be sorted.
1972 dia_dynamic_menu_set_sorting_method(DiaDynamicMenu
*ddm
, DdmSortType sort
)
1976 /** Reset the non-default entries of a menu
1979 dia_dynamic_menu_reset(GtkWidget
*item
, gpointer userdata
)
1981 DiaDynamicMenu
*ddm
= DIA_DYNAMIC_MENU(userdata
);
1982 PersistentList
*plist
= persistent_list_get(ddm
->persistent_name
);
1983 g_list_foreach(plist
->glist
, (GFunc
)g_free
, NULL
);
1984 g_list_free(plist
->glist
);
1985 plist
->glist
= NULL
;
1986 dia_dynamic_menu_create_menu(ddm
);
1987 dia_dynamic_menu_select_entry(ddm
, ddm
->active
);
1990 /** Set the maximum number of non-default entries.
1991 * If more than this number of entries are added, the least recently
1992 * selected ones are removed. */
1994 dia_dynamic_menu_set_max_entries(DiaDynamicMenu
*ddm
, gint max
)
1999 /* ************************ Misc. util functions ************************ */
2000 struct image_pair
{ GtkWidget
*on
; GtkWidget
*off
; };
2003 dia_toggle_button_swap_images(GtkToggleButton
*widget
,
2006 struct image_pair
*images
= (struct image_pair
*)data
;
2007 if (gtk_toggle_button_get_active(widget
)) {
2008 gtk_container_remove(GTK_CONTAINER(widget
),
2009 gtk_bin_get_child(GTK_BIN(widget
)));
2010 gtk_container_add(GTK_CONTAINER(widget
),
2014 gtk_container_remove(GTK_CONTAINER(widget
),
2015 gtk_bin_get_child(GTK_BIN(widget
)));
2016 gtk_container_add(GTK_CONTAINER(widget
),
2022 dia_toggle_button_destroy(GtkWidget
*widget
, gpointer data
)
2024 struct image_pair
*images
= (struct image_pair
*)data
;
2027 g_object_unref(images
->on
);
2030 g_object_unref(images
->off
);
2037 /** Create a toggle button given two image widgets for on and off */
2039 dia_toggle_button_new(GtkWidget
*on_widget
, GtkWidget
*off_widget
)
2041 GtkWidget
*button
= gtk_toggle_button_new();
2042 GtkRcStyle
*rcstyle
;
2045 struct image_pair
*images
;
2047 images
= g_new(struct image_pair
, 1);
2048 /* Since these may not be added at any point, make sure to
2050 images
->on
= on_widget
;
2051 g_object_ref(G_OBJECT(images
->on
));
2052 gtk_object_sink(GTK_OBJECT(images
->on
));
2053 gtk_widget_show(images
->on
);
2055 images
->off
= off_widget
;
2056 g_object_ref(G_OBJECT(images
->off
));
2057 gtk_object_sink(GTK_OBJECT(images
->off
));
2058 gtk_widget_show(images
->off
);
2060 /* Make border as small as possible */
2061 gtk_misc_set_padding(GTK_MISC(images
->on
), 0, 0);
2062 gtk_misc_set_padding(GTK_MISC(images
->off
), 0, 0);
2063 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(button
), GTK_CAN_FOCUS
);
2064 GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(button
), GTK_CAN_DEFAULT
);
2066 rcstyle
= gtk_rc_style_new ();
2067 rcstyle
->xthickness
= rcstyle
->ythickness
= 0;
2068 gtk_widget_modify_style (button
, rcstyle
);
2069 gtk_rc_style_unref (rcstyle
);
2071 prop
= g_new0(GValue
, 1);
2072 g_value_init(prop
, G_TYPE_INT
);
2073 gtk_widget_style_get_property(GTK_WIDGET(button
), "focus-padding", prop
);
2074 i
= g_value_get_int(prop
);
2075 g_value_set_int(prop
, 0);
2077 gtk_button_set_relief(GTK_BUTTON(button
), GTK_RELIEF_NONE
);
2078 /* gtk_button_set_focus_on_click(GTK_BUTTON(button), FALSE);*/
2079 gtk_container_set_border_width(GTK_CONTAINER(button
), 0);
2081 gtk_container_add(GTK_CONTAINER(button
), images
->off
);
2083 g_signal_connect(G_OBJECT(button
), "toggled",
2084 G_CALLBACK(dia_toggle_button_swap_images
), images
);
2085 g_signal_connect(G_OBJECT(button
), "destroy",
2086 G_CALLBACK(dia_toggle_button_destroy
), images
);
2091 /** Create a toggle button with two icons (created with gdk-pixbuf-csource,
2092 * for instance). The icons represent on and off.
2095 dia_toggle_button_new_with_icons(const guint8
*on_icon
,
2096 const guint8
*off_icon
)
2100 p1
= gdk_pixbuf_new_from_inline(-1, on_icon
, FALSE
, NULL
);
2101 p2
= gdk_pixbuf_new_from_inline(-1, off_icon
, FALSE
, NULL
);
2103 return dia_toggle_button_new(gtk_image_new_from_pixbuf(p1
),
2104 gtk_image_new_from_pixbuf(p2
));