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 gint gtk_font_selection_on_clist_key_press (GtkWidget *clist,
91 GtkFontSelection *fs);
92 static gboolean gtk_font_selection_select_next (GtkFontSelection *fs,
96 static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs);
98 static void gtk_font_selection_show_available_styles (GtkFontSelection *fs);
99 static void gtk_font_selection_select_best_style (GtkFontSelection *fs,
101 static void gtk_font_selection_select_style (GtkWidget *w,
104 GdkEventButton *bevent,
107 static void gtk_font_selection_select_best_size (GtkFontSelection *fs);
108 static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs);
109 static gint gtk_font_selection_size_key_press (GtkWidget *w,
112 static void gtk_font_selection_select_size (GtkWidget *w,
115 GdkEventButton *bevent,
118 static void gtk_font_selection_expose_list (GtkWidget *w,
119 GdkEventExpose *event,
123 /* Misc. utility functions. */
124 static void gtk_font_selection_load_font (GtkFontSelection *fs);
125 static void gtk_font_selection_update_preview (GtkFontSelection *fs);
127 /* FontSelectionDialog */
128 static void gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass);
129 static void gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag);
131 static gint gtk_font_selection_dialog_on_configure(GtkWidget *widget,
132 GdkEventConfigure *event,
133 GtkFontSelectionDialog *fsd);
135 static GtkWindowClass *font_selection_parent_class = NULL;
136 static GtkVBoxClass *font_selection_dialog_parent_class = NULL;
139 gtk_font_selection_get_type()
141 static GtkType font_selection_type = 0;
143 if(!font_selection_type)
145 static const GtkTypeInfo fontsel_type_info =
148 sizeof (GtkFontSelection),
149 sizeof (GtkFontSelectionClass),
150 (GtkClassInitFunc) gtk_font_selection_class_init,
151 (GtkObjectInitFunc) gtk_font_selection_init,
152 /* reserved_1 */ NULL,
153 /* reserved_2 */ NULL,
154 (GtkClassInitFunc) NULL,
157 font_selection_type = gtk_type_unique (GTK_TYPE_VBOX,
161 return font_selection_type;
165 gtk_font_selection_class_init(GtkFontSelectionClass *klass)
167 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
169 font_selection_parent_class = gtk_type_class (GTK_TYPE_VBOX);
171 gobject_class->finalize = gtk_font_selection_finalize;
175 gtk_font_selection_init(GtkFontSelection *fontsel)
177 GtkWidget *scrolled_win;
178 GtkWidget *text_frame;
180 GtkWidget *table, *label;
182 fontsel->font_desc = pango_font_description_from_string ("sans 12");
184 /* Create the table of font, style & size. */
185 table = gtk_table_new (3, 3, FALSE);
186 gtk_widget_show (table);
187 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
188 gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
190 fontsel->font_label = gtk_label_new(_("Family:"));
191 gtk_misc_set_alignment (GTK_MISC (fontsel->font_label), 0.0, 0.5);
192 gtk_widget_show (fontsel->font_label);
193 gtk_table_attach (GTK_TABLE (table), fontsel->font_label, 0, 1, 0, 1,
195 label = gtk_label_new(_("Style:"));
196 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
197 gtk_widget_show (label);
198 gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
200 label = gtk_label_new(_("Size:"));
201 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
202 gtk_widget_show (label);
203 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
206 fontsel->font_entry = gtk_entry_new ();
207 gtk_entry_set_editable(GTK_ENTRY(fontsel->font_entry), FALSE);
208 gtk_widget_set_usize (fontsel->font_entry, 20, -1);
209 gtk_widget_show (fontsel->font_entry);
210 gtk_table_attach (GTK_TABLE (table), fontsel->font_entry, 0, 1, 1, 2,
213 fontsel->font_style_entry = gtk_entry_new ();
214 gtk_entry_set_editable (GTK_ENTRY(fontsel->font_style_entry), FALSE);
215 gtk_widget_set_usize (fontsel->font_style_entry, 20, -1);
216 gtk_widget_show (fontsel->font_style_entry);
217 gtk_table_attach (GTK_TABLE (table), fontsel->font_style_entry, 1, 2, 1, 2,
220 fontsel->size_entry = gtk_entry_new ();
221 gtk_widget_set_usize (fontsel->size_entry, 20, -1);
222 gtk_widget_show (fontsel->size_entry);
223 gtk_table_attach (GTK_TABLE (table), fontsel->size_entry, 2, 3, 1, 2,
225 gtk_signal_connect (GTK_OBJECT (fontsel->size_entry), "key_press_event",
226 (GtkSignalFunc) gtk_font_selection_size_key_press,
229 /* Create the clists */
230 fontsel->font_clist = gtk_clist_new (1);
231 gtk_clist_column_titles_hide (GTK_CLIST (fontsel->font_clist));
232 gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_clist), 0, TRUE);
233 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
234 gtk_widget_set_usize (scrolled_win, FONT_LIST_WIDTH, FONT_LIST_HEIGHT);
235 gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->font_clist);
236 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
237 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
238 gtk_widget_show(fontsel->font_clist);
239 gtk_widget_show(scrolled_win);
241 gtk_table_attach (GTK_TABLE (table), scrolled_win, 0, 1, 2, 3,
242 GTK_EXPAND | GTK_FILL,
243 GTK_EXPAND | GTK_FILL, 0, 0);
245 fontsel->font_style_clist = gtk_clist_new (1);
246 gtk_clist_column_titles_hide (GTK_CLIST (fontsel->font_style_clist));
247 gtk_clist_set_column_auto_resize (GTK_CLIST (fontsel->font_style_clist),
249 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
250 gtk_widget_set_usize (scrolled_win, FONT_STYLE_LIST_WIDTH, -1);
251 gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->font_style_clist);
252 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
253 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
254 gtk_widget_show(fontsel->font_style_clist);
255 gtk_widget_show(scrolled_win);
256 gtk_table_attach (GTK_TABLE (table), scrolled_win, 1, 2, 2, 3,
257 GTK_EXPAND | GTK_FILL,
258 GTK_EXPAND | GTK_FILL, 0, 0);
260 fontsel->size_clist = gtk_clist_new (1);
261 gtk_clist_column_titles_hide (GTK_CLIST(fontsel->size_clist));
262 gtk_clist_set_column_width (GTK_CLIST(fontsel->size_clist), 0, 20);
263 scrolled_win = gtk_scrolled_window_new (NULL, NULL);
264 gtk_widget_set_usize (scrolled_win, FONT_SIZE_LIST_WIDTH, -1);
265 gtk_container_add (GTK_CONTAINER (scrolled_win), fontsel->size_clist);
266 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win),
267 GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
268 gtk_widget_show (fontsel->size_clist);
269 gtk_widget_show (scrolled_win);
270 gtk_table_attach (GTK_TABLE (table), scrolled_win, 2, 3, 2, 3,
271 GTK_FILL, GTK_FILL, 0, 0);
273 /* Insert the fonts. If there exist fonts with the same family but
274 different foundries, then the foundry name is appended in brackets. */
275 gtk_font_selection_show_available_fonts(fontsel);
277 gtk_signal_connect (GTK_OBJECT (fontsel->font_clist), "select_row",
278 GTK_SIGNAL_FUNC(gtk_font_selection_select_font),
280 GTK_WIDGET_SET_FLAGS (fontsel->font_clist, GTK_CAN_FOCUS);
281 gtk_signal_connect (GTK_OBJECT (fontsel->font_clist), "key_press_event",
282 GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
284 gtk_signal_connect_after (GTK_OBJECT (fontsel->font_clist), "expose_event",
285 GTK_SIGNAL_FUNC(gtk_font_selection_expose_list),
288 gtk_font_selection_show_available_styles (fontsel);
290 gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist), "select_row",
291 GTK_SIGNAL_FUNC(gtk_font_selection_select_style),
293 GTK_WIDGET_SET_FLAGS (fontsel->font_style_clist, GTK_CAN_FOCUS);
294 gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist),
296 GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
299 gtk_font_selection_show_available_sizes (fontsel);
301 gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "select_row",
302 GTK_SIGNAL_FUNC(gtk_font_selection_select_size),
304 GTK_WIDGET_SET_FLAGS (fontsel->size_clist, GTK_CAN_FOCUS);
305 gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "key_press_event",
306 GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
309 /* create the text entry widget */
310 text_frame = gtk_frame_new (_("Preview:"));
311 gtk_widget_show (text_frame);
312 gtk_frame_set_shadow_type(GTK_FRAME(text_frame), GTK_SHADOW_ETCHED_IN);
313 gtk_box_pack_start (GTK_BOX (fontsel), text_frame,
316 /* This is just used to get a 4-pixel space around the preview entry. */
317 text_box = gtk_hbox_new (FALSE, 0);
318 gtk_widget_show (text_box);
319 gtk_container_add (GTK_CONTAINER (text_frame), text_box);
320 gtk_container_set_border_width (GTK_CONTAINER (text_box), 4);
322 fontsel->preview_entry = gtk_entry_new ();
323 gtk_widget_show (fontsel->preview_entry);
324 gtk_widget_set_usize (fontsel->preview_entry, -1, INITIAL_PREVIEW_HEIGHT);
325 gtk_box_pack_start (GTK_BOX (text_box), fontsel->preview_entry,
328 gtk_font_selection_update_preview (fontsel);
332 gtk_font_selection_new()
334 GtkFontSelection *fontsel;
336 fontsel = gtk_type_new (GTK_TYPE_FONT_SELECTION);
338 return GTK_WIDGET (fontsel);
342 gtk_font_selection_finalize (GObject *object)
344 GtkFontSelection *fontsel;
346 g_return_if_fail (object != NULL);
347 g_return_if_fail (GTK_IS_FONT_SELECTION (object));
349 fontsel = GTK_FONT_SELECTION (object);
351 pango_font_description_free (fontsel->font_desc);
354 gdk_font_unref (fontsel->font);
356 if (G_OBJECT_CLASS (font_selection_parent_class)->finalize)
357 (* G_OBJECT_CLASS (font_selection_parent_class)->finalize) (object);
361 /* This is called when the clist is exposed. Here we scroll to the current
362 font if necessary. */
364 gtk_font_selection_expose_list (GtkWidget *widget,
365 GdkEventExpose *event,
368 GtkFontSelection *fontsel;
373 g_message("In expose_list\n");
375 fontsel = GTK_FONT_SELECTION(data);
377 /* Try to scroll the font family clist to the selected item */
378 selection = GTK_CLIST(fontsel->font_clist)->selection;
381 index = GPOINTER_TO_INT (selection->data);
382 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_clist), index)
383 != GTK_VISIBILITY_FULL)
384 gtk_clist_moveto(GTK_CLIST(fontsel->font_clist), index, -1, 0.5, 0);
387 /* Try to scroll the font style clist to the selected item */
388 selection = GTK_CLIST(fontsel->font_style_clist)->selection;
391 index = GPOINTER_TO_INT (selection->data);
392 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_style_clist), index)
393 != GTK_VISIBILITY_FULL)
394 gtk_clist_moveto(GTK_CLIST(fontsel->font_style_clist), index, -1,
398 /* Try to scroll the font size clist to the selected item */
399 selection = GTK_CLIST(fontsel->size_clist)->selection;
402 index = GPOINTER_TO_INT (selection->data);
403 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->size_clist), index)
404 != GTK_VISIBILITY_FULL)
405 gtk_clist_moveto(GTK_CLIST(fontsel->size_clist), index, -1, 0.5, 0);
409 /* This is called when a family is selected in the list. */
411 gtk_font_selection_select_font (GtkWidget *w,
414 GdkEventButton *bevent,
417 GtkFontSelection *fontsel;
421 fontsel = GTK_FONT_SELECTION (data);
423 if (GTK_CLIST (fontsel->font_clist)->selection)
425 index = GPOINTER_TO_INT (GTK_CLIST (fontsel->font_clist)->selection->data);
427 if (gtk_clist_get_text (GTK_CLIST (fontsel->font_clist), index, 0, &family_name) &&
428 strcasecmp (fontsel->font_desc->family_name, family_name) != 0)
430 g_free (fontsel->font_desc->family_name);
431 fontsel->font_desc->family_name = g_strdup (family_name);
433 gtk_font_selection_show_available_styles (fontsel);
434 gtk_font_selection_select_best_style (fontsel, TRUE);
440 cmp_strings (const void *a, const void *b)
442 return strcasecmp (*(const char **)a, *(const char **)b);
446 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
451 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
452 &families, &n_families);
453 qsort (families, n_families, sizeof(char *), cmp_strings);
455 gtk_clist_freeze (GTK_CLIST (fontsel->font_clist));
456 gtk_clist_clear (GTK_CLIST (fontsel->font_clist));
458 for (i=0; i<n_families; i++)
460 gtk_clist_append (GTK_CLIST (fontsel->font_clist), &families[i]);
462 if (!strcasecmp (families[i], fontsel->font_desc->family_name))
464 gtk_clist_select_row (GTK_CLIST(fontsel->font_clist), i, 0);
465 gtk_entry_set_text(GTK_ENTRY(fontsel->font_entry), families[i]);
469 gtk_clist_thaw (GTK_CLIST(fontsel->font_clist));
471 pango_font_map_free_families (families, n_families);
475 gtk_font_selection_on_clist_key_press (GtkWidget *clist,
477 GtkFontSelection *fontsel)
480 g_message("In on_clist_key_press\n");
482 if (event->keyval == GDK_Up)
483 return gtk_font_selection_select_next (fontsel, clist, -1);
484 else if (event->keyval == GDK_Down)
485 return gtk_font_selection_select_next (fontsel, clist, 1);
492 gtk_font_selection_select_next (GtkFontSelection *fontsel,
497 gint current_row, row;
499 selection = GTK_CLIST(clist)->selection;
502 current_row = GPOINTER_TO_INT (selection->data);
504 /* Stop the normal clist key handler from being run. */
505 gtk_signal_emit_stop_by_name (GTK_OBJECT (clist), "key_press_event");
507 for (row = current_row + step;
508 row >= 0 && row < GTK_CLIST(clist)->rows;
511 /* If this is the style clist, make sure that the item is not a charset
513 if (clist == fontsel->font_style_clist)
514 if (GPOINTER_TO_INT (gtk_clist_get_row_data(GTK_CLIST(clist), row)) == -1)
517 /* Now we've found the row to select. */
518 if (gtk_clist_row_is_visible(GTK_CLIST(clist), row)
519 != GTK_VISIBILITY_FULL)
520 gtk_clist_moveto(GTK_CLIST(clist), row, -1, (step < 0) ? 0 : 1, 0);
521 gtk_clist_select_row(GTK_CLIST(clist), row, 0);
528 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
530 int val = strcasecmp (a->family_name, b->family_name);
534 if (a->weight != b->weight)
535 return a->weight - b->weight;
537 if (a->style != b->style)
538 return a->style - b->style;
540 if (a->stretch != b->stretch)
541 return a->stretch - b->stretch;
543 if (a->variant != b->variant)
544 return a->variant - b->variant;
550 font_description_sort_func (const void *a, const void *b)
552 return compare_font_descriptions (*(PangoFontDescription **)a, *(PangoFontDescription **)b);
555 /* This fills the font style clist with all the possible style combinations
556 for the current font family. */
558 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
560 PangoFontDescription **descs;
565 pango_context_list_fonts (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
566 fontsel->font_desc->family_name, &descs, &n_descs);
567 qsort (descs, n_descs, sizeof(PangoFontDescription *), font_description_sort_func);
569 gtk_clist_freeze (GTK_CLIST (fontsel->font_style_clist));
570 gtk_clist_clear (GTK_CLIST (fontsel->font_style_clist));
572 for (i=0; i<n_descs; i++)
574 PangoFontDescription tmp_desc;
576 tmp_desc = *descs[i];
577 tmp_desc.family_name = NULL;
580 str = pango_font_description_to_string (&tmp_desc);
581 gtk_clist_append (GTK_CLIST (fontsel->font_style_clist), &str);
583 if (descs[i]->weight == fontsel->font_desc->weight &&
584 descs[i]->style == fontsel->font_desc->style &&
585 descs[i]->stretch == fontsel->font_desc->stretch &&
586 descs[i]->variant == fontsel->font_desc->variant)
592 gtk_clist_select_row (GTK_CLIST (fontsel->font_style_clist), match_row, 0);
593 gtk_clist_get_text (GTK_CLIST (fontsel->font_style_clist), match_row, 0, &str);
594 gtk_entry_set_text (GTK_ENTRY (fontsel->font_style_entry), str);
596 gtk_clist_thaw (GTK_CLIST(fontsel->font_style_clist));
598 pango_font_descriptions_free (descs, n_descs);
602 /* This selects a style when the user selects a font. It just uses the first
603 available style at present. I was thinking of trying to maintain the
604 selected style, e.g. bold italic, when the user selects different fonts.
605 However, the interface is so easy to use now I'm not sure it's worth it.
606 Note: This will load a font. */
608 gtk_font_selection_select_best_style(GtkFontSelection *fontsel,
613 gtk_clist_select_row(GTK_CLIST(fontsel->font_style_clist), best_row, 0);
614 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_style_clist), best_row)
615 != GTK_VISIBILITY_FULL)
616 gtk_clist_moveto(GTK_CLIST(fontsel->font_style_clist), best_row, -1,
618 gtk_font_selection_show_available_sizes (fontsel);
619 gtk_font_selection_select_best_size (fontsel);
623 /* This is called when a style is selected in the list. */
625 gtk_font_selection_select_style (GtkWidget *w,
628 GdkEventButton *bevent,
631 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
632 PangoFontDescription *tmp_desc;
636 if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
637 gtk_widget_grab_focus (w);
639 if (GTK_CLIST (fontsel->font_style_clist)->selection)
641 index = GPOINTER_TO_INT (GTK_CLIST (fontsel->font_style_clist)->selection->data);
643 if (gtk_clist_get_text (GTK_CLIST (fontsel->font_style_clist), index, 0, &text))
645 tmp_desc = pango_font_description_from_string (text);
647 fontsel->font_desc->style = tmp_desc->style;
648 fontsel->font_desc->variant = tmp_desc->variant;
649 fontsel->font_desc->weight = tmp_desc->weight;
650 fontsel->font_desc->stretch = tmp_desc->stretch;
652 pango_font_description_free (tmp_desc);
656 gtk_font_selection_show_available_sizes (fontsel);
657 gtk_font_selection_select_best_size (fontsel);
661 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel)
667 /* Insert the standard font sizes */
668 gtk_clist_freeze (GTK_CLIST (fontsel->size_clist));
669 gtk_clist_clear (GTK_CLIST (fontsel->size_clist));
671 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
673 sprintf(buffer, "%i", font_sizes[i]);
675 gtk_clist_append (GTK_CLIST(fontsel->size_clist), &size);
676 if (font_sizes[i] * PANGO_SCALE == fontsel->font_desc->size)
677 gtk_clist_select_row(GTK_CLIST(fontsel->size_clist), i, 0);
679 gtk_clist_thaw (GTK_CLIST(fontsel->size_clist));
681 sprintf (buffer, "%i", fontsel->font_desc->size / PANGO_SCALE);
682 gtk_entry_set_text (GTK_ENTRY(fontsel->size_entry), buffer);
686 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
688 gtk_font_selection_load_font (fontsel);
691 /* If the user hits return in the font size entry, we change to the new font
694 gtk_font_selection_size_key_press (GtkWidget *w,
698 GtkFontSelection *fontsel;
702 fontsel = GTK_FONT_SELECTION (data);
704 if (event->keyval == GDK_Return)
706 text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry));
707 new_size = atoi (text) * PANGO_SCALE;
709 if (fontsel->font_desc->size != new_size)
711 fontsel->font_desc->size = new_size;
712 gtk_font_selection_load_font (fontsel);
719 /* This is called when a size is selected in the list. */
721 gtk_font_selection_select_size (GtkWidget *w,
724 GdkEventButton *bevent,
727 GtkFontSelection *fontsel;
731 fontsel = GTK_FONT_SELECTION (data);
733 if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
734 gtk_widget_grab_focus (w);
736 gtk_clist_get_text(GTK_CLIST(fontsel->size_clist), row, 0, &text);
737 new_size = atoi (text) * PANGO_SCALE;
739 if (fontsel->font_desc->size != new_size)
741 /* If the size was selected by the user we set the selected_size. */
742 fontsel->font_desc->size = new_size;
744 gtk_font_selection_load_font (fontsel);
749 gtk_font_selection_load_font (GtkFontSelection *fontsel)
752 gdk_font_unref (fontsel->font);
753 fontsel->font = NULL;
755 gtk_font_selection_update_preview (fontsel);
758 /* This sets the font in the preview entry to the selected font, and tries to
759 make sure that the preview entry is a reasonable size, i.e. so that the
760 text can be seen with a bit of space to spare. But it tries to avoid
761 resizing the entry every time the font changes.
762 This also used to shrink the preview if the font size was decreased, but
763 that made it awkward if the user wanted to resize the window themself. */
765 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
767 GtkRcStyle *rc_style;
769 GtkRequisition old_requisition;
770 GtkWidget *preview_entry = fontsel->preview_entry;
773 gtk_widget_get_child_requisition (preview_entry, &old_requisition);
775 rc_style = gtk_rc_style_new ();
776 rc_style->font_desc = pango_font_description_copy (fontsel->font_desc);
777 gtk_widget_modify_style (preview_entry, rc_style);
778 gtk_rc_style_unref (rc_style);
780 gtk_widget_size_request (preview_entry, NULL);
782 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
783 new_height = CLAMP (preview_entry->requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
785 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
786 gtk_widget_set_usize(preview_entry, -1, new_height);
788 /* This sets the preview text, if it hasn't been set already. */
789 text = gtk_entry_get_text(GTK_ENTRY(preview_entry));
790 if (strlen(text) == 0)
791 gtk_entry_set_text(GTK_ENTRY(preview_entry), PREVIEW_TEXT);
792 gtk_entry_set_position(GTK_ENTRY(preview_entry), 0);
795 /*****************************************************************************
796 * These functions are the main public interface for getting/setting the font.
797 *****************************************************************************/
800 gtk_font_selection_get_font (GtkFontSelection *fontsel)
803 fontsel->font = gdk_font_from_description (fontsel->font_desc);
805 return fontsel->font;
810 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
812 return pango_font_description_to_string (fontsel->font_desc);
816 /* This sets the current font, selecting the appropriate clist rows.
817 First we check the fontname is valid and try to find the font family
818 - i.e. the name in the main list. If we can't find that, then just return.
819 Next we try to set each of the properties according to the fontname.
820 Finally we select the font family & style in the clists. */
822 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
823 const gchar *fontname)
825 PangoFontDescription *new_desc;
826 PangoFontDescription **descs;
828 gboolean found = FALSE;
830 g_return_val_if_fail (fontsel != NULL, FALSE);
831 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
833 new_desc = pango_font_description_from_string (fontname);
835 /* Check to make sure that this is in the list of allowed fonts */
837 pango_context_list_fonts (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
838 new_desc->family_name, &descs, &n_descs);
840 for (i=0; i<n_descs; i++)
842 if (descs[i]->weight == new_desc->weight &&
843 descs[i]->style == new_desc->style &&
844 descs[i]->stretch == new_desc->stretch &&
845 descs[i]->variant == new_desc->variant)
852 pango_font_descriptions_free (descs, n_descs);
857 pango_font_description_free (fontsel->font_desc);
858 fontsel->font_desc = new_desc;
864 /* This returns the text in the preview entry. You should copy the returned
865 text if you need it. */
867 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
869 return gtk_entry_get_text (GTK_ENTRY (fontsel->preview_entry));
873 /* This sets the text in the preview entry. */
875 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
878 gtk_entry_set_text (GTK_ENTRY (fontsel->preview_entry), text);
881 /*****************************************************************************
882 * GtkFontSelectionDialog
883 *****************************************************************************/
886 gtk_font_selection_dialog_get_type (void)
888 static guint font_selection_dialog_type = 0;
890 if (!font_selection_dialog_type)
892 GtkTypeInfo fontsel_diag_info =
894 "GtkFontSelectionDialog",
895 sizeof (GtkFontSelectionDialog),
896 sizeof (GtkFontSelectionDialogClass),
897 (GtkClassInitFunc) gtk_font_selection_dialog_class_init,
898 (GtkObjectInitFunc) gtk_font_selection_dialog_init,
899 /* reserved_1 */ NULL,
900 /* reserved_2 */ NULL,
901 (GtkClassInitFunc) NULL,
904 font_selection_dialog_type = gtk_type_unique (GTK_TYPE_DIALOG,
908 return font_selection_dialog_type;
912 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
914 GtkObjectClass *object_class;
916 object_class = (GtkObjectClass*) klass;
918 font_selection_dialog_parent_class = gtk_type_class (GTK_TYPE_DIALOG);
922 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
926 dialog = GTK_DIALOG (fontseldiag);
928 fontseldiag->dialog_width = -1;
929 fontseldiag->auto_resize = TRUE;
931 gtk_widget_set_events(GTK_WIDGET(fontseldiag), GDK_STRUCTURE_MASK);
932 gtk_signal_connect (GTK_OBJECT (fontseldiag), "configure_event",
933 (GtkSignalFunc) gtk_font_selection_dialog_on_configure,
936 gtk_container_set_border_width (GTK_CONTAINER (fontseldiag), 4);
937 gtk_window_set_policy(GTK_WINDOW(fontseldiag), FALSE, TRUE, TRUE);
939 fontseldiag->main_vbox = dialog->vbox;
941 fontseldiag->fontsel = gtk_font_selection_new();
942 gtk_container_set_border_width (GTK_CONTAINER (fontseldiag->fontsel), 4);
943 gtk_widget_show (fontseldiag->fontsel);
944 gtk_box_pack_start (GTK_BOX (fontseldiag->main_vbox),
945 fontseldiag->fontsel, TRUE, TRUE, 0);
947 /* Create the action area */
948 fontseldiag->action_area = dialog->action_area;
950 fontseldiag->ok_button = gtk_dialog_add_button (dialog,
953 gtk_widget_grab_default (fontseldiag->ok_button);
955 fontseldiag->apply_button = gtk_dialog_add_button (dialog,
956 GTK_STOCK_BUTTON_APPLY,
958 gtk_widget_hide (fontseldiag->apply_button);
961 fontseldiag->cancel_button = gtk_dialog_add_button (dialog,
962 GTK_STOCK_BUTTON_CANCEL,
963 GTK_RESPONSE_CANCEL);
965 gtk_window_set_title (GTK_WINDOW (fontseldiag),
966 _("Font Selection"));
971 gtk_font_selection_dialog_new (const gchar *title)
973 GtkFontSelectionDialog *fontseldiag;
975 fontseldiag = gtk_type_new (GTK_TYPE_FONT_SELECTION_DIALOG);
978 gtk_window_set_title (GTK_WINDOW (fontseldiag), title);
980 return GTK_WIDGET (fontseldiag);
984 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
986 return gtk_font_selection_get_font_name(GTK_FONT_SELECTION(fsd->fontsel));
990 gtk_font_selection_dialog_get_font (GtkFontSelectionDialog *fsd)
992 return gtk_font_selection_get_font(GTK_FONT_SELECTION(fsd->fontsel));
996 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
997 const gchar *fontname)
999 return gtk_font_selection_set_font_name(GTK_FONT_SELECTION(fsd->fontsel),
1004 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1006 return gtk_font_selection_get_preview_text(GTK_FONT_SELECTION(fsd->fontsel));
1010 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1013 gtk_font_selection_set_preview_text(GTK_FONT_SELECTION(fsd->fontsel), text);
1017 /* This turns auto-shrink off if the user resizes the width of the dialog.
1018 It also turns it back on again if the user resizes it back to its normal
1021 gtk_font_selection_dialog_on_configure (GtkWidget *widget,
1022 GdkEventConfigure *event,
1023 GtkFontSelectionDialog *fsd)
1025 /* This sets the initial width. */
1026 if (fsd->dialog_width == -1)
1027 fsd->dialog_width = event->width;
1028 else if (fsd->auto_resize && fsd->dialog_width != event->width)
1030 fsd->auto_resize = FALSE;
1031 gtk_window_set_policy(GTK_WINDOW(fsd), FALSE, TRUE, FALSE);
1033 else if (!fsd->auto_resize && fsd->dialog_width == event->width)
1035 fsd->auto_resize = TRUE;
1036 gtk_window_set_policy(GTK_WINDOW(fsd), FALSE, TRUE, TRUE);