1 /* GTK - The GIMP Toolkit
2 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * Massively updated for Pango by Owen Taylor, May 2000
5 * GtkFontSelection widget for Gtk+, by Damon Chaplin, May 1998.
6 * Based on the GnomeFontSelector widget, by Elliot Lee, but major changes.
7 * The GnomeFontSelector was derived from app/text_tool.c in the GIMP.
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Lesser General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public
20 * License along with this library; if not, write to the
21 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
22 * Boston, MA 02111-1307, USA.
26 * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
27 * file for a list of people on the GTK+ Team. See the ChangeLog
28 * files for a list of changes. These files are distributed with
29 * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
35 #include <glib/gprintf.h>
40 #include "gtkfontsel.h"
41 #include "gtkbutton.h"
42 #include "gtkcellrenderertext.h"
48 #include "gtkliststore.h"
52 #include "gtktreeselection.h"
53 #include "gtktreeview.h"
55 #include "gtkscrolledwindow.h"
57 #include "gtkaccessible.h"
58 #include "gtkbuildable.h"
59 #include "gtkprivate.h"
60 #include "gtkalignment.h"
63 #include "gtkspinbutton.h"
64 #include "gtkwidget.h"
68 * @Short_description: A widget for selecting fonts
69 * @Title: GtkFontSelection
70 * @See_also: #GtkFontSelectionDialog
72 * The #GtkFontSelection widget lists the available fonts, styles and sizes,
73 * allowing the user to select a font.
74 * It is used in the #GtkFontSelectionDialog widget to provide a dialog box for
77 * To set the font which is initially selected, use
78 * gtk_font_selection_set_font_name().
80 * To get the selected font use gtk_font_selection_get_font_name().
82 * To change the text which is shown in the preview area, use
83 * gtk_font_selection_set_preview_text().
87 struct _GtkFontSelectionPrivate
89 GtkWidget *search_entry;
90 GtkWidget *family_face_list;
91 GtkWidget *size_slider;
100 PangoFontFamily *family;
102 gboolean ignore_slider;
106 struct _GtkFontSelectionDialogPrivate
110 GtkWidget *ok_button;
111 GtkWidget *apply_button;
112 GtkWidget *cancel_button;
116 /* We don't enable the font and style entries because they don't add
117 * much in terms of visible effect and have a weird effect on keynav.
118 * the Windows font selector has entries similarly positioned but they
119 * act in conjunction with the associated lists to form a single focus
122 #undef INCLUDE_FONT_ENTRIES
124 /* This is the default text shown in the preview entry, though the user
125 can set it. Remember that some fonts only have capital letters. */
126 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
128 #define DEFAULT_FONT_NAME "Sans 10"
129 #define MAX_FONT_SIZE 999
131 /* This is the initial fixed height and the top padding of the preview entry */
132 #define PREVIEW_HEIGHT 84
133 #define PREVIEW_TOP_PADDING 6
135 /* These are the sizes of the font, style & size lists. */
136 #define FONT_LIST_HEIGHT 136
137 #define FONT_LIST_WIDTH 190
138 #define FONT_STYLE_LIST_WIDTH 170
139 #define FONT_SIZE_LIST_WIDTH 60
141 #define ROW_FORMAT_STRING "<span size=\"small\" foreground=\"%s\">%s <i>%s</i></span>\n<span size=\"large\" font_desc=\"%s\">%s</span>"
143 /* These are what we use as the standard font sizes, for the size list.
145 #define FONT_SIZES_LENGTH 25
146 static const gint font_sizes[] = {
147 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
148 32, 36, 40, 48, 56, 64, 72
165 static void gtk_font_selection_set_property (GObject *object,
169 static void gtk_font_selection_get_property (GObject *object,
173 static void gtk_font_selection_finalize (GObject *object);
174 static void gtk_font_selection_screen_changed (GtkWidget *widget,
175 GdkScreen *previous_screen);
176 static void gtk_font_selection_style_updated (GtkWidget *widget);
178 static void gtk_font_selection_ref_family (GtkFontSelection *fontsel,
179 PangoFontFamily *family);
180 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
181 PangoFontFace *face);
182 static void gtk_font_selection_bootstrap_fontlist (GtkFontSelection *fontsel);
184 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_VBOX)
187 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
189 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
190 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
192 gobject_class->finalize = gtk_font_selection_finalize;
193 gobject_class->set_property = gtk_font_selection_set_property;
194 gobject_class->get_property = gtk_font_selection_get_property;
196 widget_class->screen_changed = gtk_font_selection_screen_changed;
197 widget_class->style_updated = gtk_font_selection_style_updated;
199 g_object_class_install_property (gobject_class,
201 g_param_spec_string ("font-name",
203 P_("The string that represents this font"),
205 GTK_PARAM_READWRITE));
206 g_object_class_install_property (gobject_class,
208 g_param_spec_string ("preview-text",
210 P_("The text to display in order to demonstrate the selected font"),
212 GTK_PARAM_READWRITE));
214 g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
218 gtk_font_selection_set_property (GObject *object,
223 GtkFontSelection *fontsel;
225 fontsel = GTK_FONT_SELECTION (object);
230 gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
232 case PROP_PREVIEW_TEXT:
233 gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
236 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
241 static void gtk_font_selection_get_property (GObject *object,
246 GtkFontSelection *fontsel;
248 fontsel = GTK_FONT_SELECTION (object);
253 g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
255 case PROP_PREVIEW_TEXT:
256 g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
259 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
265 deleted_text_cb (GtkEntryBuffer *buffer,
270 GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)user_data;
271 GtkWidget *entry = priv->search_entry;
273 if (gtk_entry_buffer_get_length (buffer) == 0)
275 gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
276 GTK_ENTRY_ICON_SECONDARY,
280 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
284 inserted_text_cb (GtkEntryBuffer *buffer,
290 GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)user_data;
291 GtkWidget *entry = priv->search_entry;
293 if (g_strcmp0 (gtk_entry_get_icon_stock (GTK_ENTRY (entry), GTK_ENTRY_ICON_SECONDARY),
295 gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
296 GTK_ENTRY_ICON_SECONDARY,
300 gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (priv->filter));
304 icon_press_cb (GtkEntry *entry,
305 GtkEntryIconPosition pos,
309 gtk_entry_buffer_delete_text (gtk_entry_get_buffer (entry), 0, -1);
313 slider_change_cb (GtkAdjustment *adjustment, gpointer data)
315 GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
317 /* If we set the silder value manually, we ignore this callback */
318 if (priv->ignore_slider)
320 priv->ignore_slider = FALSE;
324 gtk_adjustment_set_value (gtk_spin_button_get_adjustment( GTK_SPIN_BUTTON(priv->size_spin)),
325 gtk_adjustment_get_value (adjustment));
329 spin_change_cb (GtkAdjustment *adjustment, gpointer data)
331 PangoFontDescription *desc;
332 GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
334 gdouble size = gtk_adjustment_get_value (adjustment);
336 GtkAdjustment *slider_adj = gtk_range_get_adjustment (GTK_RANGE (priv->size_slider));
338 /* We ignore the slider value change callback for both of this set_value call */
339 if (size < gtk_adjustment_get_lower (slider_adj))
341 priv->ignore_slider = TRUE;
342 gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_lower (slider_adj));
344 else if (size > gtk_adjustment_get_upper (slider_adj))
346 priv->ignore_slider = TRUE;
347 gtk_adjustment_set_value (slider_adj, gtk_adjustment_get_upper (slider_adj));
350 priv->size = ((gint)gtk_adjustment_get_value (adjustment)) * PANGO_SCALE;
352 desc = pango_context_get_font_description (gtk_widget_get_pango_context (priv->preview));
353 pango_font_description_set_size (desc, priv->size);
354 gtk_widget_override_font (priv->preview, desc);
356 gtk_widget_queue_draw (priv->preview);
360 set_range_marks (GtkWidget* size_slider, gint* sizes, gint length)
364 gtk_scale_clear_marks (GTK_SCALE (size_slider));
366 for (i=0; i<length; i++)
367 gtk_scale_add_mark (GTK_SCALE (size_slider),
369 GTK_POS_BOTTOM, NULL);
373 cursor_changed_cb (GtkTreeView *treeview, gpointer data)
377 PangoFontDescription *desc;
383 GtkTreePath *path = gtk_tree_path_new ();
385 GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*)data;
387 gtk_tree_view_get_cursor (treeview, &path, NULL);
392 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->model), &iter, path))
395 gtk_tree_model_get (GTK_TREE_MODEL (priv->model), &iter,
397 FAMILY_NAME_COLUMN, &family_name,
400 if (!face && !family_name)
404 g_free (family_name);
409 g_object_unref ((gpointer)face);
413 desc = pango_font_face_describe (face);
414 pango_font_description_set_size (desc, priv->size);
415 gtk_widget_override_font (priv->preview, desc);
417 pango_font_face_list_sizes (face, &sizes, &n_sizes);
418 /* It seems not many fonts actually have a sane set of sizes */
419 /* set_range_marks (priv->size_slider, sizes, n_sizes); */
422 g_free (family_name);
423 g_object_unref ((gpointer)face);
424 pango_font_description_free(desc);
425 gtk_tree_path_free (path);
429 gtk_font_selection_init (GtkFontSelection *fontsel)
431 GtkFontSelectionPrivate *priv;
432 PangoFontDescription *font_desc;
433 GtkWidget *scrolled_win;
434 GtkWidget *alignment;
435 GtkWidget *preview_and_size;
436 GtkWidget *size_controls;
438 GList *focus_chain = NULL;
442 fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
443 GTK_TYPE_FONT_SELECTION,
444 GtkFontSelectionPrivate);
445 priv = fontsel->priv;
446 gtk_widget_push_composite_child ();
448 /* Creating fundamental widgets for the private struct */
449 priv->search_entry = gtk_entry_new ();
450 priv->family_face_list = gtk_tree_view_new ();
451 priv->preview = gtk_entry_new ();
452 priv->size_slider = gtk_scale_new_with_range (GTK_ORIENTATION_HORIZONTAL,
453 (gdouble) font_sizes[0],
454 (gdouble) font_sizes[FONT_SIZES_LENGTH - 1],
457 priv->size_spin = gtk_spin_button_new_with_range (0.0, (gdouble)(G_MAXINT / PANGO_SCALE), 1.0);
459 /** Bootstrapping widget layout **/
460 gtk_box_set_spacing (GTK_BOX (fontsel), 6);
461 gtk_box_pack_start (GTK_BOX (fontsel), priv->search_entry, FALSE, TRUE, 0);
463 /* Main font family/face view */
464 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
465 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
466 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
467 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_face_list);
469 /* Alignment for the preview and size controls */
470 alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
471 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
472 PREVIEW_TOP_PADDING, 0, 0, 0);
473 gtk_box_pack_start (GTK_BOX (fontsel), scrolled_win, TRUE, TRUE, 0);
475 preview_and_size = gtk_vbox_new (TRUE, 0);
476 gtk_box_set_homogeneous (GTK_BOX (preview_and_size), FALSE);
478 /* The preview entry needs a scrolled window to make sure we have a */
479 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
480 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
481 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
482 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_win),
484 gtk_box_pack_start (GTK_BOX (preview_and_size), scrolled_win, FALSE, FALSE, 0);
486 /* Setting the size requests for various widgets */
487 gtk_widget_set_size_request (GTK_WIDGET (fontsel), -1, 460);
488 gtk_widget_set_size_request (scrolled_win, -1, PREVIEW_HEIGHT);
489 gtk_widget_set_size_request (priv->preview, -1, PREVIEW_HEIGHT - 6);
491 /* Unset the frame on the preview entry and set a shadow in the scrolled window */
492 gtk_entry_set_has_frame (GTK_ENTRY (priv->preview), FALSE);
493 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win),
496 /* Packing the slider and the spin in a hbox */
497 size_controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
498 gtk_scale_set_draw_value (GTK_SCALE (priv->size_slider), FALSE);
499 gtk_box_pack_start (GTK_BOX (size_controls), priv->size_slider, TRUE, TRUE, 0);
500 gtk_box_pack_start (GTK_BOX (size_controls), priv->size_spin, FALSE, TRUE, 0);
502 gtk_widget_set_valign (priv->size_spin, GTK_ALIGN_START);
504 gtk_box_pack_start (GTK_BOX (preview_and_size), size_controls, FALSE, FALSE, 0);
505 gtk_container_add (GTK_CONTAINER (alignment), preview_and_size);
507 gtk_box_pack_start (GTK_BOX (fontsel), GTK_WIDGET(alignment), FALSE, TRUE, 0);
509 /* Getting the default size */
510 font_desc = pango_context_get_font_description (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)));
511 priv->size = pango_font_description_get_size (font_desc);
515 gtk_adjustment_set_value (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider)),
516 (gdouble)(priv->size / PANGO_SCALE));
517 gtk_adjustment_set_value (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin)),
518 (gdouble)(priv->size / PANGO_SCALE));
520 gtk_widget_show_all (GTK_WIDGET (fontsel));
521 gtk_widget_hide (GTK_WIDGET (fontsel));
523 /* Treeview column and model bootstrapping */
524 gtk_font_selection_bootstrap_fontlist (fontsel);
526 /* Set default preview text */
527 gtk_entry_set_text (GTK_ENTRY (priv->preview),
528 pango_language_get_sample_string (NULL));
530 /* Set search icon and place holder text */
531 gtk_entry_set_icon_from_stock (GTK_ENTRY (priv->search_entry),
532 GTK_ENTRY_ICON_SECONDARY,
534 gtk_entry_set_placeholder_text (GTK_ENTRY (priv->search_entry), _("Search font name"));
536 /** Callback connections **/
537 /* Connect to callback for the live search text entry */
538 g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
539 "deleted-text", G_CALLBACK (deleted_text_cb), (gpointer)priv);
540 g_signal_connect (G_OBJECT (gtk_entry_get_buffer (GTK_ENTRY (priv->search_entry))),
541 "inserted-text", G_CALLBACK (inserted_text_cb), (gpointer)priv);
542 g_signal_connect (G_OBJECT (priv->search_entry),
543 "icon-press", G_CALLBACK (icon_press_cb), (gpointer)priv);
545 /* Size controls callbacks */
546 g_signal_connect (G_OBJECT (gtk_range_get_adjustment (GTK_RANGE (priv->size_slider))),
547 "value-changed", G_CALLBACK (slider_change_cb), (gpointer)priv);
548 g_signal_connect (G_OBJECT (gtk_spin_button_get_adjustment (GTK_SPIN_BUTTON (priv->size_spin))),
549 "value-changed", G_CALLBACK (spin_change_cb), (gpointer)priv);
550 priv->ignore_slider = FALSE;
552 /* Font selection callbacks */
553 g_signal_connect (G_OBJECT (priv->family_face_list), "cursor-changed",
554 G_CALLBACK (cursor_changed_cb), (gpointer)priv);
557 set_range_marks (priv->size_slider, (gint*)font_sizes, FONT_SIZES_LENGTH);
559 gtk_widget_pop_composite_child();
563 * gtk_font_selection_new:
565 * Creates a new #GtkFontSelection.
567 * Return value: a n ew #GtkFontSelection
570 gtk_font_selection_new (void)
572 GtkFontSelection *fontsel;
574 fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
576 return GTK_WIDGET (fontsel);
580 cmp_families (const void *a, const void *b)
582 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
583 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
585 return g_utf8_collate (a_name, b_name);
589 populate_list (GtkTreeView* treeview, GtkListStore* model)
591 GtkStyleContext *style_context;
596 GtkTreeIter match_row;
600 PangoFontFamily **families;
602 GString *tmp = g_string_new (NULL);
604 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (treeview)),
608 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
610 gtk_list_store_clear (model);
612 /* Get row header font color */
613 style_context = gtk_widget_get_style_context (GTK_WIDGET (treeview));
614 gtk_style_context_get_color (style_context,
615 GTK_STATE_FLAG_NORMAL |GTK_STATE_FLAG_INSENSITIVE,
618 p_color.red = (guint16)((gdouble)G_MAXUINT16 * g_color.red);
619 p_color.green = (guint16)((gdouble)G_MAXUINT16 * g_color.green);
620 p_color.blue = (guint16)((gdouble)G_MAXUINT16 * g_color.blue);
621 color_string = pango_color_to_string (&p_color);
623 /* Iterate over families and faces */
624 for (i=0; i<n_families; i++)
627 PangoFontFace **faces;
629 const gchar *fam_name = pango_font_family_get_name (families[i]);
631 pango_font_family_list_faces (families[i], &faces, &n_faces);
633 for (j=0; j<n_faces; j++)
635 PangoFontDescription *pango_desc = pango_font_face_describe (faces[j]);
636 const gchar *face_name = pango_font_face_get_face_name (faces[j]);
637 gchar *font_desc = pango_font_description_to_string (pango_desc);
639 /* foreground_color, family_name, face_name, desc, sample string */
640 g_string_printf (tmp, ROW_FORMAT_STRING,
648 gtk_list_store_append (model, &iter);
649 gtk_list_store_set (model, &iter,
650 FAMILY_COLUMN, families[i],
651 FACE_COLUMN, faces[j],
652 FAMILY_NAME_COLUMN, fam_name,
653 TEXT_COLUMN, tmp->str,
656 if ((i == 0 && j == 0) ||
657 (!g_ascii_strcasecmp (face_name, "sans") && j == 0))
662 pango_font_description_free(pango_desc);
669 path = gtk_tree_model_get_path (GTK_TREE_MODEL (model), &match_row);
670 gtk_tree_view_set_cursor (treeview, path, NULL, FALSE);
672 gtk_tree_path_free(path);
673 g_string_free (tmp, TRUE);
674 g_free (color_string);
679 visible_func (GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
681 gboolean result = FALSE;
682 GtkFontSelectionPrivate *priv = (GtkFontSelectionPrivate*) data;
684 const gchar *search_text = (const gchar*)gtk_entry_get_text (GTK_ENTRY (priv->search_entry));
686 gchar *font_name_casefold;
687 gchar *search_text_casefold;
689 gtk_tree_model_get (model, iter,
690 FAMILY_NAME_COLUMN, &font_name,
693 /* Covering some corner cases to speed up the result */
694 if (font_name == NULL ||
695 strlen (search_text) > strlen (font_name))
700 if (strlen (search_text) == 0)
706 font_name_casefold = g_utf8_casefold (font_name, -1);
707 search_text_casefold = g_utf8_casefold (search_text, -1);
709 if (g_strrstr (font_name_casefold, search_text_casefold))
712 g_free (search_text_casefold);
713 g_free (font_name_casefold);
719 gtk_font_selection_bootstrap_fontlist (GtkFontSelection* fontsel)
721 GtkTreeView *treeview = GTK_TREE_VIEW (fontsel->priv->family_face_list);
722 GtkTreeViewColumn *col;
724 fontsel->priv->model = gtk_list_store_new (4,
725 PANGO_TYPE_FONT_FAMILY,
726 PANGO_TYPE_FONT_FACE,
730 fontsel->priv->filter = gtk_tree_model_filter_new (GTK_TREE_MODEL (fontsel->priv->model),
732 g_object_unref (fontsel->priv->model);
734 gtk_tree_model_filter_set_visible_func (GTK_TREE_MODEL_FILTER (fontsel->priv->filter),
736 (gpointer)fontsel->priv,
740 gtk_tree_view_set_model (treeview, GTK_TREE_MODEL (fontsel->priv->filter));
741 g_object_unref (fontsel->priv->filter);
743 gtk_tree_view_set_rules_hint (treeview, TRUE);
744 gtk_tree_view_set_headers_visible (treeview, FALSE);
746 col = gtk_tree_view_column_new_with_attributes ("Family",
747 gtk_cell_renderer_text_new (),
748 "markup", TEXT_COLUMN,
750 gtk_tree_view_append_column (treeview, col);
752 populate_list (treeview, fontsel->priv->model);
757 gtk_font_selection_finalize (GObject *object)
759 GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
761 gtk_font_selection_ref_family (fontsel, NULL);
762 gtk_font_selection_ref_face (fontsel, NULL);
764 G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
768 gtk_font_selection_screen_changed (GtkWidget *widget,
769 GdkScreen *previous_screen)
775 gtk_font_selection_style_updated (GtkWidget *widget)
777 GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);
783 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
784 PangoFontFamily *family)
786 GtkFontSelectionPrivate *priv = fontsel->priv;
789 family = g_object_ref (family);
791 g_object_unref (priv->family);
792 priv->family = family;
796 gtk_font_selection_ref_face (GtkFontSelection *fontsel,
799 GtkFontSelectionPrivate *priv = fontsel->priv;
802 face = g_object_ref (face);
804 g_object_unref (priv->face);
808 /*****************************************************************************
809 * These functions are the main public interface for getting/setting the font.
810 *****************************************************************************/
813 * gtk_font_selection_get_family_list:
814 * @fontsel: a #GtkFontSelection
816 * This returns the #GtkTreeView that lists font families, for
817 * example, 'Sans', 'Serif', etc.
819 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
824 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
826 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
832 * gtk_font_selection_get_face_list:
833 * @fontsel: a #GtkFontSelection
835 * This returns the #GtkTreeView which lists all styles available for
836 * the selected font. For example, 'Regular', 'Bold', etc.
838 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
843 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
845 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
851 * gtk_font_selection_get_size_entry:
852 * @fontsel: a #GtkFontSelection
854 * This returns the #GtkEntry used to allow the user to edit the font
855 * number manually instead of selecting it from the list of font sizes.
857 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
862 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
864 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
870 * gtk_font_selection_get_size_list:
871 * @fontsel: a #GtkFontSelection
873 * This returns the #GtkTreeeView used to list font sizes.
875 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
880 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
882 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
888 * gtk_font_selection_get_preview_entry:
889 * @fontsel: a #GtkFontSelection
891 * This returns the #GtkEntry used to display the font as a preview.
893 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
898 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
900 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
906 * gtk_font_selection_get_family:
907 * @fontsel: a #GtkFontSelection
909 * Gets the #PangoFontFamily representing the selected font family.
911 * Return value: (transfer none): A #PangoFontFamily representing the
912 * selected font family. Font families are a collection of font
913 * faces. The returned object is owned by @fontsel and must not
914 * be modified or freed.
919 gtk_font_selection_get_family (GtkFontSelection *fontsel)
921 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
927 * gtk_font_selection_get_face:
928 * @fontsel: a #GtkFontSelection
930 * Gets the #PangoFontFace representing the selected font group
931 * details (i.e. family, slant, weight, width, etc).
933 * Return value: (transfer none): A #PangoFontFace representing the
934 * selected font group details. The returned object is owned by
935 * @fontsel and must not be modified or freed.
940 gtk_font_selection_get_face (GtkFontSelection *fontsel)
942 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
948 * gtk_font_selection_get_size:
949 * @fontsel: a #GtkFontSelection
951 * The selected font size.
953 * Return value: A n integer representing the selected font size,
954 * or -1 if no font size is selected.
959 gtk_font_selection_get_size (GtkFontSelection *fontsel)
961 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
963 return fontsel->priv->size;
967 * gtk_font_selection_get_font_name:
968 * @fontsel: a #GtkFontSelection
970 * Gets the currently-selected font name.
972 * Note that this can be a different string than what you set with
973 * gtk_font_selection_set_font_name(), as the font selection widget may
974 * normalize font names and thus return a string with a different structure.
975 * For example, "Helvetica Italic Bold 12" could be normalized to
976 * "Helvetica Bold Italic 12". Use pango_font_description_equal()
977 * if you want to compare two font descriptions.
979 * Return value: A string with the name of the current font, or %NULL if
980 * no font is selected. You must free this string with g_free().
983 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
988 /* This sets the current font, then selecting the appropriate list rows. */
991 * gtk_font_selection_set_font_name:
992 * @fontsel: a #GtkFontSelection
993 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
995 * Sets the currently-selected font.
997 * Note that the @fontsel needs to know the screen in which it will appear
998 * for this to work; this can be guaranteed by simply making sure that the
999 * @fontsel is inserted in a toplevel window before you call this function.
1001 * Return value: %TRUE if the font could be set successfully; %FALSE if no
1002 * such font exists or if the @fontsel doesn't belong to a particular
1006 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1007 const gchar *fontname)
1010 PangoFontFamily *family = NULL;
1011 PangoFontFace *face = NULL;
1012 PangoFontDescription *new_desc;
1015 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1021 * gtk_font_selection_get_preview_text:
1022 * @fontsel: a #GtkFontSelection
1024 * Gets the text displayed in the preview area.
1026 * Return value: the text displayed in the preview area.
1027 * This string is owned by the widget and should not be
1030 G_CONST_RETURN gchar*
1031 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1038 * gtk_font_selection_set_preview_text:
1039 * @fontsel: a #GtkFontSelection
1040 * @text: the text to display in the preview area
1042 * Sets the text displayed in the preview area.
1043 * The @text is used to show how the selected font looks.
1046 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
1050 GtkFontSelectionPrivate *priv;
1052 g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1053 g_return_if_fail (text != NULL);
1055 priv = fontsel->priv;
1061 * SECTION:gtkfontseldlg
1062 * @Short_description: A dialog box for selecting fonts
1063 * @Title: GtkFontSelectionDialog
1064 * @See_also: #GtkFontSelection, #GtkDialog
1066 * The #GtkFontSelectionDialog widget is a dialog box for selecting a font.
1068 * To set the font which is initially selected, use
1069 * gtk_font_selection_dialog_set_font_name().
1071 * To get the selected font use gtk_font_selection_dialog_get_font_name().
1073 * To change the text which is shown in the preview area, use
1074 * gtk_font_selection_dialog_set_preview_text().
1076 * <refsect2 id="GtkFontSelectionDialog-BUILDER-UI">
1077 * <title>GtkFontSelectionDialog as GtkBuildable</title>
1078 * The GtkFontSelectionDialog implementation of the GtkBuildable interface
1079 * exposes the embedded #GtkFontSelection as internal child with the
1080 * name "font_selection". It also exposes the buttons with the names
1081 * "ok_button", "cancel_button" and "apply_button".
1085 static void gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface);
1086 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1087 GtkBuilder *builder,
1088 const gchar *childname);
1090 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1092 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1093 gtk_font_selection_dialog_buildable_interface_init))
1095 static GtkBuildableIface *parent_buildable_iface;
1098 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1100 g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1104 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1106 GtkFontSelectionDialogPrivate *priv;
1107 GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1108 GtkWidget *action_area, *content_area;
1110 fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1111 GTK_TYPE_FONT_SELECTION_DIALOG,
1112 GtkFontSelectionDialogPrivate);
1113 priv = fontseldiag->priv;
1115 content_area = gtk_dialog_get_content_area (dialog);
1116 action_area = gtk_dialog_get_action_area (dialog);
1118 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1119 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1120 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1121 gtk_box_set_spacing (GTK_BOX (action_area), 6);
1123 gtk_widget_push_composite_child ();
1125 gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1127 /* Create the content area */
1128 priv->fontsel = gtk_font_selection_new ();
1129 gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1130 gtk_widget_show (priv->fontsel);
1131 gtk_box_pack_start (GTK_BOX (content_area),
1132 priv->fontsel, TRUE, TRUE, 0);
1134 /* Create the action area */
1135 priv->cancel_button = gtk_dialog_add_button (dialog,
1137 GTK_RESPONSE_CANCEL);
1139 priv->apply_button = gtk_dialog_add_button (dialog,
1141 GTK_RESPONSE_APPLY);
1142 gtk_widget_hide (priv->apply_button);
1144 priv->ok_button = gtk_dialog_add_button (dialog,
1147 gtk_widget_grab_default (priv->ok_button);
1149 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1152 GTK_RESPONSE_CANCEL,
1155 gtk_window_set_title (GTK_WINDOW (fontseldiag),
1156 _("Font Selection"));
1158 gtk_widget_pop_composite_child ();
1162 * gtk_font_selection_dialog_new:
1163 * @title: the title of the dialog window
1165 * Creates a new #GtkFontSelectionDialog.
1167 * Return value: a new #GtkFontSelectionDialog
1170 gtk_font_selection_dialog_new (const gchar *title)
1172 GtkFontSelectionDialog *fontseldiag;
1174 fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1177 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1179 return GTK_WIDGET (fontseldiag);
1183 * gtk_font_selection_dialog_get_font_selection:
1184 * @fsd: a #GtkFontSelectionDialog
1186 * Retrieves the #GtkFontSelection widget embedded in the dialog.
1188 * Returns: (transfer none): the embedded #GtkFontSelection
1193 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1195 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1197 return fsd->priv->fontsel;
1202 * gtk_font_selection_dialog_get_ok_button:
1203 * @fsd: a #GtkFontSelectionDialog
1205 * Gets the 'OK' button.
1207 * Return value: (transfer none): the #GtkWidget used in the dialog
1208 * for the 'OK' button.
1213 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1215 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1217 return fsd->priv->ok_button;
1221 * gtk_font_selection_dialog_get_cancel_button:
1222 * @fsd: a #GtkFontSelectionDialog
1224 * Gets the 'Cancel' button.
1226 * Return value: (transfer none): the #GtkWidget used in the dialog
1227 * for the 'Cancel' button.
1232 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1234 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1236 return fsd->priv->cancel_button;
1240 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1242 parent_buildable_iface = g_type_interface_peek_parent (iface);
1243 iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1247 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1248 GtkBuilder *builder,
1249 const gchar *childname)
1251 GtkFontSelectionDialogPrivate *priv;
1253 priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1255 if (g_strcmp0 (childname, "ok_button") == 0)
1256 return G_OBJECT (priv->ok_button);
1257 else if (g_strcmp0 (childname, "cancel_button") == 0)
1258 return G_OBJECT (priv->cancel_button);
1259 else if (g_strcmp0 (childname, "apply_button") == 0)
1260 return G_OBJECT (priv->apply_button);
1261 else if (g_strcmp0 (childname, "font_selection") == 0)
1262 return G_OBJECT (priv->fontsel);
1264 return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1268 * gtk_font_selection_dialog_get_font_name:
1269 * @fsd: a #GtkFontSelectionDialog
1271 * Gets the currently-selected font name.
1273 * Note that this can be a different string than what you set with
1274 * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1275 * may normalize font names and thus return a string with a different
1276 * structure. For example, "Helvetica Italic Bold 12" could be normalized
1277 * to "Helvetica Bold Italic 12". Use pango_font_description_equal()
1278 * if you want to compare two font descriptions.
1280 * Return value: A string with the name of the current font, or %NULL if no
1281 * font is selected. You must free this string with g_free().
1284 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1286 GtkFontSelectionDialogPrivate *priv;
1288 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1292 return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1296 * gtk_font_selection_dialog_set_font_name:
1297 * @fsd: a #GtkFontSelectionDialog
1298 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1300 * Sets the currently selected font.
1302 * Return value: %TRUE if the font selected in @fsd is now the
1303 * @fontname specified, %FALSE otherwise.
1306 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1307 const gchar *fontname)
1309 GtkFontSelectionDialogPrivate *priv;
1311 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1312 g_return_val_if_fail (fontname, FALSE);
1316 return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1320 * gtk_font_selection_dialog_get_preview_text:
1321 * @fsd: a #GtkFontSelectionDialog
1323 * Gets the text displayed in the preview area.
1325 * Return value: the text displayed in the preview area.
1326 * This string is owned by the widget and should not be
1329 G_CONST_RETURN gchar*
1330 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1332 GtkFontSelectionDialogPrivate *priv;
1334 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1338 return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1342 * gtk_font_selection_dialog_set_preview_text:
1343 * @fsd: a #GtkFontSelectionDialog
1344 * @text: the text to display in the preview area
1346 * Sets the text displayed in the preview area.
1349 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1352 GtkFontSelectionDialogPrivate *priv;
1354 g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1355 g_return_if_fail (text != NULL);
1359 gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);