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"
46 #include "gtkliststore.h"
50 #include "gtktreeselection.h"
51 #include "gtktreeview.h"
52 #include "gtkscrolledwindow.h"
54 #include "gtkaccessible.h"
55 #include "gtkbuildable.h"
56 #include "gtkorientable.h"
57 #include "gtkprivate.h"
62 * @Short_description: A widget for selecting fonts
63 * @Title: GtkFontSelection
64 * @See_also: #GtkFontSelectionDialog
66 * The #GtkFontSelection widget lists the available fonts, styles and sizes,
67 * allowing the user to select a font.
68 * It is used in the #GtkFontSelectionDialog widget to provide a dialog box for
71 * To set the font which is initially selected, use
72 * gtk_font_selection_set_font_name().
74 * To get the selected font use gtk_font_selection_get_font_name().
76 * To change the text which is shown in the preview area, use
77 * gtk_font_selection_set_preview_text().
81 struct _GtkFontSelectionPrivate
83 GtkWidget *font_entry; /* Used _get_family_entry() for consistency, -mr */
84 GtkWidget *font_style_entry; /* Used _get_face_entry() for consistency, -mr */
86 GtkWidget *size_entry;
87 GtkWidget *preview_entry;
89 GtkWidget *family_list;
93 PangoFontFamily *family; /* Current family */
94 PangoFontFace *face; /* Current face */
100 struct _GtkFontSelectionDialogPrivate
104 GtkWidget *ok_button;
105 GtkWidget *apply_button;
106 GtkWidget *cancel_button;
110 /* We don't enable the font and style entries because they don't add
111 * much in terms of visible effect and have a weird effect on keynav.
112 * the Windows font selector has entries similarly positioned but they
113 * act in conjunction with the associated lists to form a single focus
116 #undef INCLUDE_FONT_ENTRIES
118 /* This is the default text shown in the preview entry, though the user
119 can set it. Remember that some fonts only have capital letters. */
120 #define PREVIEW_TEXT N_("abcdefghijk ABCDEFGHIJK")
122 #define DEFAULT_FONT_NAME "Sans 10"
124 /* This is the initial and maximum height of the preview entry (it expands
125 when large font sizes are selected). Initial height is also the minimum. */
126 #define INITIAL_PREVIEW_HEIGHT 44
127 #define MAX_PREVIEW_HEIGHT 300
129 /* These are the sizes of the font, style & size lists. */
130 #define FONT_LIST_HEIGHT 136
131 #define FONT_LIST_WIDTH 190
132 #define FONT_STYLE_LIST_WIDTH 170
133 #define FONT_SIZE_LIST_WIDTH 60
135 /* These are what we use as the standard font sizes, for the size list.
137 static const guint16 font_sizes[] = {
138 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 20, 22, 24, 26, 28,
139 32, 36, 40, 48, 56, 64, 72
163 static void gtk_font_selection_set_property (GObject *object,
167 static void gtk_font_selection_get_property (GObject *object,
171 static void gtk_font_selection_finalize (GObject *object);
172 static void gtk_font_selection_screen_changed (GtkWidget *widget,
173 GdkScreen *previous_screen);
174 static void gtk_font_selection_style_updated (GtkWidget *widget);
176 /* These are the callbacks & related functions. */
177 static void gtk_font_selection_select_font (GtkTreeSelection *selection,
179 static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs);
181 static void gtk_font_selection_show_available_styles (GtkFontSelection *fs);
182 static void gtk_font_selection_select_best_style (GtkFontSelection *fs,
184 static void gtk_font_selection_select_style (GtkTreeSelection *selection,
187 static void gtk_font_selection_select_best_size (GtkFontSelection *fs);
188 static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs,
189 gboolean first_time);
190 static void gtk_font_selection_size_activate (GtkWidget *w,
192 static gboolean gtk_font_selection_size_focus_out (GtkWidget *w,
193 GdkEventFocus *event,
195 static void gtk_font_selection_select_size (GtkTreeSelection *selection,
198 static void gtk_font_selection_scroll_on_map (GtkWidget *w,
201 static void gtk_font_selection_preview_changed (GtkWidget *entry,
202 GtkFontSelection *fontsel);
203 static void gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel);
206 /* Misc. utility functions. */
207 static void gtk_font_selection_load_font (GtkFontSelection *fs);
208 static void gtk_font_selection_update_preview (GtkFontSelection *fs);
210 static PangoFontDescription *gtk_font_selection_get_font_description (GtkFontSelection *fontsel);
211 static gboolean gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
212 PangoFontDescription *new_desc,
213 PangoFontFamily **pfamily,
214 PangoFontFace **pface);
215 static void gtk_font_selection_reload_fonts (GtkFontSelection *fontsel);
216 static void gtk_font_selection_ref_family (GtkFontSelection *fontsel,
217 PangoFontFamily *family);
218 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
219 PangoFontFace *face);
221 G_DEFINE_TYPE (GtkFontSelection, gtk_font_selection, GTK_TYPE_BOX)
224 gtk_font_selection_class_init (GtkFontSelectionClass *klass)
226 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
227 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
229 gobject_class->finalize = gtk_font_selection_finalize;
230 gobject_class->set_property = gtk_font_selection_set_property;
231 gobject_class->get_property = gtk_font_selection_get_property;
233 widget_class->screen_changed = gtk_font_selection_screen_changed;
234 widget_class->style_updated = gtk_font_selection_style_updated;
236 g_object_class_install_property (gobject_class,
238 g_param_spec_string ("font-name",
240 P_("The string that represents this font"),
242 GTK_PARAM_READWRITE));
243 g_object_class_install_property (gobject_class,
245 g_param_spec_string ("preview-text",
247 P_("The text to display in order to demonstrate the selected font"),
249 GTK_PARAM_READWRITE));
251 g_type_class_add_private (klass, sizeof (GtkFontSelectionPrivate));
255 gtk_font_selection_set_property (GObject *object,
260 GtkFontSelection *fontsel;
262 fontsel = GTK_FONT_SELECTION (object);
267 gtk_font_selection_set_font_name (fontsel, g_value_get_string (value));
269 case PROP_PREVIEW_TEXT:
270 gtk_font_selection_set_preview_text (fontsel, g_value_get_string (value));
273 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
278 static void gtk_font_selection_get_property (GObject *object,
283 GtkFontSelection *fontsel;
285 fontsel = GTK_FONT_SELECTION (object);
290 g_value_take_string (value, gtk_font_selection_get_font_name (fontsel));
292 case PROP_PREVIEW_TEXT:
293 g_value_set_string (value, gtk_font_selection_get_preview_text (fontsel));
296 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
301 /* Handles key press events on the lists, so that we can trap Enter to
302 * activate the default button on our own.
305 list_row_activated (GtkWidget *widget)
307 GtkWidget *default_widget, *focus_widget;
310 window = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (widget)));
311 if (!gtk_widget_is_toplevel (GTK_WIDGET (window)))
316 default_widget = gtk_window_get_default_widget (window);
317 focus_widget = gtk_window_get_focus (window);
319 if (widget != default_widget &&
320 !(widget == focus_widget && (!default_widget || !gtk_widget_get_sensitive (default_widget))))
321 gtk_window_activate_default (window);
328 gtk_font_selection_init (GtkFontSelection *fontsel)
330 GtkFontSelectionPrivate *priv;
331 GtkWidget *scrolled_win;
333 GtkWidget *table, *label;
334 GtkWidget *font_label, *style_label;
337 GtkTreeViewColumn *column;
338 GList *focus_chain = NULL;
341 fontsel->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontsel,
342 GTK_TYPE_FONT_SELECTION,
343 GtkFontSelectionPrivate);
344 priv = fontsel->priv;
346 gtk_orientable_set_orientation (GTK_ORIENTABLE (fontsel),
347 GTK_ORIENTATION_VERTICAL);
349 gtk_widget_push_composite_child ();
351 gtk_box_set_spacing (GTK_BOX (fontsel), 12);
352 priv->size = 12 * PANGO_SCALE;
354 /* Create the table of font, style & size. */
355 table = gtk_table_new (3, 3, FALSE);
356 gtk_widget_show (table);
357 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
358 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
359 gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
361 #ifdef INCLUDE_FONT_ENTRIES
362 priv->font_entry = gtk_entry_new ();
363 gtk_editable_set_editable (GTK_EDITABLE (priv->font_entry), FALSE);
364 gtk_widget_set_size_request (priv->font_entry, 20, -1);
365 gtk_widget_show (priv->font_entry);
366 gtk_table_attach (GTK_TABLE (table), priv->font_entry, 0, 1, 1, 2,
369 priv->font_style_entry = gtk_entry_new ();
370 gtk_editable_set_editable (GTK_EDITABLE (priv->font_style_entry), FALSE);
371 gtk_widget_set_size_request (priv->font_style_entry, 20, -1);
372 gtk_widget_show (priv->font_style_entry);
373 gtk_table_attach (GTK_TABLE (table), priv->font_style_entry, 1, 2, 1, 2,
375 #endif /* INCLUDE_FONT_ENTRIES */
377 priv->size_entry = gtk_entry_new ();
378 gtk_widget_set_size_request (priv->size_entry, 20, -1);
379 gtk_widget_show (priv->size_entry);
380 gtk_table_attach (GTK_TABLE (table), priv->size_entry, 2, 3, 1, 2,
382 g_signal_connect (priv->size_entry, "activate",
383 G_CALLBACK (gtk_font_selection_size_activate),
385 g_signal_connect_after (priv->size_entry, "focus-out-event",
386 G_CALLBACK (gtk_font_selection_size_focus_out),
389 font_label = gtk_label_new_with_mnemonic (_("_Family:"));
390 gtk_widget_set_halign (font_label, GTK_ALIGN_START);
391 gtk_widget_set_valign (font_label, GTK_ALIGN_CENTER);
392 gtk_widget_show (font_label);
393 gtk_table_attach (GTK_TABLE (table), font_label, 0, 1, 0, 1,
396 style_label = gtk_label_new_with_mnemonic (_("_Style:"));
397 gtk_widget_set_halign (style_label, GTK_ALIGN_START);
398 gtk_widget_set_valign (style_label, GTK_ALIGN_CENTER);
399 gtk_widget_show (style_label);
400 gtk_table_attach (GTK_TABLE (table), style_label, 1, 2, 0, 1,
403 label = gtk_label_new_with_mnemonic (_("Si_ze:"));
404 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
406 gtk_widget_set_halign (label, GTK_ALIGN_START);
407 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
408 gtk_widget_show (label);
409 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
413 /* Create the lists */
415 model = gtk_list_store_new (2,
416 G_TYPE_OBJECT, /* FAMILY_COLUMN */
417 G_TYPE_STRING); /* FAMILY_NAME_COLUMN */
418 priv->family_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
419 g_object_unref (model);
421 g_signal_connect (priv->family_list, "row-activated",
422 G_CALLBACK (list_row_activated), fontsel);
424 column = gtk_tree_view_column_new_with_attributes ("Family",
425 gtk_cell_renderer_text_new (),
426 "text", FAMILY_NAME_COLUMN,
428 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
429 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->family_list), column);
431 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->family_list), FALSE);
432 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)),
433 GTK_SELECTION_BROWSE);
435 gtk_label_set_mnemonic_widget (GTK_LABEL (font_label), priv->family_list);
437 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
438 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
439 gtk_widget_set_size_request (scrolled_win,
440 FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
441 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->family_list);
442 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
443 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
444 gtk_widget_show (priv->family_list);
445 gtk_widget_show (scrolled_win);
447 gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 1, 3,
448 GTK_EXPAND | GTK_FILL,
449 GTK_EXPAND | GTK_FILL, 0, 0);
450 focus_chain = g_list_append (focus_chain, scrolled_win);
452 model = gtk_list_store_new (2,
453 G_TYPE_OBJECT, /* FACE_COLUMN */
454 G_TYPE_STRING); /* FACE_NAME_COLUMN */
455 priv->face_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
456 g_object_unref (model);
457 g_signal_connect (priv->face_list, "row-activated",
458 G_CALLBACK (list_row_activated), fontsel);
460 gtk_label_set_mnemonic_widget (GTK_LABEL (style_label), priv->face_list);
462 column = gtk_tree_view_column_new_with_attributes ("Face",
463 gtk_cell_renderer_text_new (),
464 "text", FACE_NAME_COLUMN,
466 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
467 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->face_list), column);
469 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->face_list), FALSE);
470 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)),
471 GTK_SELECTION_BROWSE);
473 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
474 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
475 gtk_widget_set_size_request (scrolled_win,
476 FONT_STYLE_LIST_WIDTH, FONT_LIST_HEIGHT);
477 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->face_list);
478 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
479 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
480 gtk_widget_show (priv->face_list);
481 gtk_widget_show (scrolled_win);
482 gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 1, 3,
483 GTK_EXPAND | GTK_FILL,
484 GTK_EXPAND | GTK_FILL, 0, 0);
485 focus_chain = g_list_append (focus_chain, scrolled_win);
487 focus_chain = g_list_append (focus_chain, priv->size_entry);
489 model = gtk_list_store_new (1, G_TYPE_INT);
490 priv->size_list = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
491 g_object_unref (model);
492 g_signal_connect (priv->size_list, "row-activated",
493 G_CALLBACK (list_row_activated), fontsel);
495 column = gtk_tree_view_column_new_with_attributes ("Size",
496 gtk_cell_renderer_text_new (),
499 gtk_tree_view_column_set_sizing (column, GTK_TREE_VIEW_COLUMN_AUTOSIZE);
500 gtk_tree_view_append_column (GTK_TREE_VIEW (priv->size_list), column);
502 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (priv->size_list), FALSE);
503 gtk_tree_selection_set_mode (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)),
504 GTK_SELECTION_BROWSE);
506 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
507 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled_win), GTK_SHADOW_IN);
508 gtk_container_add (GTK_CONTAINER (scrolled_win), priv->size_list);
509 gtk_widget_set_size_request (scrolled_win, -1, FONT_LIST_HEIGHT);
510 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
511 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
512 gtk_widget_show (priv->size_list);
513 gtk_widget_show (scrolled_win);
514 gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
515 GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0);
516 focus_chain = g_list_append (focus_chain, scrolled_win);
518 gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
519 g_list_free (focus_chain);
521 /* Insert the fonts. */
522 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->family_list)), "changed",
523 G_CALLBACK (gtk_font_selection_select_font), fontsel);
525 g_signal_connect_after (priv->family_list, "map",
526 G_CALLBACK (gtk_font_selection_scroll_on_map),
529 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->face_list)), "changed",
530 G_CALLBACK (gtk_font_selection_select_style), fontsel);
532 g_signal_connect (gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list)), "changed",
533 G_CALLBACK (gtk_font_selection_select_size), fontsel);
534 atk_obj = gtk_widget_get_accessible (priv->size_list);
535 if (GTK_IS_ACCESSIBLE (atk_obj))
537 /* Accessibility support is enabled.
538 * Make the label ATK_RELATON_LABEL_FOR for the size list as well.
540 AtkObject *atk_label;
541 AtkRelationSet *relation_set;
542 AtkRelation *relation;
543 AtkObject *obj_array[1];
545 atk_label = gtk_widget_get_accessible (label);
546 relation_set = atk_object_ref_relation_set (atk_obj);
547 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABELLED_BY);
550 atk_relation_add_target (relation, atk_label);
554 obj_array[0] = atk_label;
555 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABELLED_BY);
556 atk_relation_set_add (relation_set, relation);
558 g_object_unref (relation_set);
560 relation_set = atk_object_ref_relation_set (atk_label);
561 relation = atk_relation_set_get_relation_by_type (relation_set, ATK_RELATION_LABEL_FOR);
564 atk_relation_add_target (relation, atk_obj);
568 obj_array[0] = atk_obj;
569 relation = atk_relation_new (obj_array, 1, ATK_RELATION_LABEL_FOR);
570 atk_relation_set_add (relation_set, relation);
572 g_object_unref (relation_set);
575 vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
576 gtk_widget_show (vbox);
577 gtk_box_pack_start (GTK_BOX (fontsel), vbox, FALSE, TRUE, 0);
579 /* create the text entry widget */
580 label = gtk_label_new_with_mnemonic (_("_Preview:"));
581 gtk_widget_set_halign (label, GTK_ALIGN_START);
582 gtk_widget_set_valign (label, GTK_ALIGN_CENTER);
583 gtk_widget_show (label);
584 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 0);
586 text_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
587 gtk_widget_show (text_box);
588 gtk_box_pack_start (GTK_BOX (vbox), text_box, FALSE, TRUE, 0);
590 priv->preview_entry = gtk_entry_new ();
591 gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->preview_entry);
592 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), _(PREVIEW_TEXT));
594 gtk_widget_show (priv->preview_entry);
595 g_signal_connect (priv->preview_entry, "changed",
596 G_CALLBACK (gtk_font_selection_preview_changed), fontsel);
597 gtk_widget_set_size_request (priv->preview_entry,
598 -1, INITIAL_PREVIEW_HEIGHT);
599 gtk_box_pack_start (GTK_BOX (text_box), priv->preview_entry,
601 gtk_widget_pop_composite_child();
605 * gtk_font_selection_new:
607 * Creates a new #GtkFontSelection.
609 * Return value: a n ew #GtkFontSelection
612 gtk_font_selection_new (void)
614 GtkFontSelection *fontsel;
616 fontsel = g_object_new (GTK_TYPE_FONT_SELECTION, NULL);
618 return GTK_WIDGET (fontsel);
622 gtk_font_selection_finalize (GObject *object)
624 GtkFontSelection *fontsel = GTK_FONT_SELECTION (object);
626 gtk_font_selection_ref_family (fontsel, NULL);
627 gtk_font_selection_ref_face (fontsel, NULL);
629 G_OBJECT_CLASS (gtk_font_selection_parent_class)->finalize (object);
633 gtk_font_selection_ref_family (GtkFontSelection *fontsel,
634 PangoFontFamily *family)
636 GtkFontSelectionPrivate *priv = fontsel->priv;
639 family = g_object_ref (family);
641 g_object_unref (priv->family);
642 priv->family = family;
645 static void gtk_font_selection_ref_face (GtkFontSelection *fontsel,
648 GtkFontSelectionPrivate *priv = fontsel->priv;
651 face = g_object_ref (face);
653 g_object_unref (priv->face);
658 gtk_font_selection_reload_fonts (GtkFontSelection *fontsel)
660 if (gtk_widget_has_screen (GTK_WIDGET (fontsel)))
662 PangoFontDescription *desc;
663 desc = gtk_font_selection_get_font_description (fontsel);
665 gtk_font_selection_show_available_fonts (fontsel);
666 gtk_font_selection_show_available_sizes (fontsel, TRUE);
667 gtk_font_selection_show_available_styles (fontsel);
669 gtk_font_selection_select_font_desc (fontsel, desc, NULL, NULL);
670 gtk_font_selection_scroll_to_selection (fontsel);
672 pango_font_description_free (desc);
677 gtk_font_selection_screen_changed (GtkWidget *widget,
678 GdkScreen *previous_screen)
680 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
684 gtk_font_selection_style_updated (GtkWidget *widget)
686 GTK_WIDGET_CLASS (gtk_font_selection_parent_class)->style_updated (widget);
688 /* Maybe fonts where installed or removed... */
689 gtk_font_selection_reload_fonts (GTK_FONT_SELECTION (widget));
693 gtk_font_selection_preview_changed (GtkWidget *entry,
694 GtkFontSelection *fontsel)
696 g_object_notify (G_OBJECT (fontsel), "preview-text");
700 scroll_to_selection (GtkTreeView *tree_view)
702 GtkTreeSelection *selection = gtk_tree_view_get_selection (tree_view);
706 if (gtk_tree_selection_get_selected (selection, &model, &iter))
708 GtkTreePath *path = gtk_tree_model_get_path (model, &iter);
709 gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE, 0.5, 0.5);
710 gtk_tree_path_free (path);
715 set_cursor_to_iter (GtkTreeView *view,
718 GtkTreeModel *model = gtk_tree_view_get_model (view);
719 GtkTreePath *path = gtk_tree_model_get_path (model, iter);
721 gtk_tree_view_set_cursor (view, path, NULL, FALSE);
723 gtk_tree_path_free (path);
727 gtk_font_selection_scroll_to_selection (GtkFontSelection *fontsel)
729 GtkFontSelectionPrivate *priv = fontsel->priv;
731 /* Try to scroll the font family list to the selected item */
732 scroll_to_selection (GTK_TREE_VIEW (priv->family_list));
734 /* Try to scroll the font family list to the selected item */
735 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
737 /* Try to scroll the font family list to the selected item */
738 scroll_to_selection (GTK_TREE_VIEW (priv->size_list));
739 /* This is called when the list is mapped. Here we scroll to the current
740 font if necessary. */
744 gtk_font_selection_scroll_on_map (GtkWidget *widget,
747 gtk_font_selection_scroll_to_selection (GTK_FONT_SELECTION (data));
750 /* This is called when a family is selected in the list. */
752 gtk_font_selection_select_font (GtkTreeSelection *selection,
755 GtkFontSelection *fontsel;
756 GtkFontSelectionPrivate *priv;
759 #ifdef INCLUDE_FONT_ENTRIES
760 const gchar *family_name;
763 fontsel = GTK_FONT_SELECTION (data);
764 priv = fontsel->priv;
766 if (gtk_tree_selection_get_selected (selection, &model, &iter))
768 PangoFontFamily *family;
770 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
771 if (priv->family != family)
773 gtk_font_selection_ref_family (fontsel, family);
775 #ifdef INCLUDE_FONT_ENTRIES
776 family_name = pango_font_family_get_name (priv->family);
777 gtk_entry_set_text (GTK_ENTRY (priv->font_entry), family_name);
780 gtk_font_selection_show_available_styles (fontsel);
781 gtk_font_selection_select_best_style (fontsel, TRUE);
784 g_object_unref (family);
789 cmp_families (const void *a, const void *b)
791 const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
792 const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
794 return g_utf8_collate (a_name, b_name);
798 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
800 GtkFontSelectionPrivate *priv = fontsel->priv;
802 PangoFontFamily **families;
803 PangoFontFamily *match_family = NULL;
805 GtkTreeIter match_row;
807 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list)));
809 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
810 &families, &n_families);
811 qsort (families, n_families, sizeof (PangoFontFamily *), cmp_families);
813 gtk_list_store_clear (model);
815 for (i=0; i<n_families; i++)
817 const gchar *name = pango_font_family_get_name (families[i]);
820 gtk_list_store_append (model, &iter);
821 gtk_list_store_set (model, &iter,
822 FAMILY_COLUMN, families[i],
823 FAMILY_NAME_COLUMN, name,
826 if (i == 0 || !g_ascii_strcasecmp (name, "sans"))
828 match_family = families[i];
833 gtk_font_selection_ref_family (fontsel, match_family);
836 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &match_row);
837 #ifdef INCLUDE_FONT_ENTRIES
838 gtk_entry_set_text (GTK_ENTRY (priv->font_entry),
839 pango_font_family_get_name (match_family));
840 #endif /* INCLUDE_FONT_ENTRIES */
847 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
849 int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
853 if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
854 return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
856 if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
857 return pango_font_description_get_style (a) - pango_font_description_get_style (b);
859 if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
860 return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
862 if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
863 return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
869 faces_sort_func (const void *a, const void *b)
871 PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
872 PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
874 int ord = compare_font_descriptions (desc_a, desc_b);
876 pango_font_description_free (desc_a);
877 pango_font_description_free (desc_b);
883 font_description_style_equal (const PangoFontDescription *a,
884 const PangoFontDescription *b)
886 return (pango_font_description_get_weight (a) == pango_font_description_get_weight (b) &&
887 pango_font_description_get_style (a) == pango_font_description_get_style (b) &&
888 pango_font_description_get_stretch (a) == pango_font_description_get_stretch (b) &&
889 pango_font_description_get_variant (a) == pango_font_description_get_variant (b));
892 /* This fills the font style list with all the possible style combinations
893 for the current font family. */
895 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
897 GtkFontSelectionPrivate *priv = fontsel->priv;
899 PangoFontFace **faces;
900 PangoFontDescription *old_desc;
902 GtkTreeIter match_row;
903 PangoFontFace *match_face = NULL;
905 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list)));
908 old_desc = pango_font_face_describe (priv->face);
912 pango_font_family_list_faces (priv->family, &faces, &n_faces);
913 qsort (faces, n_faces, sizeof (PangoFontFace *), faces_sort_func);
915 gtk_list_store_clear (model);
917 for (i=0; i < n_faces; i++)
920 const gchar *str = pango_font_face_get_face_name (faces[i]);
922 gtk_list_store_append (model, &iter);
923 gtk_list_store_set (model, &iter,
924 FACE_COLUMN, faces[i],
925 FACE_NAME_COLUMN, str,
931 match_face = faces[i];
935 PangoFontDescription *tmp_desc = pango_font_face_describe (faces[i]);
937 if (font_description_style_equal (tmp_desc, old_desc))
940 match_face = faces[i];
943 pango_font_description_free (tmp_desc);
948 pango_font_description_free (old_desc);
950 gtk_font_selection_ref_face (fontsel, match_face);
953 #ifdef INCLUDE_FONT_ENTRIES
954 const gchar *str = pango_font_face_get_face_name (priv->face);
956 gtk_entry_set_text (GTK_ENTRY (priv->font_style_entry), str);
958 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_row);
964 /* This selects a style when the user selects a font. It just uses the first
965 available style at present. I was thinking of trying to maintain the
966 selected style, e.g. bold italic, when the user selects different fonts.
967 However, the interface is so easy to use now I'm not sure it's worth it.
968 Note: This will load a font. */
970 gtk_font_selection_select_best_style (GtkFontSelection *fontsel,
973 GtkFontSelectionPrivate *priv = fontsel->priv;
977 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
979 if (gtk_tree_model_get_iter_first (model, &iter))
981 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &iter);
982 scroll_to_selection (GTK_TREE_VIEW (priv->face_list));
985 gtk_font_selection_show_available_sizes (fontsel, FALSE);
986 gtk_font_selection_select_best_size (fontsel);
990 /* This is called when a style is selected in the list. */
992 gtk_font_selection_select_style (GtkTreeSelection *selection,
995 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
999 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1001 PangoFontFace *face;
1003 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1004 gtk_font_selection_ref_face (fontsel, face);
1005 g_object_unref (face);
1008 gtk_font_selection_show_available_sizes (fontsel, FALSE);
1009 gtk_font_selection_select_best_size (fontsel);
1013 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel,
1014 gboolean first_time)
1016 GtkFontSelectionPrivate *priv = fontsel->priv;
1018 GtkListStore *model;
1022 model = GTK_LIST_STORE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->size_list)));
1024 /* Insert the standard font sizes */
1027 gtk_list_store_clear (model);
1029 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
1033 gtk_list_store_append (model, &iter);
1034 gtk_list_store_set (model, &iter, SIZE_COLUMN, font_sizes[i], -1);
1036 if (font_sizes[i] * PANGO_SCALE == priv->size)
1037 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1043 gboolean found = FALSE;
1045 gtk_tree_model_get_iter_first (GTK_TREE_MODEL (model), &iter);
1046 for (i = 0; i < G_N_ELEMENTS (font_sizes) && !found; i++)
1048 if (font_sizes[i] * PANGO_SCALE == priv->size)
1050 set_cursor_to_iter (GTK_TREE_VIEW (priv->size_list), &iter);
1054 gtk_tree_model_iter_next (GTK_TREE_MODEL (model), &iter);
1059 GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->size_list));
1060 gtk_tree_selection_unselect_all (selection);
1064 /* Set the entry to the new size, rounding to 1 digit,
1065 * trimming of trailing 0's and a trailing period
1067 g_snprintf (buffer, sizeof (buffer), "%.1f", priv->size / (1.0 * PANGO_SCALE));
1068 if (strchr (buffer, '.'))
1070 p = buffer + strlen (buffer) - 1;
1078 /* Compare, to avoid moving the cursor unecessarily */
1079 if (strcmp (gtk_entry_get_text (GTK_ENTRY (priv->size_entry)), buffer) != 0)
1080 gtk_entry_set_text (GTK_ENTRY (priv->size_entry), buffer);
1084 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
1086 gtk_font_selection_load_font (fontsel);
1090 gtk_font_selection_set_size (GtkFontSelection *fontsel,
1093 GtkFontSelectionPrivate *priv = fontsel->priv;
1095 if (priv->size != new_size)
1097 priv->size = new_size;
1099 gtk_font_selection_show_available_sizes (fontsel, FALSE);
1100 gtk_font_selection_load_font (fontsel);
1104 /* If the user hits return in the font size entry, we change to the new font
1107 gtk_font_selection_size_activate (GtkWidget *w,
1110 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1111 GtkFontSelectionPrivate *priv = fontsel->priv;
1115 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1116 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1118 if (priv->size != new_size)
1119 gtk_font_selection_set_size (fontsel, new_size);
1121 list_row_activated (w);
1125 gtk_font_selection_size_focus_out (GtkWidget *w,
1126 GdkEventFocus *event,
1129 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1130 GtkFontSelectionPrivate *priv = fontsel->priv;
1134 text = gtk_entry_get_text (GTK_ENTRY (priv->size_entry));
1135 new_size = MAX (0.1, atof (text) * PANGO_SCALE + 0.5);
1137 gtk_font_selection_set_size (fontsel, new_size);
1142 /* This is called when a size is selected in the list. */
1144 gtk_font_selection_select_size (GtkTreeSelection *selection,
1147 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
1148 GtkTreeModel *model;
1152 if (gtk_tree_selection_get_selected (selection, &model, &iter))
1154 gtk_tree_model_get (model, &iter, SIZE_COLUMN, &new_size, -1);
1155 gtk_font_selection_set_size (fontsel, new_size * PANGO_SCALE);
1160 gtk_font_selection_load_font (GtkFontSelection *fontsel)
1162 gtk_font_selection_update_preview (fontsel);
1165 static PangoFontDescription *
1166 gtk_font_selection_get_font_description (GtkFontSelection *fontsel)
1168 GtkFontSelectionPrivate *priv = fontsel->priv;
1169 PangoFontDescription *font_desc;
1173 font_desc = pango_font_face_describe (priv->face);
1174 pango_font_description_set_size (font_desc, priv->size);
1177 font_desc = pango_font_description_from_string (DEFAULT_FONT_NAME);
1182 /* This sets the font in the preview entry to the selected font,
1183 * and tries to make sure that the preview entry is a reasonable
1184 * size, i.e. so that the text can be seen with a bit of space to
1185 * spare. But it tries to avoid resizing the entry every time the
1186 * font changes. This also used to shrink the preview if the font
1187 * size was decreased, but that made it awkward if the user wanted
1188 * to resize the window themself.
1191 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
1193 GtkFontSelectionPrivate *priv = fontsel->priv;
1195 GtkRequisition old_requisition, new_requisition;
1196 GtkWidget *preview_entry = priv->preview_entry;
1199 gtk_widget_get_preferred_size (preview_entry, &old_requisition, NULL);
1201 gtk_widget_override_font (preview_entry,
1202 gtk_font_selection_get_font_description (fontsel));
1204 gtk_widget_get_preferred_size (preview_entry, &new_requisition, NULL);
1206 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
1207 new_height = CLAMP (new_requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
1209 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
1210 gtk_widget_set_size_request (preview_entry, -1, new_height);
1212 /* This sets the preview text, if it hasn't been set already. */
1213 text = gtk_entry_get_text (GTK_ENTRY (preview_entry));
1214 if (strlen (text) == 0)
1215 gtk_entry_set_text (GTK_ENTRY (preview_entry), _(PREVIEW_TEXT));
1216 gtk_editable_set_position (GTK_EDITABLE (preview_entry), 0);
1220 /*****************************************************************************
1221 * These functions are the main public interface for getting/setting the font.
1222 *****************************************************************************/
1225 * gtk_font_selection_get_family_list:
1226 * @fontsel: a #GtkFontSelection
1228 * This returns the #GtkTreeView that lists font families, for
1229 * example, 'Sans', 'Serif', etc.
1231 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1236 gtk_font_selection_get_family_list (GtkFontSelection *fontsel)
1238 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1240 return fontsel->priv->family_list;
1244 * gtk_font_selection_get_face_list:
1245 * @fontsel: a #GtkFontSelection
1247 * This returns the #GtkTreeView which lists all styles available for
1248 * the selected font. For example, 'Regular', 'Bold', etc.
1250 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1255 gtk_font_selection_get_face_list (GtkFontSelection *fontsel)
1257 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1259 return fontsel->priv->face_list;
1263 * gtk_font_selection_get_size_entry:
1264 * @fontsel: a #GtkFontSelection
1266 * This returns the #GtkEntry used to allow the user to edit the font
1267 * number manually instead of selecting it from the list of font sizes.
1269 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1274 gtk_font_selection_get_size_entry (GtkFontSelection *fontsel)
1276 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1278 return fontsel->priv->size_entry;
1282 * gtk_font_selection_get_size_list:
1283 * @fontsel: a #GtkFontSelection
1285 * This returns the #GtkTreeeView used to list font sizes.
1287 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1292 gtk_font_selection_get_size_list (GtkFontSelection *fontsel)
1294 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1296 return fontsel->priv->size_list;
1300 * gtk_font_selection_get_preview_entry:
1301 * @fontsel: a #GtkFontSelection
1303 * This returns the #GtkEntry used to display the font as a preview.
1305 * Return value: (transfer none): A #GtkWidget that is part of @fontsel
1310 gtk_font_selection_get_preview_entry (GtkFontSelection *fontsel)
1312 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1314 return fontsel->priv->preview_entry;
1318 * gtk_font_selection_get_family:
1319 * @fontsel: a #GtkFontSelection
1321 * Gets the #PangoFontFamily representing the selected font family.
1323 * Return value: (transfer none): A #PangoFontFamily representing the
1324 * selected font family. Font families are a collection of font
1325 * faces. The returned object is owned by @fontsel and must not
1326 * be modified or freed.
1331 gtk_font_selection_get_family (GtkFontSelection *fontsel)
1333 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1335 return fontsel->priv->family;
1339 * gtk_font_selection_get_face:
1340 * @fontsel: a #GtkFontSelection
1342 * Gets the #PangoFontFace representing the selected font group
1343 * details (i.e. family, slant, weight, width, etc).
1345 * Return value: (transfer none): A #PangoFontFace representing the
1346 * selected font group details. The returned object is owned by
1347 * @fontsel and must not be modified or freed.
1352 gtk_font_selection_get_face (GtkFontSelection *fontsel)
1354 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1356 return fontsel->priv->face;
1360 * gtk_font_selection_get_size:
1361 * @fontsel: a #GtkFontSelection
1363 * The selected font size.
1365 * Return value: A n integer representing the selected font size,
1366 * or -1 if no font size is selected.
1371 gtk_font_selection_get_size (GtkFontSelection *fontsel)
1373 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), -1);
1375 return fontsel->priv->size;
1379 * gtk_font_selection_get_font_name:
1380 * @fontsel: a #GtkFontSelection
1382 * Gets the currently-selected font name.
1384 * Note that this can be a different string than what you set with
1385 * gtk_font_selection_set_font_name(), as the font selection widget may
1386 * normalize font names and thus return a string with a different structure.
1387 * For example, "Helvetica Italic Bold 12" could be normalized to
1388 * "Helvetica Bold Italic 12". Use pango_font_description_equal()
1389 * if you want to compare two font descriptions.
1391 * Return value: A string with the name of the current font, or %NULL if
1392 * no font is selected. You must free this string with g_free().
1395 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
1399 PangoFontDescription *font_desc = gtk_font_selection_get_font_description (fontsel);
1400 result = pango_font_description_to_string (font_desc);
1401 pango_font_description_free (font_desc);
1406 /* This selects the appropriate list rows.
1407 First we check the fontname is valid and try to find the font family
1408 - i.e. the name in the main list. If we can't find that, then just return.
1409 Next we try to set each of the properties according to the fontname.
1410 Finally we select the font family & style in the lists. */
1412 gtk_font_selection_select_font_desc (GtkFontSelection *fontsel,
1413 PangoFontDescription *new_desc,
1414 PangoFontFamily **pfamily,
1415 PangoFontFace **pface)
1417 GtkFontSelectionPrivate *priv = fontsel->priv;
1418 PangoFontFamily *new_family = NULL;
1419 PangoFontFace *new_face = NULL;
1420 PangoFontFace *fallback_face = NULL;
1421 GtkTreeModel *model;
1423 GtkTreeIter match_iter;
1425 const gchar *new_family_name;
1427 new_family_name = pango_font_description_get_family (new_desc);
1429 if (!new_family_name)
1432 /* Check to make sure that this is in the list of allowed fonts
1434 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->family_list));
1435 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1437 valid = gtk_tree_model_iter_next (model, &iter))
1439 PangoFontFamily *family;
1441 gtk_tree_model_get (model, &iter, FAMILY_COLUMN, &family, -1);
1443 if (g_ascii_strcasecmp (pango_font_family_get_name (family),
1444 new_family_name) == 0)
1445 new_family = g_object_ref (family);
1447 g_object_unref (family);
1457 *pfamily = new_family;
1459 g_object_unref (new_family);
1460 set_cursor_to_iter (GTK_TREE_VIEW (priv->family_list), &iter);
1461 gtk_font_selection_show_available_styles (fontsel);
1463 model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->face_list));
1464 for (valid = gtk_tree_model_get_iter_first (model, &iter);
1466 valid = gtk_tree_model_iter_next (model, &iter))
1468 PangoFontFace *face;
1469 PangoFontDescription *tmp_desc;
1471 gtk_tree_model_get (model, &iter, FACE_COLUMN, &face, -1);
1472 tmp_desc = pango_font_face_describe (face);
1474 if (font_description_style_equal (tmp_desc, new_desc))
1475 new_face = g_object_ref (face);
1479 fallback_face = g_object_ref (face);
1483 pango_font_description_free (tmp_desc);
1484 g_object_unref (face);
1494 new_face = fallback_face;
1495 else if (fallback_face)
1496 g_object_unref (fallback_face);
1501 g_object_unref (new_face);
1502 set_cursor_to_iter (GTK_TREE_VIEW (priv->face_list), &match_iter);
1504 gtk_font_selection_set_size (fontsel, pango_font_description_get_size (new_desc));
1510 /* This sets the current font, then selecting the appropriate list rows. */
1513 * gtk_font_selection_set_font_name:
1514 * @fontsel: a #GtkFontSelection
1515 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1517 * Sets the currently-selected font.
1519 * Note that the @fontsel needs to know the screen in which it will appear
1520 * for this to work; this can be guaranteed by simply making sure that the
1521 * @fontsel is inserted in a toplevel window before you call this function.
1523 * Return value: %TRUE if the font could be set successfully; %FALSE if no
1524 * such font exists or if the @fontsel doesn't belong to a particular
1528 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
1529 const gchar *fontname)
1531 PangoFontFamily *family = NULL;
1532 PangoFontFace *face = NULL;
1533 PangoFontDescription *new_desc;
1535 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
1537 if (!gtk_widget_has_screen (GTK_WIDGET (fontsel)))
1540 new_desc = pango_font_description_from_string (fontname);
1542 if (gtk_font_selection_select_font_desc (fontsel, new_desc, &family, &face))
1544 gtk_font_selection_ref_family (fontsel, family);
1546 g_object_unref (family);
1548 gtk_font_selection_ref_face (fontsel, face);
1550 g_object_unref (face);
1553 pango_font_description_free (new_desc);
1555 g_object_notify (G_OBJECT (fontsel), "font-name");
1561 * gtk_font_selection_get_preview_text:
1562 * @fontsel: a #GtkFontSelection
1564 * Gets the text displayed in the preview area.
1566 * Return value: the text displayed in the preview area.
1567 * This string is owned by the widget and should not be
1571 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
1573 GtkFontSelectionPrivate *priv;
1575 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), NULL);
1577 priv = fontsel->priv;
1579 return gtk_entry_get_text (GTK_ENTRY (priv->preview_entry));
1584 * gtk_font_selection_set_preview_text:
1585 * @fontsel: a #GtkFontSelection
1586 * @text: the text to display in the preview area
1588 * Sets the text displayed in the preview area.
1589 * The @text is used to show how the selected font looks.
1592 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
1595 GtkFontSelectionPrivate *priv;
1597 g_return_if_fail (GTK_IS_FONT_SELECTION (fontsel));
1598 g_return_if_fail (text != NULL);
1600 priv = fontsel->priv;
1602 gtk_entry_set_text (GTK_ENTRY (priv->preview_entry), text);
1607 * SECTION:gtkfontseldlg
1608 * @Short_description: A dialog box for selecting fonts
1609 * @Title: GtkFontSelectionDialog
1610 * @See_also: #GtkFontSelection, #GtkDialog
1612 * The #GtkFontSelectionDialog widget is a dialog box for selecting a font.
1614 * To set the font which is initially selected, use
1615 * gtk_font_selection_dialog_set_font_name().
1617 * To get the selected font use gtk_font_selection_dialog_get_font_name().
1619 * To change the text which is shown in the preview area, use
1620 * gtk_font_selection_dialog_set_preview_text().
1622 * <refsect2 id="GtkFontSelectionDialog-BUILDER-UI">
1623 * <title>GtkFontSelectionDialog as GtkBuildable</title>
1624 * The GtkFontSelectionDialog implementation of the GtkBuildable interface
1625 * exposes the embedded #GtkFontSelection as internal child with the
1626 * name "font_selection". It also exposes the buttons with the names
1627 * "ok_button", "cancel_button" and "apply_button".
1631 static void gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface);
1632 static GObject * gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1633 GtkBuilder *builder,
1634 const gchar *childname);
1636 G_DEFINE_TYPE_WITH_CODE (GtkFontSelectionDialog, gtk_font_selection_dialog,
1638 G_IMPLEMENT_INTERFACE (GTK_TYPE_BUILDABLE,
1639 gtk_font_selection_dialog_buildable_interface_init))
1641 static GtkBuildableIface *parent_buildable_iface;
1644 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
1646 g_type_class_add_private (klass, sizeof (GtkFontSelectionDialogPrivate));
1650 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
1652 GtkFontSelectionDialogPrivate *priv;
1653 GtkDialog *dialog = GTK_DIALOG (fontseldiag);
1654 GtkWidget *action_area, *content_area;
1656 fontseldiag->priv = G_TYPE_INSTANCE_GET_PRIVATE (fontseldiag,
1657 GTK_TYPE_FONT_SELECTION_DIALOG,
1658 GtkFontSelectionDialogPrivate);
1659 priv = fontseldiag->priv;
1661 content_area = gtk_dialog_get_content_area (dialog);
1662 action_area = gtk_dialog_get_action_area (dialog);
1664 gtk_container_set_border_width (GTK_CONTAINER (dialog), 5);
1665 gtk_box_set_spacing (GTK_BOX (content_area), 2); /* 2 * 5 + 2 = 12 */
1666 gtk_container_set_border_width (GTK_CONTAINER (action_area), 5);
1667 gtk_box_set_spacing (GTK_BOX (action_area), 6);
1669 gtk_widget_push_composite_child ();
1671 gtk_window_set_resizable (GTK_WINDOW (fontseldiag), TRUE);
1673 /* Create the content area */
1674 priv->fontsel = gtk_font_selection_new ();
1675 gtk_container_set_border_width (GTK_CONTAINER (priv->fontsel), 5);
1676 gtk_widget_show (priv->fontsel);
1677 gtk_box_pack_start (GTK_BOX (content_area),
1678 priv->fontsel, TRUE, TRUE, 0);
1680 /* Create the action area */
1681 priv->cancel_button = gtk_dialog_add_button (dialog,
1683 GTK_RESPONSE_CANCEL);
1685 priv->apply_button = gtk_dialog_add_button (dialog,
1687 GTK_RESPONSE_APPLY);
1688 gtk_widget_hide (priv->apply_button);
1690 priv->ok_button = gtk_dialog_add_button (dialog,
1693 gtk_widget_grab_default (priv->ok_button);
1695 gtk_dialog_set_alternative_button_order (GTK_DIALOG (fontseldiag),
1698 GTK_RESPONSE_CANCEL,
1701 gtk_window_set_title (GTK_WINDOW (fontseldiag),
1702 _("Font Selection"));
1704 gtk_widget_pop_composite_child ();
1708 * gtk_font_selection_dialog_new:
1709 * @title: the title of the dialog window
1711 * Creates a new #GtkFontSelectionDialog.
1713 * Return value: a new #GtkFontSelectionDialog
1716 gtk_font_selection_dialog_new (const gchar *title)
1718 GtkFontSelectionDialog *fontseldiag;
1720 fontseldiag = g_object_new (GTK_TYPE_FONT_SELECTION_DIALOG, NULL);
1723 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
1725 return GTK_WIDGET (fontseldiag);
1729 * gtk_font_selection_dialog_get_font_selection:
1730 * @fsd: a #GtkFontSelectionDialog
1732 * Retrieves the #GtkFontSelection widget embedded in the dialog.
1734 * Returns: (transfer none): the embedded #GtkFontSelection
1739 gtk_font_selection_dialog_get_font_selection (GtkFontSelectionDialog *fsd)
1741 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1743 return fsd->priv->fontsel;
1748 * gtk_font_selection_dialog_get_ok_button:
1749 * @fsd: a #GtkFontSelectionDialog
1751 * Gets the 'OK' button.
1753 * Return value: (transfer none): the #GtkWidget used in the dialog
1754 * for the 'OK' button.
1759 gtk_font_selection_dialog_get_ok_button (GtkFontSelectionDialog *fsd)
1761 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1763 return fsd->priv->ok_button;
1767 * gtk_font_selection_dialog_get_cancel_button:
1768 * @fsd: a #GtkFontSelectionDialog
1770 * Gets the 'Cancel' button.
1772 * Return value: (transfer none): the #GtkWidget used in the dialog
1773 * for the 'Cancel' button.
1778 gtk_font_selection_dialog_get_cancel_button (GtkFontSelectionDialog *fsd)
1780 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1782 return fsd->priv->cancel_button;
1786 gtk_font_selection_dialog_buildable_interface_init (GtkBuildableIface *iface)
1788 parent_buildable_iface = g_type_interface_peek_parent (iface);
1789 iface->get_internal_child = gtk_font_selection_dialog_buildable_get_internal_child;
1793 gtk_font_selection_dialog_buildable_get_internal_child (GtkBuildable *buildable,
1794 GtkBuilder *builder,
1795 const gchar *childname)
1797 GtkFontSelectionDialogPrivate *priv;
1799 priv = GTK_FONT_SELECTION_DIALOG (buildable)->priv;
1801 if (g_strcmp0 (childname, "ok_button") == 0)
1802 return G_OBJECT (priv->ok_button);
1803 else if (g_strcmp0 (childname, "cancel_button") == 0)
1804 return G_OBJECT (priv->cancel_button);
1805 else if (g_strcmp0 (childname, "apply_button") == 0)
1806 return G_OBJECT (priv->apply_button);
1807 else if (g_strcmp0 (childname, "font_selection") == 0)
1808 return G_OBJECT (priv->fontsel);
1810 return parent_buildable_iface->get_internal_child (buildable, builder, childname);
1814 * gtk_font_selection_dialog_get_font_name:
1815 * @fsd: a #GtkFontSelectionDialog
1817 * Gets the currently-selected font name.
1819 * Note that this can be a different string than what you set with
1820 * gtk_font_selection_dialog_set_font_name(), as the font selection widget
1821 * may normalize font names and thus return a string with a different
1822 * structure. For example, "Helvetica Italic Bold 12" could be normalized
1823 * to "Helvetica Bold Italic 12". Use pango_font_description_equal()
1824 * if you want to compare two font descriptions.
1826 * Return value: A string with the name of the current font, or %NULL if no
1827 * font is selected. You must free this string with g_free().
1830 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
1832 GtkFontSelectionDialogPrivate *priv;
1834 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1838 return gtk_font_selection_get_font_name (GTK_FONT_SELECTION (priv->fontsel));
1842 * gtk_font_selection_dialog_set_font_name:
1843 * @fsd: a #GtkFontSelectionDialog
1844 * @fontname: a font name like "Helvetica 12" or "Times Bold 18"
1846 * Sets the currently selected font.
1848 * Return value: %TRUE if the font selected in @fsd is now the
1849 * @fontname specified, %FALSE otherwise.
1852 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1853 const gchar *fontname)
1855 GtkFontSelectionDialogPrivate *priv;
1857 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), FALSE);
1858 g_return_val_if_fail (fontname, FALSE);
1862 return gtk_font_selection_set_font_name (GTK_FONT_SELECTION (priv->fontsel), fontname);
1866 * gtk_font_selection_dialog_get_preview_text:
1867 * @fsd: a #GtkFontSelectionDialog
1869 * Gets the text displayed in the preview area.
1871 * Return value: the text displayed in the preview area.
1872 * This string is owned by the widget and should not be
1876 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1878 GtkFontSelectionDialogPrivate *priv;
1880 g_return_val_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd), NULL);
1884 return gtk_font_selection_get_preview_text (GTK_FONT_SELECTION (priv->fontsel));
1888 * gtk_font_selection_dialog_set_preview_text:
1889 * @fsd: a #GtkFontSelectionDialog
1890 * @text: the text to display in the preview area
1892 * Sets the text displayed in the preview area.
1895 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1898 GtkFontSelectionDialogPrivate *priv;
1900 g_return_if_fail (GTK_IS_FONT_SELECTION_DIALOG (fsd));
1901 g_return_if_fail (text != NULL);
1905 gtk_font_selection_set_preview_text (GTK_FONT_SELECTION (priv->fontsel), text);