2 * GTK - The GIMP Toolkit
3 * Copyright (C) 1998 David Abilleira Freijeiro <odaf@nexo.es>
6 * Based on gnome-color-picker by Federico Mena <federico@nuclecu.unam.mx>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place - Suite 330, Cambridge, MA 02139, USA.
23 * Modified by the GTK+ Team and others 2003. See the AUTHORS
24 * file for a list of people on the GTK+ Team. See the ChangeLog
25 * files for a list of changes. These files are distributed with
26 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
31 #include "gtkfontbutton.h"
33 #include "gtksignal.h"
35 #include "gtkalignment.h"
38 #include "gtkvseparator.h"
39 #include "gtkfontsel.h"
41 #include "gtkmarshalers.h"
42 #include "gtkprivate.h"
49 #define GTK_FONT_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_FONT_BUTTON, GtkFontButtonPrivate))
51 struct _GtkFontButtonPrivate
62 GtkWidget *font_dialog;
64 GtkWidget *font_label;
65 GtkWidget *size_label;
87 static void gtk_font_button_init (GtkFontButton *font_button);
88 static void gtk_font_button_class_init (GtkFontButtonClass *klass);
89 static void gtk_font_button_finalize (GObject *object);
90 static void gtk_font_button_get_property (GObject *object,
94 static void gtk_font_button_set_property (GObject *object,
99 static void gtk_font_button_clicked (GtkButton *button);
101 /* Dialog response functions */
102 static void dialog_ok_clicked (GtkWidget *widget,
104 static void dialog_cancel_clicked (GtkWidget *widget,
106 static void dialog_destroy (GtkWidget *widget,
109 /* Auxiliary functions */
110 static GtkWidget *gtk_font_button_create_inside (GtkFontButton *gfs);
111 static void gtk_font_button_label_use_font (GtkFontButton *gfs);
112 static void gtk_font_button_update_font_info (GtkFontButton *gfs);
114 static gpointer parent_class = NULL;
115 static guint font_button_signals[LAST_SIGNAL] = { 0 };
118 gtk_font_button_get_type (void)
120 static GType font_button_type = 0;
122 if (!font_button_type)
124 static const GTypeInfo font_button_info =
126 sizeof (GtkFontButtonClass),
127 NULL, /* base_init */
128 NULL, /* base_finalize */
129 (GClassInitFunc) gtk_font_button_class_init,
130 NULL, /* class_finalize */
131 NULL, /* class_data */
132 sizeof (GtkFontButton),
134 (GInstanceInitFunc) gtk_font_button_init,
138 g_type_register_static (GTK_TYPE_BUTTON, I_("GtkFontButton"),
139 &font_button_info, 0);
142 return font_button_type;
147 gtk_font_button_class_init (GtkFontButtonClass *klass)
149 GObjectClass *gobject_class;
150 GtkButtonClass *button_class;
152 gobject_class = (GObjectClass *) klass;
153 button_class = (GtkButtonClass *) klass;
155 parent_class = g_type_class_peek_parent (klass);
157 gobject_class->finalize = gtk_font_button_finalize;
158 gobject_class->set_property = gtk_font_button_set_property;
159 gobject_class->get_property = gtk_font_button_get_property;
161 button_class->clicked = gtk_font_button_clicked;
163 klass->font_set = NULL;
166 * GtkFontButton:title:
168 * The title of the font selection dialog.
172 g_object_class_install_property (gobject_class,
174 g_param_spec_string ("title",
176 P_("The title of the font selection dialog"),
178 (GTK_PARAM_READABLE |
179 GTK_PARAM_WRITABLE)));
182 * GtkFontButton:font-name:
184 * The name of the currently selected font.
188 g_object_class_install_property (gobject_class,
190 g_param_spec_string ("font-name",
192 P_("The name of the selected font"),
194 (GTK_PARAM_READABLE |
195 GTK_PARAM_WRITABLE)));
198 * GtkFontButton:use-font:
200 * If this property is set to %TRUE, the label will be drawn in the selected font.
204 g_object_class_install_property (gobject_class,
206 g_param_spec_boolean ("use-font",
207 P_("Use font in label"),
208 P_("Whether the label is drawn in the selected font"),
210 GTK_PARAM_READWRITE));
213 * GtkFontButton:use-size:
215 * If this property is set to %TRUE, the label will be drawn with the selected font size.
219 g_object_class_install_property (gobject_class,
221 g_param_spec_boolean ("use-size",
222 P_("Use size in label"),
223 P_("Whether the label is drawn with the selected font size"),
225 GTK_PARAM_READWRITE));
228 * GtkFontButton:show-style:
230 * If this property is set to %TRUE, the name of the selected font style will be shown in the label. For
231 * a more WYSIWIG way to show the selected style, see the ::use-font property.
235 g_object_class_install_property (gobject_class,
237 g_param_spec_boolean ("show-style",
239 P_("Whether the selected font style is shown in the label"),
241 GTK_PARAM_READWRITE));
243 * GtkFontButton:show-size:
245 * If this property is set to %TRUE, the selected font size will be shown in the label. For
246 * a more WYSIWIG way to show the selected size, see the ::use-size property.
250 g_object_class_install_property (gobject_class,
252 g_param_spec_boolean ("show-size",
254 P_("Whether selected font size is shown in the label"),
256 GTK_PARAM_READWRITE));
259 * GtkFontButton::font-set:
260 * @widget: the object which received the signal.
262 * The ::font-set signal is emitted when the user selects a font. When handling this signal,
263 * use gtk_font_button_get_font_name() to find out which font was just selected.
267 font_button_signals[FONT_SET] = g_signal_new (I_("font-set"),
268 G_TYPE_FROM_CLASS (gobject_class),
270 G_STRUCT_OFFSET (GtkFontButtonClass, font_set),
272 g_cclosure_marshal_VOID__VOID,
275 g_type_class_add_private (gobject_class, sizeof (GtkFontButtonPrivate));
279 gtk_font_button_init (GtkFontButton *font_button)
281 font_button->priv = GTK_FONT_BUTTON_GET_PRIVATE (font_button);
283 /* Initialize fields */
284 font_button->priv->fontname = g_strdup (_("Sans 12"));
285 font_button->priv->use_font = FALSE;
286 font_button->priv->use_size = FALSE;
287 font_button->priv->show_style = TRUE;
288 font_button->priv->show_size = TRUE;
289 font_button->priv->font_dialog = NULL;
290 font_button->priv->title = g_strdup (_("Pick a Font"));
292 font_button->priv->inside = gtk_font_button_create_inside (font_button);
293 gtk_container_add (GTK_CONTAINER (font_button), font_button->priv->inside);
295 gtk_font_button_update_font_info (font_button);
300 gtk_font_button_finalize (GObject *object)
302 GtkFontButton *font_button = GTK_FONT_BUTTON (object);
304 if (font_button->priv->font_dialog != NULL)
305 gtk_widget_destroy (font_button->priv->font_dialog);
306 font_button->priv->font_dialog = NULL;
308 g_free (font_button->priv->fontname);
309 font_button->priv->fontname = NULL;
311 g_free (font_button->priv->title);
312 font_button->priv->title = NULL;
314 G_OBJECT_CLASS (parent_class)->finalize (object);
318 gtk_font_button_set_property (GObject *object,
323 GtkFontButton *font_button = GTK_FONT_BUTTON (object);
328 gtk_font_button_set_title (font_button, g_value_get_string (value));
331 gtk_font_button_set_font_name (font_button, g_value_get_string (value));
334 gtk_font_button_set_use_font (font_button, g_value_get_boolean (value));
337 gtk_font_button_set_use_size (font_button, g_value_get_boolean (value));
339 case PROP_SHOW_STYLE:
340 gtk_font_button_set_show_style (font_button, g_value_get_boolean (value));
343 gtk_font_button_set_show_size (font_button, g_value_get_boolean (value));
346 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
352 gtk_font_button_get_property (GObject *object,
357 GtkFontButton *font_button = GTK_FONT_BUTTON (object);
362 g_value_set_string (value, gtk_font_button_get_title (font_button));
365 g_value_set_string (value, gtk_font_button_get_font_name (font_button));
368 g_value_set_boolean (value, gtk_font_button_get_use_font (font_button));
371 g_value_set_boolean (value, gtk_font_button_get_use_size (font_button));
373 case PROP_SHOW_STYLE:
374 g_value_set_boolean (value, gtk_font_button_get_show_style (font_button));
377 g_value_set_boolean (value, gtk_font_button_get_show_size (font_button));
380 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
387 * gtk_font_button_new:
389 * Creates a new font picker widget.
391 * Returns: a new font picker widget.
396 gtk_font_button_new (void)
398 return g_object_new (GTK_TYPE_FONT_BUTTON, NULL);
402 * gtk_font_button_new_with_font:
403 * @fontname: Name of font to display in font selection dialog
405 * Creates a new font picker widget.
407 * Returns: a new font picker widget.
412 gtk_font_button_new_with_font (const gchar *fontname)
414 return g_object_new (GTK_TYPE_FONT_BUTTON, "font_name", fontname, NULL);
418 * gtk_font_button_set_title:
419 * @font_button: a #GtkFontButton
420 * @title: a string containing the font selection dialog title
422 * Sets the title for the font selection dialog.
427 gtk_font_button_set_title (GtkFontButton *font_button,
431 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
433 old_title = font_button->priv->title;
434 font_button->priv->title = g_strdup (title);
437 if (font_button->priv->font_dialog)
438 gtk_window_set_title (GTK_WINDOW (font_button->priv->font_dialog),
439 font_button->priv->title);
441 g_object_notify (G_OBJECT (font_button), "title");
445 * gtk_font_button_get_title:
446 * @font_button: a #GtkFontButton
448 * Retrieves the title of the font selection dialog.
450 * Returns: an internal copy of the title string which must not be freed.
454 G_CONST_RETURN gchar*
455 gtk_font_button_get_title (GtkFontButton *font_button)
457 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
459 return font_button->priv->title;
463 * gtk_font_button_get_use_font:
464 * @font_button: a #GtkFontButton
466 * Returns whether the selected font is used in the label.
468 * Returns: whether the selected font is used in the label.
473 gtk_font_button_get_use_font (GtkFontButton *font_button)
475 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
477 return font_button->priv->use_font;
481 * gtk_font_button_set_use_font:
482 * @font_button: a #GtkFontButton
483 * @use_font: If %TRUE, font name will be written using font chosen.
485 * If @use_font is %TRUE, the font name will be written using the selected font.
490 gtk_font_button_set_use_font (GtkFontButton *font_button,
493 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
495 use_font = (use_font != FALSE);
497 if (font_button->priv->use_font != use_font)
499 font_button->priv->use_font = use_font;
502 gtk_font_button_label_use_font (font_button);
504 gtk_widget_set_style (font_button->priv->font_label, NULL);
506 g_object_notify (G_OBJECT (font_button), "use-font");
512 * gtk_font_button_get_use_size:
513 * @font_button: a #GtkFontButton
515 * Returns whether the selected size is used in the label.
517 * Returns: whether the selected size is used in the label.
522 gtk_font_button_get_use_size (GtkFontButton *font_button)
524 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
526 return font_button->priv->use_size;
530 * gtk_font_button_set_use_size:
531 * @font_button: a #GtkFontButton
532 * @use_size: If %TRUE, font name will be written using the selected size.
534 * If @use_size is %TRUE, the font name will be written using the selected size.
539 gtk_font_button_set_use_size (GtkFontButton *font_button,
542 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
544 use_size = (use_size != FALSE);
545 if (font_button->priv->use_size != use_size)
547 font_button->priv->use_size = use_size;
549 if (font_button->priv->use_font)
550 gtk_font_button_label_use_font (font_button);
552 g_object_notify (G_OBJECT (font_button), "use-size");
557 * gtk_font_button_get_show_style:
558 * @font_button: a #GtkFontButton
560 * Returns whether the name of the font style will be shown in the label.
562 * Return value: whether the font style will be shown in the label.
567 gtk_font_button_get_show_style (GtkFontButton *font_button)
569 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
571 return font_button->priv->show_style;
575 * gtk_font_button_set_show_style:
576 * @font_button: a #GtkFontButton
577 * @show_style: %TRUE if font style should be displayed in label.
579 * If @show_style is %TRUE, the font style will be displayed along with name of the selected font.
584 gtk_font_button_set_show_style (GtkFontButton *font_button,
587 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
589 show_style = (show_style != FALSE);
590 if (font_button->priv->show_style != show_style)
592 font_button->priv->show_style = show_style;
594 gtk_font_button_update_font_info (font_button);
596 g_object_notify (G_OBJECT (font_button), "show-style");
602 * gtk_font_button_get_show_size:
603 * @font_button: a #GtkFontButton
605 * Returns whether the font size will be shown in the label.
607 * Return value: whether the font size will be shown in the label.
612 gtk_font_button_get_show_size (GtkFontButton *font_button)
614 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
616 return font_button->priv->show_size;
620 * gtk_font_button_set_show_size:
621 * @font_button: a #GtkFontButton
622 * @show_size: %TRUE if font size should be displayed in dialog.
624 * If @show_size is %TRUE, the font size will be displayed along with the name of the selected font.
629 gtk_font_button_set_show_size (GtkFontButton *font_button,
632 g_return_if_fail (GTK_IS_FONT_BUTTON (font_button));
634 show_size = (show_size != FALSE);
636 if (font_button->priv->show_size != show_size)
638 font_button->priv->show_size = show_size;
640 gtk_container_remove (GTK_CONTAINER (font_button), font_button->priv->inside);
641 font_button->priv->inside = gtk_font_button_create_inside (font_button);
642 gtk_container_add (GTK_CONTAINER (font_button), font_button->priv->inside);
644 gtk_font_button_update_font_info (font_button);
646 g_object_notify (G_OBJECT (font_button), "show-size");
652 * gtk_font_button_get_font_name:
653 * @font_button: a #GtkFontButton
655 * Retrieves the name of the currently selected font.
657 * Returns: an internal copy of the font name which must not be freed.
661 G_CONST_RETURN gchar *
662 gtk_font_button_get_font_name (GtkFontButton *font_button)
664 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), NULL);
666 return font_button->priv->fontname;
670 * gtk_font_button_set_font_name:
671 * @font_button: a #GtkFontButton
672 * @fontname: Name of font to display in font selection dialog
674 * Sets or updates the currently-displayed font in font picker dialog.
676 * Returns: Return value of gtk_font_selection_dialog_set_font_name() if the
677 * font selection dialog exists, otherwise %FALSE.
682 gtk_font_button_set_font_name (GtkFontButton *font_button,
683 const gchar *fontname)
688 g_return_val_if_fail (GTK_IS_FONT_BUTTON (font_button), FALSE);
689 g_return_val_if_fail (fontname != NULL, FALSE);
691 if (g_ascii_strcasecmp (font_button->priv->fontname, fontname))
693 old_fontname = font_button->priv->fontname;
694 font_button->priv->fontname = g_strdup (fontname);
695 g_free (old_fontname);
698 gtk_font_button_update_font_info (font_button);
700 if (font_button->priv->font_dialog)
701 result = gtk_font_selection_dialog_set_font_name (GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog),
702 font_button->priv->fontname);
706 g_object_notify (G_OBJECT (font_button), "font-name");
712 gtk_font_button_clicked (GtkButton *button)
714 GtkFontSelectionDialog *font_dialog;
715 GtkFontButton *font_button = GTK_FONT_BUTTON (button);
717 if (!font_button->priv->font_dialog)
721 parent = gtk_widget_get_toplevel (GTK_WIDGET (font_button));
723 font_button->priv->font_dialog = gtk_font_selection_dialog_new (font_button->priv->title);
725 font_dialog = GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog);
728 gtk_window_set_transient_for (GTK_WINDOW (font_dialog), GTK_WINDOW (parent));
730 /* If there is a grabbed window, set new dialog as modal */
731 if (gtk_grab_get_current ())
732 gtk_window_set_modal (GTK_WINDOW (font_dialog), TRUE);
734 g_signal_connect (font_dialog->ok_button, "clicked",
735 G_CALLBACK (dialog_ok_clicked), font_button);
736 g_signal_connect (font_dialog->cancel_button, "clicked",
737 G_CALLBACK (dialog_cancel_clicked), font_button);
738 g_signal_connect (font_dialog, "destroy",
739 G_CALLBACK (dialog_destroy), font_button);
742 if (!GTK_WIDGET_VISIBLE (font_button->priv->font_dialog))
744 font_dialog = GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog);
746 gtk_font_selection_dialog_set_font_name (font_dialog, font_button->priv->fontname);
750 gtk_window_present (GTK_WINDOW (font_button->priv->font_dialog));
754 dialog_ok_clicked (GtkWidget *widget,
757 GtkFontButton *font_button = GTK_FONT_BUTTON (data);
759 gtk_widget_hide (font_button->priv->font_dialog);
761 g_free (font_button->priv->fontname);
762 font_button->priv->fontname = gtk_font_selection_dialog_get_font_name (GTK_FONT_SELECTION_DIALOG (font_button->priv->font_dialog));
765 gtk_font_button_update_font_info (font_button);
767 g_object_notify (G_OBJECT (font_button), "font-name");
769 /* Emit font_set signal */
770 g_signal_emit (font_button, font_button_signals[FONT_SET], 0);
775 dialog_cancel_clicked (GtkWidget *widget,
778 GtkFontButton *font_button = GTK_FONT_BUTTON (data);
780 gtk_widget_hide (font_button->priv->font_dialog);
784 dialog_destroy (GtkWidget *widget,
787 GtkFontButton *font_button = GTK_FONT_BUTTON (data);
789 /* Dialog will get destroyed so reference is not valid now */
790 font_button->priv->font_dialog = NULL;
794 gtk_font_button_create_inside (GtkFontButton *font_button)
798 gtk_widget_push_composite_child ();
800 widget = gtk_hbox_new (FALSE, 0);
802 font_button->priv->font_label = gtk_label_new (_("Font"));
804 gtk_label_set_justify (GTK_LABEL (font_button->priv->font_label), GTK_JUSTIFY_LEFT);
805 gtk_box_pack_start (GTK_BOX (widget), font_button->priv->font_label, TRUE, TRUE, 5);
807 if (font_button->priv->show_size)
809 gtk_box_pack_start (GTK_BOX (widget), gtk_vseparator_new (), FALSE, FALSE, 0);
810 font_button->priv->size_label = gtk_label_new ("14");
811 gtk_box_pack_start (GTK_BOX (widget), font_button->priv->size_label, FALSE, FALSE, 5);
814 gtk_widget_show_all (widget);
816 gtk_widget_pop_composite_child ();
822 gtk_font_button_label_use_font (GtkFontButton *font_button)
824 PangoFontDescription *desc;
826 if (!font_button->priv->use_font)
829 desc = pango_font_description_from_string (font_button->priv->fontname);
831 if (!font_button->priv->use_size)
832 pango_font_description_unset_fields (desc, PANGO_FONT_MASK_SIZE);
834 gtk_widget_modify_font (font_button->priv->font_label, desc);
836 pango_font_description_free (desc);
840 font_description_style_equal (const PangoFontDescription *a,
841 const PangoFontDescription *b)
843 return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
844 pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
845 pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
846 pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
850 gtk_font_button_update_font_info (GtkFontButton *font_button)
852 PangoFontDescription *desc;
857 desc = pango_font_description_from_string (font_button->priv->fontname);
858 family = pango_font_description_get_family (desc);
861 /* This gives the wrong names, e.g. Italic when the font selection
862 * dialog displayed Oblique.
864 pango_font_description_unset_fields (desc, PANGO_FONT_MASK_FAMILY | PANGO_FONT_MASK_SIZE);
865 style = pango_font_description_to_string (desc);
866 gtk_label_set_text (GTK_LABEL (font_button->priv->style_label), style);
870 if (font_button->priv->show_style && family)
872 PangoFontFamily **families;
873 PangoFontFace **faces;
874 gint n_families, n_faces, i;
877 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (font_button)),
878 &families, &n_families);
881 for (i = 0; i < n_families; i++)
883 const gchar *name = pango_font_family_get_name (families[i]);
885 if (!g_ascii_strcasecmp (name, family))
887 pango_font_family_list_faces (families[i], &faces, &n_faces);
893 for (i = 0; i < n_faces; i++)
895 PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
897 if (font_description_style_equal (tmp_desc, desc))
899 style = g_strdup (pango_font_face_get_face_name (faces[i]));
900 pango_font_description_free (tmp_desc);
904 pango_font_description_free (tmp_desc);
909 if (style == NULL || !g_ascii_strcasecmp (style, "Regular"))
910 family_style = g_strdup (family);
912 family_style = g_strdup_printf ("%s %s", family, style);
914 gtk_label_set_text (GTK_LABEL (font_button->priv->font_label), family_style);
917 g_free (family_style);
919 if (font_button->priv->show_size)
921 gchar *size = g_strdup_printf ("%g",
922 pango_font_description_get_size (desc) / (double)PANGO_SCALE);
924 gtk_label_set_text (GTK_LABEL (font_button->priv->size_label), size);
929 gtk_font_button_label_use_font (font_button);
931 pango_font_description_free (desc);
934 #define __GTK_FONT_BUTTON_C__
935 #include "gtkaliasdef.c"