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/.
38 #include "gdk/gdkkeysyms.h"
40 #include "gtkfontsel.h"
42 #include "gtkbutton.h"
50 #include "gtksignal.h"
54 #include "gtkscrolledwindow.h"
57 /* This is the default text shown in the preview entry, though the user
58 can set it. Remember that some fonts only have capital letters. */
59 #define PREVIEW_TEXT "abcdefghijk ABCDEFGHIJK"
61 /* This is the initial and maximum height of the preview entry (it expands
62 when large font sizes are selected). Initial height is also the minimum. */
63 #define INITIAL_PREVIEW_HEIGHT 44
64 #define MAX_PREVIEW_HEIGHT 300
66 /* These are the sizes of the font, style & size clists. */
67 #define FONT_LIST_HEIGHT 136
68 #define FONT_LIST_WIDTH 190
69 #define FONT_STYLE_LIST_WIDTH 170
70 #define FONT_SIZE_LIST_WIDTH 60
72 /* These are what we use as the standard font sizes, for the size clist.
74 static const guint16 font_sizes[] = {
75 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 26, 28,
76 32, 36, 40, 48, 56, 64, 72
79 static void gtk_font_selection_class_init (GtkFontSelectionClass *klass);
80 static void gtk_font_selection_init (GtkFontSelection *fontsel);
81 static void gtk_font_selection_finalize (GObject *object);
83 /* These are the callbacks & related functions. */
84 static void gtk_font_selection_select_font (GtkWidget *w,
87 GdkEventButton *bevent,
89 static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs);
91 static void gtk_font_selection_show_available_styles (GtkFontSelection *fs);
92 static void gtk_font_selection_select_best_style (GtkFontSelection *fs,
94 static void gtk_font_selection_select_style (GtkWidget *w,
97 GdkEventButton *bevent,
100 static void gtk_font_selection_select_best_size (GtkFontSelection *fs);
101 static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs);
102 static void gtk_font_selection_size_activate (GtkWidget *w,
104 static void gtk_font_selection_select_size (GtkWidget *w,
107 GdkEventButton *bevent,
110 static void gtk_font_selection_expose_list (GtkWidget *w,
111 GdkEventExpose *event,
115 /* Misc. utility functions. */
116 static void gtk_font_selection_load_font (GtkFontSelection *fs);
117 static void gtk_font_selection_update_preview (GtkFontSelection *fs);
119 /* FontSelectionDialog */
120 static void gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass);
121 static void gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag);
123 static gint gtk_font_selection_dialog_on_configure(GtkWidget *widget,
124 GdkEventConfigure *event,
125 GtkFontSelectionDialog *fsd);
127 static GtkWindowClass *font_selection_parent_class = NULL;
128 static GtkVBoxClass *font_selection_dialog_parent_class = NULL;
131 gtk_font_selection_get_type()
133 static GtkType font_selection_type = 0;
135 if(!font_selection_type)
137 static const GtkTypeInfo fontsel_type_info =
140 sizeof (GtkFontSelection),
141 sizeof (GtkFontSelectionClass),
142 (GtkClassInitFunc) gtk_font_selection_class_init,
143 (GtkObjectInitFunc) gtk_font_selection_init,
144 /* reserved_1 */ NULL,
145 /* reserved_2 */ NULL,
146 (GtkClassInitFunc) NULL,
149 font_selection_type = gtk_type_unique (GTK_TYPE_VBOX,
153 return font_selection_type;
157 gtk_font_selection_class_init(GtkFontSelectionClass *klass)
159 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
161 font_selection_parent_class = gtk_type_class (GTK_TYPE_VBOX);
163 gobject_class->finalize = gtk_font_selection_finalize;
167 gtk_font_selection_init(GtkFontSelection *fontsel)
169 GtkWidget *scrolled_win;
170 GtkWidget *text_frame;
172 GtkWidget *table, *label;
174 fontsel->font_desc = pango_font_description_from_string ("sans 12");
176 /* Create the table of font, style & size. */
177 table = gtk_table_new (3, 3, FALSE);
178 gtk_widget_show (table);
179 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
180 gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
182 fontsel->font_entry = gtk_entry_new ();
183 gtk_entry_set_editable(GTK_ENTRY(fontsel->font_entry), FALSE);
184 gtk_widget_set_usize (fontsel->font_entry, 20, -1);
185 gtk_widget_show (fontsel->font_entry);
186 gtk_table_attach (GTK_TABLE (table), fontsel->font_entry, 0, 1, 1, 2,
189 fontsel->font_style_entry = gtk_entry_new ();
190 gtk_entry_set_editable (GTK_ENTRY(fontsel->font_style_entry), FALSE);
191 gtk_widget_set_usize (fontsel->font_style_entry, 20, -1);
192 gtk_widget_show (fontsel->font_style_entry);
193 gtk_table_attach (GTK_TABLE (table), fontsel->font_style_entry, 1, 2, 1, 2,
196 fontsel->size_entry = gtk_entry_new ();
197 gtk_widget_set_usize (fontsel->size_entry, 20, -1);
198 gtk_widget_show (fontsel->size_entry);
199 gtk_table_attach (GTK_TABLE (table), fontsel->size_entry, 2, 3, 1, 2,
201 gtk_signal_connect (GTK_OBJECT (fontsel->size_entry), "activate",
202 (GtkSignalFunc) gtk_font_selection_size_activate,
205 fontsel->font_label = gtk_label_new_with_mnemonic (_("_Family:"));
206 gtk_label_set_mnemonic_widget (GTK_LABEL (fontsel->font_label),
207 fontsel->font_entry);
208 gtk_misc_set_alignment (GTK_MISC (fontsel->font_label), 0.0, 0.5);
209 gtk_widget_show (fontsel->font_label);
210 gtk_table_attach (GTK_TABLE (table), fontsel->font_label, 0, 1, 0, 1,
212 label = gtk_label_new_with_mnemonic (_("_Style:"));
213 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
214 fontsel->font_style_entry);
215 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
216 gtk_widget_show (label);
217 gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
219 label = gtk_label_new_with_mnemonic (_("Si_ze:"));
220 gtk_label_set_mnemonic_widget (GTK_LABEL (label),
221 fontsel->size_entry);
222 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
223 gtk_widget_show (label);
224 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
228 /* Create the clists */
229 fontsel->font_clist = gtk_clist_new (1);
230 gtk_clist_column_titles_hide (GTK_CLIST (fontsel->font_clist));
231 gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_clist), 0, TRUE);
232 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
233 gtk_widget_set_usize (scrolled_win, FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
234 gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->font_clist);
235 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
236 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
237 gtk_widget_show(fontsel->font_clist);
238 gtk_widget_show(scrolled_win);
240 gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 2, 3,
241 GTK_EXPAND | GTK_FILL,
242 GTK_EXPAND | GTK_FILL, 0, 0);
244 fontsel->font_style_clist = gtk_clist_new (1);
245 gtk_clist_column_titles_hide (GTK_CLIST (fontsel->font_style_clist));
246 gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_style_clist),
248 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
249 gtk_widget_set_usize (scrolled_win, FONT_STYLE_LIST_WIDTH, -1);
250 gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->font_style_clist);
251 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
252 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
253 gtk_widget_show(fontsel->font_style_clist);
254 gtk_widget_show(scrolled_win);
255 gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 2, 3,
256 GTK_EXPAND | GTK_FILL,
257 GTK_EXPAND | GTK_FILL, 0, 0);
259 fontsel->size_clist = gtk_clist_new (1);
260 gtk_clist_column_titles_hide (GTK_CLIST(fontsel->size_clist));
261 gtk_clist_set_column_width (GTK_CLIST(fontsel->size_clist), 0, 20);
262 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
263 gtk_widget_set_usize (scrolled_win, FONT_SIZE_LIST_WIDTH, -1);
264 gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->size_clist);
265 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
266 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
267 gtk_widget_show (fontsel->size_clist);
268 gtk_widget_show (scrolled_win);
269 gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
270 GTK_FILL, GTK_FILL, 0, 0);
272 /* Insert the fonts. If there exist fonts with the same family but
273 different foundries, then the foundry name is appended in brackets. */
274 gtk_font_selection_show_available_fonts(fontsel);
276 gtk_signal_connect (GTK_OBJECT (fontsel->font_clist), "select_row",
277 GTK_SIGNAL_FUNC(gtk_font_selection_select_font),
279 GTK_WIDGET_SET_FLAGS (fontsel->font_clist, GTK_CAN_FOCUS);
281 gtk_signal_connect_after (GTK_OBJECT (fontsel->font_clist), "expose_event",
282 GTK_SIGNAL_FUNC(gtk_font_selection_expose_list),
285 gtk_font_selection_show_available_styles (fontsel);
287 gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist), "select_row",
288 GTK_SIGNAL_FUNC(gtk_font_selection_select_style),
290 GTK_WIDGET_SET_FLAGS (fontsel->font_style_clist, GTK_CAN_FOCUS);
292 gtk_font_selection_show_available_sizes (fontsel);
294 gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "select_row",
295 GTK_SIGNAL_FUNC(gtk_font_selection_select_size),
297 GTK_WIDGET_SET_FLAGS (fontsel->size_clist, GTK_CAN_FOCUS);
299 /* create the text entry widget */
300 text_frame = gtk_frame_new (_("Preview:"));
301 gtk_widget_show (text_frame);
302 gtk_frame_set_shadow_type(GTK_FRAME(text_frame), GTK_SHADOW_ETCHED_IN);
303 gtk_box_pack_start (GTK_BOX (fontsel), text_frame,
306 /* This is just used to get a 4-pixel space around the preview entry. */
307 text_box = gtk_hbox_new (FALSE, 0);
308 gtk_widget_show (text_box);
309 gtk_container_add (GTK_CONTAINER (text_frame), text_box);
310 gtk_container_set_border_width (GTK_CONTAINER (text_box), 4);
312 fontsel->preview_entry = gtk_entry_new ();
313 gtk_widget_show (fontsel->preview_entry);
314 gtk_widget_set_usize (fontsel->preview_entry, -1, INITIAL_PREVIEW_HEIGHT);
315 gtk_box_pack_start (GTK_BOX (text_box), fontsel->preview_entry,
318 gtk_font_selection_update_preview (fontsel);
322 gtk_font_selection_new()
324 GtkFontSelection *fontsel;
326 fontsel = gtk_type_new (GTK_TYPE_FONT_SELECTION);
328 return GTK_WIDGET (fontsel);
332 gtk_font_selection_finalize (GObject *object)
334 GtkFontSelection *fontsel;
336 g_return_if_fail (object != NULL);
337 g_return_if_fail (GTK_IS_FONT_SELECTION (object));
339 fontsel = GTK_FONT_SELECTION (object);
341 pango_font_description_free (fontsel->font_desc);
344 gdk_font_unref (fontsel->font);
346 if (G_OBJECT_CLASS (font_selection_parent_class)->finalize)
347 (* G_OBJECT_CLASS (font_selection_parent_class)->finalize) (object);
351 /* This is called when the clist is exposed. Here we scroll to the current
352 font if necessary. */
354 gtk_font_selection_expose_list (GtkWidget *widget,
355 GdkEventExpose *event,
358 GtkFontSelection *fontsel;
363 g_message("In expose_list\n");
365 fontsel = GTK_FONT_SELECTION(data);
367 /* Try to scroll the font family clist to the selected item */
368 selection = GTK_CLIST(fontsel->font_clist)->selection;
371 index = GPOINTER_TO_INT (selection->data);
372 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_clist), index)
373 != GTK_VISIBILITY_FULL)
374 gtk_clist_moveto(GTK_CLIST(fontsel->font_clist), index, -1, 0.5, 0);
377 /* Try to scroll the font style clist to the selected item */
378 selection = GTK_CLIST(fontsel->font_style_clist)->selection;
381 index = GPOINTER_TO_INT (selection->data);
382 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_style_clist), index)
383 != GTK_VISIBILITY_FULL)
384 gtk_clist_moveto(GTK_CLIST(fontsel->font_style_clist), index, -1,
388 /* Try to scroll the font size clist to the selected item */
389 selection = GTK_CLIST(fontsel->size_clist)->selection;
392 index = GPOINTER_TO_INT (selection->data);
393 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->size_clist), index)
394 != GTK_VISIBILITY_FULL)
395 gtk_clist_moveto(GTK_CLIST(fontsel->size_clist), index, -1, 0.5, 0);
399 /* This is called when a family is selected in the list. */
401 gtk_font_selection_select_font (GtkWidget *w,
404 GdkEventButton *bevent,
407 GtkFontSelection *fontsel;
411 fontsel = GTK_FONT_SELECTION (data);
413 if (GTK_CLIST (fontsel->font_clist)->selection)
415 index = GPOINTER_TO_INT (GTK_CLIST (fontsel->font_clist)->selection->data);
417 if (gtk_clist_get_text (GTK_CLIST (fontsel->font_clist), index, 0, &family_name) &&
418 strcasecmp (fontsel->font_desc->family_name, family_name) != 0)
420 g_free (fontsel->font_desc->family_name);
421 fontsel->font_desc->family_name = g_strdup (family_name);
423 gtk_entry_set_text (GTK_ENTRY (fontsel->font_entry), family_name);
425 gtk_font_selection_show_available_styles (fontsel);
426 gtk_font_selection_select_best_style (fontsel, TRUE);
432 cmp_strings (const void *a, const void *b)
434 return strcasecmp (*(const char **)a, *(const char **)b);
438 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
443 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
444 &families, &n_families);
445 qsort (families, n_families, sizeof(char *), cmp_strings);
447 gtk_clist_freeze (GTK_CLIST (fontsel->font_clist));
448 gtk_clist_clear (GTK_CLIST (fontsel->font_clist));
450 for (i=0; i<n_families; i++)
452 gtk_clist_append (GTK_CLIST (fontsel->font_clist), &families[i]);
454 if (!strcasecmp (families[i], fontsel->font_desc->family_name))
456 gtk_clist_select_row (GTK_CLIST(fontsel->font_clist), i, 0);
457 gtk_entry_set_text(GTK_ENTRY(fontsel->font_entry), families[i]);
461 gtk_clist_thaw (GTK_CLIST(fontsel->font_clist));
463 pango_font_map_free_families (families, n_families);
467 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
469 int val = strcasecmp (a->family_name, b->family_name);
473 if (a->weight != b->weight)
474 return a->weight - b->weight;
476 if (a->style != b->style)
477 return a->style - b->style;
479 if (a->stretch != b->stretch)
480 return a->stretch - b->stretch;
482 if (a->variant != b->variant)
483 return a->variant - b->variant;
489 font_description_sort_func (const void *a, const void *b)
491 return compare_font_descriptions (*(PangoFontDescription **)a, *(PangoFontDescription **)b);
494 /* This fills the font style clist with all the possible style combinations
495 for the current font family. */
497 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
499 PangoFontDescription **descs;
504 pango_context_list_fonts (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
505 fontsel->font_desc->family_name, &descs, &n_descs);
506 qsort (descs, n_descs, sizeof(PangoFontDescription *), font_description_sort_func);
508 gtk_clist_freeze (GTK_CLIST (fontsel->font_style_clist));
509 gtk_clist_clear (GTK_CLIST (fontsel->font_style_clist));
511 for (i=0; i<n_descs; i++)
513 PangoFontDescription tmp_desc;
515 tmp_desc = *descs[i];
516 tmp_desc.family_name = NULL;
519 str = pango_font_description_to_string (&tmp_desc);
520 gtk_clist_append (GTK_CLIST (fontsel->font_style_clist), &str);
522 if (descs[i]->weight == fontsel->font_desc->weight &&
523 descs[i]->style == fontsel->font_desc->style &&
524 descs[i]->stretch == fontsel->font_desc->stretch &&
525 descs[i]->variant == fontsel->font_desc->variant)
531 gtk_clist_select_row (GTK_CLIST (fontsel->font_style_clist), match_row, 0);
534 gtk_clist_get_text (GTK_CLIST (fontsel->font_style_clist), match_row, 0, &str);
535 gtk_entry_set_text (GTK_ENTRY (fontsel->font_style_entry), str);
538 gtk_clist_thaw (GTK_CLIST(fontsel->font_style_clist));
540 pango_font_descriptions_free (descs, n_descs);
544 /* This selects a style when the user selects a font. It just uses the first
545 available style at present. I was thinking of trying to maintain the
546 selected style, e.g. bold italic, when the user selects different fonts.
547 However, the interface is so easy to use now I'm not sure it's worth it.
548 Note: This will load a font. */
550 gtk_font_selection_select_best_style(GtkFontSelection *fontsel,
555 gtk_clist_select_row(GTK_CLIST(fontsel->font_style_clist), best_row, 0);
556 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_style_clist), best_row)
557 != GTK_VISIBILITY_FULL)
558 gtk_clist_moveto(GTK_CLIST(fontsel->font_style_clist), best_row, -1,
560 gtk_font_selection_show_available_sizes (fontsel);
561 gtk_font_selection_select_best_size (fontsel);
565 /* This is called when a style is selected in the list. */
567 gtk_font_selection_select_style (GtkWidget *w,
570 GdkEventButton *bevent,
573 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
574 PangoFontDescription *tmp_desc;
578 if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
579 gtk_widget_grab_focus (w);
581 if (GTK_CLIST (fontsel->font_style_clist)->selection)
583 index = GPOINTER_TO_INT (GTK_CLIST (fontsel->font_style_clist)->selection->data);
585 if (gtk_clist_get_text (GTK_CLIST (fontsel->font_style_clist), index, 0, &text))
587 tmp_desc = pango_font_description_from_string (text);
589 fontsel->font_desc->style = tmp_desc->style;
590 fontsel->font_desc->variant = tmp_desc->variant;
591 fontsel->font_desc->weight = tmp_desc->weight;
592 fontsel->font_desc->stretch = tmp_desc->stretch;
594 pango_font_description_free (tmp_desc);
598 gtk_font_selection_show_available_sizes (fontsel);
599 gtk_font_selection_select_best_size (fontsel);
603 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel)
609 /* Insert the standard font sizes */
610 gtk_clist_freeze (GTK_CLIST (fontsel->size_clist));
611 gtk_clist_clear (GTK_CLIST (fontsel->size_clist));
613 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
615 sprintf(buffer, "%i", font_sizes[i]);
617 gtk_clist_append (GTK_CLIST(fontsel->size_clist), &size);
618 if (font_sizes[i] * PANGO_SCALE == fontsel->font_desc->size)
619 gtk_clist_select_row(GTK_CLIST(fontsel->size_clist), i, 0);
621 gtk_clist_thaw (GTK_CLIST(fontsel->size_clist));
623 sprintf (buffer, "%i", fontsel->font_desc->size / PANGO_SCALE);
624 gtk_entry_set_text (GTK_ENTRY(fontsel->size_entry), buffer);
628 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
630 gtk_font_selection_load_font (fontsel);
633 /* If the user hits return in the font size entry, we change to the new font
636 gtk_font_selection_size_activate (GtkWidget *w,
639 GtkFontSelection *fontsel;
643 fontsel = GTK_FONT_SELECTION (data);
645 text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry));
646 new_size = atoi (text) * PANGO_SCALE;
648 if (fontsel->font_desc->size != new_size)
650 fontsel->font_desc->size = new_size;
651 gtk_font_selection_load_font (fontsel);
655 /* This is called when a size is selected in the list. */
657 gtk_font_selection_select_size (GtkWidget *w,
660 GdkEventButton *bevent,
663 GtkFontSelection *fontsel;
667 fontsel = GTK_FONT_SELECTION (data);
669 if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
670 gtk_widget_grab_focus (w);
672 gtk_clist_get_text(GTK_CLIST(fontsel->size_clist), row, 0, &text);
673 new_size = atoi (text) * PANGO_SCALE;
675 if (fontsel->font_desc->size != new_size)
677 /* If the size was selected by the user we set the selected_size. */
678 fontsel->font_desc->size = new_size;
680 gtk_font_selection_load_font (fontsel);
685 gtk_font_selection_load_font (GtkFontSelection *fontsel)
688 gdk_font_unref (fontsel->font);
689 fontsel->font = NULL;
691 gtk_font_selection_update_preview (fontsel);
694 /* This sets the font in the preview entry to the selected font, and tries to
695 make sure that the preview entry is a reasonable size, i.e. so that the
696 text can be seen with a bit of space to spare. But it tries to avoid
697 resizing the entry every time the font changes.
698 This also used to shrink the preview if the font size was decreased, but
699 that made it awkward if the user wanted to resize the window themself. */
701 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
703 GtkRcStyle *rc_style;
705 GtkRequisition old_requisition;
706 GtkWidget *preview_entry = fontsel->preview_entry;
709 gtk_widget_get_child_requisition (preview_entry, &old_requisition);
711 rc_style = gtk_rc_style_new ();
712 rc_style->font_desc = pango_font_description_copy (fontsel->font_desc);
713 gtk_widget_modify_style (preview_entry, rc_style);
714 gtk_rc_style_unref (rc_style);
716 gtk_widget_size_request (preview_entry, NULL);
718 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
719 new_height = CLAMP (preview_entry->requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
721 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
722 gtk_widget_set_usize(preview_entry, -1, new_height);
724 /* This sets the preview text, if it hasn't been set already. */
725 text = gtk_entry_get_text(GTK_ENTRY(preview_entry));
726 if (strlen(text) == 0)
727 gtk_entry_set_text(GTK_ENTRY(preview_entry), PREVIEW_TEXT);
728 gtk_entry_set_position(GTK_ENTRY(preview_entry), 0);
731 /*****************************************************************************
732 * These functions are the main public interface for getting/setting the font.
733 *****************************************************************************/
736 gtk_font_selection_get_font (GtkFontSelection *fontsel)
739 fontsel->font = gdk_font_from_description (fontsel->font_desc);
741 return fontsel->font;
746 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
748 return pango_font_description_to_string (fontsel->font_desc);
752 /* This sets the current font, selecting the appropriate clist rows.
753 First we check the fontname is valid and try to find the font family
754 - i.e. the name in the main list. If we can't find that, then just return.
755 Next we try to set each of the properties according to the fontname.
756 Finally we select the font family & style in the clists. */
758 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
759 const gchar *fontname)
761 PangoFontDescription *new_desc;
762 PangoFontDescription **descs;
764 gboolean found = FALSE;
766 g_return_val_if_fail (fontsel != NULL, FALSE);
767 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
769 new_desc = pango_font_description_from_string (fontname);
771 /* Check to make sure that this is in the list of allowed fonts */
773 pango_context_list_fonts (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
774 new_desc->family_name, &descs, &n_descs);
776 for (i=0; i<n_descs; i++)
778 if (descs[i]->weight == new_desc->weight &&
779 descs[i]->style == new_desc->style &&
780 descs[i]->stretch == new_desc->stretch &&
781 descs[i]->variant == new_desc->variant)
788 pango_font_descriptions_free (descs, n_descs);
793 pango_font_description_free (fontsel->font_desc);
794 fontsel->font_desc = new_desc;
800 /* This returns the text in the preview entry. You should copy the returned
801 text if you need it. */
803 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
805 return gtk_entry_get_text (GTK_ENTRY (fontsel->preview_entry));
809 /* This sets the text in the preview entry. */
811 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
814 gtk_entry_set_text (GTK_ENTRY (fontsel->preview_entry), text);
817 /*****************************************************************************
818 * GtkFontSelectionDialog
819 *****************************************************************************/
822 gtk_font_selection_dialog_get_type (void)
824 static guint font_selection_dialog_type = 0;
826 if (!font_selection_dialog_type)
828 GtkTypeInfo fontsel_diag_info =
830 "GtkFontSelectionDialog",
831 sizeof (GtkFontSelectionDialog),
832 sizeof (GtkFontSelectionDialogClass),
833 (GtkClassInitFunc) gtk_font_selection_dialog_class_init,
834 (GtkObjectInitFunc) gtk_font_selection_dialog_init,
835 /* reserved_1 */ NULL,
836 /* reserved_2 */ NULL,
837 (GtkClassInitFunc) NULL,
840 font_selection_dialog_type = gtk_type_unique (GTK_TYPE_DIALOG,
844 return font_selection_dialog_type;
848 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
850 GtkObjectClass *object_class;
852 object_class = (GtkObjectClass*) klass;
854 font_selection_dialog_parent_class = gtk_type_class (GTK_TYPE_DIALOG);
858 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
862 dialog = GTK_DIALOG (fontseldiag);
864 fontseldiag->dialog_width = -1;
865 fontseldiag->auto_resize = TRUE;
867 gtk_widget_set_events(GTK_WIDGET(fontseldiag), GDK_STRUCTURE_MASK);
868 gtk_signal_connect (GTK_OBJECT (fontseldiag), "configure_event",
869 (GtkSignalFunc) gtk_font_selection_dialog_on_configure,
872 gtk_container_set_border_width (GTK_CONTAINER (fontseldiag), 4);
873 gtk_window_set_policy(GTK_WINDOW(fontseldiag), FALSE, TRUE, TRUE);
875 fontseldiag->main_vbox = dialog->vbox;
877 fontseldiag->fontsel = gtk_font_selection_new();
878 gtk_container_set_border_width (GTK_CONTAINER (fontseldiag->fontsel), 4);
879 gtk_widget_show (fontseldiag->fontsel);
880 gtk_box_pack_start (GTK_BOX (fontseldiag->main_vbox),
881 fontseldiag->fontsel, TRUE, TRUE, 0);
883 /* Create the action area */
884 fontseldiag->action_area = dialog->action_area;
886 fontseldiag->ok_button = gtk_dialog_add_button (dialog,
889 gtk_widget_grab_default (fontseldiag->ok_button);
891 fontseldiag->apply_button = gtk_dialog_add_button (dialog,
892 GTK_STOCK_BUTTON_APPLY,
894 gtk_widget_hide (fontseldiag->apply_button);
897 fontseldiag->cancel_button = gtk_dialog_add_button (dialog,
898 GTK_STOCK_BUTTON_CANCEL,
899 GTK_RESPONSE_CANCEL);
901 gtk_window_set_title (GTK_WINDOW (fontseldiag),
902 _("Font Selection"));
907 gtk_font_selection_dialog_new (const gchar *title)
909 GtkFontSelectionDialog *fontseldiag;
911 fontseldiag = gtk_type_new (GTK_TYPE_FONT_SELECTION_DIALOG);
914 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
916 return GTK_WIDGET (fontseldiag);
920 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
922 return gtk_font_selection_get_font_name(GTK_FONT_SELECTION(fsd->fontsel));
926 gtk_font_selection_dialog_get_font (GtkFontSelectionDialog *fsd)
928 return gtk_font_selection_get_font(GTK_FONT_SELECTION(fsd->fontsel));
932 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
933 const gchar *fontname)
935 return gtk_font_selection_set_font_name(GTK_FONT_SELECTION(fsd->fontsel),
940 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
942 return gtk_font_selection_get_preview_text(GTK_FONT_SELECTION(fsd->fontsel));
946 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
949 gtk_font_selection_set_preview_text(GTK_FONT_SELECTION(fsd->fontsel), text);
953 /* This turns auto-shrink off if the user resizes the width of the dialog.
954 It also turns it back on again if the user resizes it back to its normal
957 gtk_font_selection_dialog_on_configure (GtkWidget *widget,
958 GdkEventConfigure *event,
959 GtkFontSelectionDialog *fsd)
961 /* This sets the initial width. */
962 if (fsd->dialog_width == -1)
963 fsd->dialog_width = event->width;
964 else if (fsd->auto_resize && fsd->dialog_width != event->width)
966 fsd->auto_resize = FALSE;
967 gtk_window_set_policy(GTK_WINDOW(fsd), FALSE, TRUE, FALSE);
969 else if (!fsd->auto_resize && fsd->dialog_width == event->width)
971 fsd->auto_resize = TRUE;
972 gtk_window_set_policy(GTK_WINDOW(fsd), FALSE, TRUE, TRUE);