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"
53 #include "gtkscrolledwindow.h"
56 /* This is the default text shown in the preview entry, though the user
57 can set it. Remember that some fonts only have capital letters. */
58 #define PREVIEW_TEXT "abcdefghijk ABCDEFGHIJK"
60 /* This is the initial and maximum height of the preview entry (it expands
61 when large font sizes are selected). Initial height is also the minimum. */
62 #define INITIAL_PREVIEW_HEIGHT 44
63 #define MAX_PREVIEW_HEIGHT 300
65 /* These are the sizes of the font, style & size clists. */
66 #define FONT_LIST_HEIGHT 136
67 #define FONT_LIST_WIDTH 190
68 #define FONT_STYLE_LIST_WIDTH 170
69 #define FONT_SIZE_LIST_WIDTH 60
71 /* These are what we use as the standard font sizes, for the size clist.
73 static const guint16 font_sizes[] = {
74 8, 9, 10, 11, 12, 13, 14, 16, 18, 20, 22, 24, 26, 28,
75 32, 36, 40, 48, 56, 64, 72
78 static void gtk_font_selection_class_init (GtkFontSelectionClass *klass);
79 static void gtk_font_selection_init (GtkFontSelection *fontsel);
80 static void gtk_font_selection_finalize (GObject *object);
82 /* These are the callbacks & related functions. */
83 static void gtk_font_selection_select_font (GtkWidget *w,
86 GdkEventButton *bevent,
88 static gint gtk_font_selection_on_clist_key_press (GtkWidget *clist,
90 GtkFontSelection *fs);
91 static gboolean gtk_font_selection_select_next (GtkFontSelection *fs,
95 static void gtk_font_selection_show_available_fonts (GtkFontSelection *fs);
97 static void gtk_font_selection_show_available_styles (GtkFontSelection *fs);
98 static void gtk_font_selection_select_best_style (GtkFontSelection *fs,
100 static void gtk_font_selection_select_style (GtkWidget *w,
103 GdkEventButton *bevent,
106 static void gtk_font_selection_select_best_size (GtkFontSelection *fs);
107 static void gtk_font_selection_show_available_sizes (GtkFontSelection *fs);
108 static gint gtk_font_selection_size_key_press (GtkWidget *w,
111 static void gtk_font_selection_select_size (GtkWidget *w,
114 GdkEventButton *bevent,
117 static void gtk_font_selection_expose_list (GtkWidget *w,
118 GdkEventExpose *event,
122 /* Misc. utility functions. */
123 static void gtk_font_selection_load_font (GtkFontSelection *fs);
124 static void gtk_font_selection_update_preview (GtkFontSelection *fs);
126 /* FontSelectionDialog */
127 static void gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass);
128 static void gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag);
130 static gint gtk_font_selection_dialog_on_configure(GtkWidget *widget,
131 GdkEventConfigure *event,
132 GtkFontSelectionDialog *fsd);
134 static GtkWindowClass *font_selection_parent_class = NULL;
135 static GtkVBoxClass *font_selection_dialog_parent_class = NULL;
138 gtk_font_selection_get_type()
140 static GtkType font_selection_type = 0;
142 if(!font_selection_type)
144 static const GtkTypeInfo fontsel_type_info =
147 sizeof (GtkFontSelection),
148 sizeof (GtkFontSelectionClass),
149 (GtkClassInitFunc) gtk_font_selection_class_init,
150 (GtkObjectInitFunc) gtk_font_selection_init,
151 /* reserved_1 */ NULL,
152 /* reserved_2 */ NULL,
153 (GtkClassInitFunc) NULL,
156 font_selection_type = gtk_type_unique (GTK_TYPE_VBOX,
160 return font_selection_type;
164 gtk_font_selection_class_init(GtkFontSelectionClass *klass)
166 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
168 font_selection_parent_class = gtk_type_class (GTK_TYPE_VBOX);
170 gobject_class->finalize = gtk_font_selection_finalize;
174 gtk_font_selection_init(GtkFontSelection *fontsel)
176 GtkWidget *scrolled_win;
177 GtkWidget *text_frame;
179 GtkWidget *table, *label;
181 fontsel->font_desc = pango_font_description_from_string ("sans 12");
183 /* Create the table of font, style & size. */
184 table = gtk_table_new (3, 3, FALSE);
185 gtk_widget_show (table);
186 gtk_table_set_col_spacings(GTK_TABLE(table), 8);
187 gtk_box_pack_start (GTK_BOX (fontsel), table, TRUE, TRUE, 0);
189 fontsel->font_label = gtk_label_new(_("Family:"));
190 gtk_misc_set_alignment (GTK_MISC (fontsel->font_label), 0.0, 0.5);
191 gtk_widget_show (fontsel->font_label);
192 gtk_table_attach (GTK_TABLE (table), fontsel->font_label, 0, 1, 0, 1,
194 label = gtk_label_new(_("Style:"));
195 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
196 gtk_widget_show (label);
197 gtk_table_attach (GTK_TABLE (table), label, 1, 2, 0, 1,
199 label = gtk_label_new(_("Size:"));
200 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
201 gtk_widget_show (label);
202 gtk_table_attach (GTK_TABLE (table), label, 2, 3, 0, 1,
205 fontsel->font_entry = gtk_entry_new ();
206 gtk_entry_set_editable(GTK_ENTRY(fontsel->font_entry), FALSE);
207 gtk_widget_set_usize (fontsel->font_entry, 20, -1);
208 gtk_widget_show (fontsel->font_entry);
209 gtk_table_attach (GTK_TABLE (table), fontsel->font_entry, 0, 1, 1, 2,
212 fontsel->font_style_entry = gtk_entry_new ();
213 gtk_entry_set_editable (GTK_ENTRY(fontsel->font_style_entry), FALSE);
214 gtk_widget_set_usize (fontsel->font_style_entry, 20, -1);
215 gtk_widget_show (fontsel->font_style_entry);
216 gtk_table_attach (GTK_TABLE (table), fontsel->font_style_entry, 1, 2, 1, 2,
219 fontsel->size_entry = gtk_entry_new ();
220 gtk_widget_set_usize (fontsel->size_entry, 20, -1);
221 gtk_widget_show (fontsel->size_entry);
222 gtk_table_attach (GTK_TABLE (table), fontsel->size_entry, 2, 3, 1, 2,
224 gtk_signal_connect (GTK_OBJECT (fontsel->size_entry), "key_press_event",
225 (GtkSignalFunc) gtk_font_selection_size_key_press,
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);
280 gtk_signal_connect (GTK_OBJECT (fontsel->font_clist), "key_press_event",
281 GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
283 gtk_signal_connect_after (GTK_OBJECT (fontsel->font_clist), "expose_event",
284 GTK_SIGNAL_FUNC(gtk_font_selection_expose_list),
287 gtk_font_selection_show_available_styles (fontsel);
289 gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist), "select_row",
290 GTK_SIGNAL_FUNC(gtk_font_selection_select_style),
292 GTK_WIDGET_SET_FLAGS (fontsel->font_style_clist, GTK_CAN_FOCUS);
293 gtk_signal_connect (GTK_OBJECT (fontsel->font_style_clist),
295 GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
298 gtk_font_selection_show_available_sizes (fontsel);
300 gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "select_row",
301 GTK_SIGNAL_FUNC(gtk_font_selection_select_size),
303 GTK_WIDGET_SET_FLAGS (fontsel->size_clist, GTK_CAN_FOCUS);
304 gtk_signal_connect (GTK_OBJECT (fontsel->size_clist), "key_press_event",
305 GTK_SIGNAL_FUNC(gtk_font_selection_on_clist_key_press),
308 /* create the text entry widget */
309 text_frame = gtk_frame_new (_("Preview:"));
310 gtk_widget_show (text_frame);
311 gtk_frame_set_shadow_type(GTK_FRAME(text_frame), GTK_SHADOW_ETCHED_IN);
312 gtk_box_pack_start (GTK_BOX (fontsel), text_frame,
315 /* This is just used to get a 4-pixel space around the preview entry. */
316 text_box = gtk_hbox_new (FALSE, 0);
317 gtk_widget_show (text_box);
318 gtk_container_add (GTK_CONTAINER (text_frame), text_box);
319 gtk_container_set_border_width (GTK_CONTAINER (text_box), 4);
321 fontsel->preview_entry = gtk_entry_new ();
322 gtk_widget_show (fontsel->preview_entry);
323 gtk_widget_set_usize (fontsel->preview_entry, -1, INITIAL_PREVIEW_HEIGHT);
324 gtk_box_pack_start (GTK_BOX (text_box), fontsel->preview_entry,
327 gtk_font_selection_update_preview (fontsel);
331 gtk_font_selection_new()
333 GtkFontSelection *fontsel;
335 fontsel = gtk_type_new (GTK_TYPE_FONT_SELECTION);
337 return GTK_WIDGET (fontsel);
341 gtk_font_selection_finalize (GObject *object)
343 GtkFontSelection *fontsel;
345 g_return_if_fail (object != NULL);
346 g_return_if_fail (GTK_IS_FONT_SELECTION (object));
348 fontsel = GTK_FONT_SELECTION (object);
350 pango_font_description_free (fontsel->font_desc);
353 gdk_font_unref (fontsel->font);
355 if (G_OBJECT_CLASS (font_selection_parent_class)->finalize)
356 (* G_OBJECT_CLASS (font_selection_parent_class)->finalize) (object);
360 /* This is called when the clist is exposed. Here we scroll to the current
361 font if necessary. */
363 gtk_font_selection_expose_list (GtkWidget *widget,
364 GdkEventExpose *event,
367 GtkFontSelection *fontsel;
372 g_message("In expose_list\n");
374 fontsel = GTK_FONT_SELECTION(data);
376 /* Try to scroll the font family clist to the selected item */
377 selection = GTK_CLIST(fontsel->font_clist)->selection;
380 index = GPOINTER_TO_INT (selection->data);
381 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_clist), index)
382 != GTK_VISIBILITY_FULL)
383 gtk_clist_moveto(GTK_CLIST(fontsel->font_clist), index, -1, 0.5, 0);
386 /* Try to scroll the font style clist to the selected item */
387 selection = GTK_CLIST(fontsel->font_style_clist)->selection;
390 index = GPOINTER_TO_INT (selection->data);
391 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_style_clist), index)
392 != GTK_VISIBILITY_FULL)
393 gtk_clist_moveto(GTK_CLIST(fontsel->font_style_clist), index, -1,
397 /* Try to scroll the font size clist to the selected item */
398 selection = GTK_CLIST(fontsel->size_clist)->selection;
401 index = GPOINTER_TO_INT (selection->data);
402 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->size_clist), index)
403 != GTK_VISIBILITY_FULL)
404 gtk_clist_moveto(GTK_CLIST(fontsel->size_clist), index, -1, 0.5, 0);
408 /* This is called when a family is selected in the list. */
410 gtk_font_selection_select_font (GtkWidget *w,
413 GdkEventButton *bevent,
416 GtkFontSelection *fontsel;
420 fontsel = GTK_FONT_SELECTION (data);
422 if (GTK_CLIST (fontsel->font_clist)->selection)
424 index = GPOINTER_TO_INT (GTK_CLIST (fontsel->font_clist)->selection->data);
426 if (gtk_clist_get_text (GTK_CLIST (fontsel->font_clist), index, 0, &family_name) &&
427 strcasecmp (fontsel->font_desc->family_name, family_name) != 0)
429 g_free (fontsel->font_desc->family_name);
430 fontsel->font_desc->family_name = g_strdup (family_name);
432 gtk_font_selection_show_available_styles (fontsel);
433 gtk_font_selection_select_best_style (fontsel, TRUE);
439 cmp_strings (const void *a, const void *b)
441 return strcasecmp (*(const char **)a, *(const char **)b);
445 gtk_font_selection_show_available_fonts (GtkFontSelection *fontsel)
450 pango_context_list_families (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
451 &families, &n_families);
452 qsort (families, n_families, sizeof(char *), cmp_strings);
454 gtk_clist_freeze (GTK_CLIST (fontsel->font_clist));
455 gtk_clist_clear (GTK_CLIST (fontsel->font_clist));
457 for (i=0; i<n_families; i++)
459 gtk_clist_append (GTK_CLIST (fontsel->font_clist), &families[i]);
461 if (!strcasecmp (families[i], fontsel->font_desc->family_name))
463 gtk_clist_select_row (GTK_CLIST(fontsel->font_clist), i, 0);
464 gtk_entry_set_text(GTK_ENTRY(fontsel->font_entry), families[i]);
468 gtk_clist_thaw (GTK_CLIST(fontsel->font_clist));
470 pango_font_map_free_families (families, n_families);
474 gtk_font_selection_on_clist_key_press (GtkWidget *clist,
476 GtkFontSelection *fontsel)
479 g_message("In on_clist_key_press\n");
481 if (event->keyval == GDK_Up)
482 return gtk_font_selection_select_next (fontsel, clist, -1);
483 else if (event->keyval == GDK_Down)
484 return gtk_font_selection_select_next (fontsel, clist, 1);
491 gtk_font_selection_select_next (GtkFontSelection *fontsel,
496 gint current_row, row;
498 selection = GTK_CLIST(clist)->selection;
501 current_row = GPOINTER_TO_INT (selection->data);
503 /* Stop the normal clist key handler from being run. */
504 gtk_signal_emit_stop_by_name (GTK_OBJECT (clist), "key_press_event");
506 for (row = current_row + step;
507 row >= 0 && row < GTK_CLIST(clist)->rows;
510 /* If this is the style clist, make sure that the item is not a charset
512 if (clist == fontsel->font_style_clist)
513 if (GPOINTER_TO_INT (gtk_clist_get_row_data(GTK_CLIST(clist), row)) == -1)
516 /* Now we've found the row to select. */
517 if (gtk_clist_row_is_visible(GTK_CLIST(clist), row)
518 != GTK_VISIBILITY_FULL)
519 gtk_clist_moveto(GTK_CLIST(clist), row, -1, (step < 0) ? 0 : 1, 0);
520 gtk_clist_select_row(GTK_CLIST(clist), row, 0);
527 compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
529 int val = strcasecmp (a->family_name, b->family_name);
533 if (a->weight != b->weight)
534 return a->weight - b->weight;
536 if (a->style != b->style)
537 return a->style - b->style;
539 if (a->stretch != b->stretch)
540 return a->stretch - b->stretch;
542 if (a->variant != b->variant)
543 return a->variant - b->variant;
549 font_description_sort_func (const void *a, const void *b)
551 return compare_font_descriptions (*(PangoFontDescription **)a, *(PangoFontDescription **)b);
554 /* This fills the font style clist with all the possible style combinations
555 for the current font family. */
557 gtk_font_selection_show_available_styles (GtkFontSelection *fontsel)
559 PangoFontDescription **descs;
564 pango_context_list_fonts (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
565 fontsel->font_desc->family_name, &descs, &n_descs);
566 qsort (descs, n_descs, sizeof(PangoFontDescription *), font_description_sort_func);
568 gtk_clist_freeze (GTK_CLIST (fontsel->font_style_clist));
569 gtk_clist_clear (GTK_CLIST (fontsel->font_style_clist));
571 for (i=0; i<n_descs; i++)
573 PangoFontDescription tmp_desc;
575 tmp_desc = *descs[i];
576 tmp_desc.family_name = NULL;
579 str = pango_font_description_to_string (&tmp_desc);
580 gtk_clist_append (GTK_CLIST (fontsel->font_style_clist), &str);
582 if (descs[i]->weight == fontsel->font_desc->weight &&
583 descs[i]->style == fontsel->font_desc->style &&
584 descs[i]->stretch == fontsel->font_desc->stretch &&
585 descs[i]->variant == fontsel->font_desc->variant)
591 gtk_clist_select_row (GTK_CLIST (fontsel->font_style_clist), match_row, 0);
592 gtk_clist_get_text (GTK_CLIST (fontsel->font_style_clist), match_row, 0, &str);
593 gtk_entry_set_text (GTK_ENTRY (fontsel->font_style_entry), str);
595 gtk_clist_thaw (GTK_CLIST(fontsel->font_style_clist));
597 pango_font_descriptions_free (descs, n_descs);
601 /* This selects a style when the user selects a font. It just uses the first
602 available style at present. I was thinking of trying to maintain the
603 selected style, e.g. bold italic, when the user selects different fonts.
604 However, the interface is so easy to use now I'm not sure it's worth it.
605 Note: This will load a font. */
607 gtk_font_selection_select_best_style(GtkFontSelection *fontsel,
612 gtk_clist_select_row(GTK_CLIST(fontsel->font_style_clist), best_row, 0);
613 if (gtk_clist_row_is_visible(GTK_CLIST(fontsel->font_style_clist), best_row)
614 != GTK_VISIBILITY_FULL)
615 gtk_clist_moveto(GTK_CLIST(fontsel->font_style_clist), best_row, -1,
617 gtk_font_selection_show_available_sizes (fontsel);
618 gtk_font_selection_select_best_size (fontsel);
622 /* This is called when a style is selected in the list. */
624 gtk_font_selection_select_style (GtkWidget *w,
627 GdkEventButton *bevent,
630 GtkFontSelection *fontsel = GTK_FONT_SELECTION (data);
631 PangoFontDescription *tmp_desc;
635 if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
636 gtk_widget_grab_focus (w);
638 if (GTK_CLIST (fontsel->font_style_clist)->selection)
640 index = GPOINTER_TO_INT (GTK_CLIST (fontsel->font_style_clist)->selection->data);
642 if (gtk_clist_get_text (GTK_CLIST (fontsel->font_style_clist), index, 0, &text))
644 tmp_desc = pango_font_description_from_string (text);
646 fontsel->font_desc->style = tmp_desc->style;
647 fontsel->font_desc->variant = tmp_desc->variant;
648 fontsel->font_desc->weight = tmp_desc->weight;
649 fontsel->font_desc->stretch = tmp_desc->stretch;
651 pango_font_description_free (tmp_desc);
655 gtk_font_selection_show_available_sizes (fontsel);
656 gtk_font_selection_select_best_size (fontsel);
660 gtk_font_selection_show_available_sizes (GtkFontSelection *fontsel)
666 /* Insert the standard font sizes */
667 gtk_clist_freeze (GTK_CLIST (fontsel->size_clist));
668 gtk_clist_clear (GTK_CLIST (fontsel->size_clist));
670 for (i = 0; i < G_N_ELEMENTS (font_sizes); i++)
672 sprintf(buffer, "%i", font_sizes[i]);
674 gtk_clist_append (GTK_CLIST(fontsel->size_clist), &size);
675 if (font_sizes[i] * PANGO_SCALE == fontsel->font_desc->size)
676 gtk_clist_select_row(GTK_CLIST(fontsel->size_clist), i, 0);
678 gtk_clist_thaw (GTK_CLIST(fontsel->size_clist));
680 sprintf (buffer, "%i", fontsel->font_desc->size / PANGO_SCALE);
681 gtk_entry_set_text (GTK_ENTRY(fontsel->size_entry), buffer);
685 gtk_font_selection_select_best_size (GtkFontSelection *fontsel)
687 gtk_font_selection_load_font (fontsel);
690 /* If the user hits return in the font size entry, we change to the new font
693 gtk_font_selection_size_key_press (GtkWidget *w,
697 GtkFontSelection *fontsel;
701 fontsel = GTK_FONT_SELECTION (data);
703 if (event->keyval == GDK_Return)
705 text = gtk_entry_get_text (GTK_ENTRY (fontsel->size_entry));
706 new_size = atoi (text) * PANGO_SCALE;
708 if (fontsel->font_desc->size != new_size)
710 fontsel->font_desc->size = new_size;
711 gtk_font_selection_load_font (fontsel);
718 /* This is called when a size is selected in the list. */
720 gtk_font_selection_select_size (GtkWidget *w,
723 GdkEventButton *bevent,
726 GtkFontSelection *fontsel;
730 fontsel = GTK_FONT_SELECTION (data);
732 if (bevent && !GTK_WIDGET_HAS_FOCUS (w))
733 gtk_widget_grab_focus (w);
735 gtk_clist_get_text(GTK_CLIST(fontsel->size_clist), row, 0, &text);
736 new_size = atoi (text) * PANGO_SCALE;
738 if (fontsel->font_desc->size != new_size)
740 /* If the size was selected by the user we set the selected_size. */
741 fontsel->font_desc->size = new_size;
743 gtk_font_selection_load_font (fontsel);
748 gtk_font_selection_load_font (GtkFontSelection *fontsel)
751 gdk_font_unref (fontsel->font);
752 fontsel->font = NULL;
754 gtk_font_selection_update_preview (fontsel);
757 /* This sets the font in the preview entry to the selected font, and tries to
758 make sure that the preview entry is a reasonable size, i.e. so that the
759 text can be seen with a bit of space to spare. But it tries to avoid
760 resizing the entry every time the font changes.
761 This also used to shrink the preview if the font size was decreased, but
762 that made it awkward if the user wanted to resize the window themself. */
764 gtk_font_selection_update_preview (GtkFontSelection *fontsel)
766 GtkRcStyle *rc_style;
768 GtkRequisition old_requisition;
769 GtkWidget *preview_entry = fontsel->preview_entry;
772 gtk_widget_get_child_requisition (preview_entry, &old_requisition);
774 rc_style = gtk_rc_style_new ();
775 rc_style->font_desc = pango_font_description_copy (fontsel->font_desc);
776 gtk_widget_modify_style (preview_entry, rc_style);
777 gtk_rc_style_unref (rc_style);
779 gtk_widget_size_request (preview_entry, NULL);
781 /* We don't ever want to be over MAX_PREVIEW_HEIGHT pixels high. */
782 new_height = CLAMP (preview_entry->requisition.height, INITIAL_PREVIEW_HEIGHT, MAX_PREVIEW_HEIGHT);
784 if (new_height > old_requisition.height || new_height < old_requisition.height - 30)
785 gtk_widget_set_usize(preview_entry, -1, new_height);
787 /* This sets the preview text, if it hasn't been set already. */
788 text = gtk_entry_get_text(GTK_ENTRY(preview_entry));
789 if (strlen(text) == 0)
790 gtk_entry_set_text(GTK_ENTRY(preview_entry), PREVIEW_TEXT);
791 gtk_entry_set_position(GTK_ENTRY(preview_entry), 0);
794 /*****************************************************************************
795 * These functions are the main public interface for getting/setting the font.
796 *****************************************************************************/
799 gtk_font_selection_get_font (GtkFontSelection *fontsel)
802 fontsel->font = gdk_font_from_description (fontsel->font_desc);
804 return fontsel->font;
809 gtk_font_selection_get_font_name (GtkFontSelection *fontsel)
811 return pango_font_description_to_string (fontsel->font_desc);
815 /* This sets the current font, selecting the appropriate clist rows.
816 First we check the fontname is valid and try to find the font family
817 - i.e. the name in the main list. If we can't find that, then just return.
818 Next we try to set each of the properties according to the fontname.
819 Finally we select the font family & style in the clists. */
821 gtk_font_selection_set_font_name (GtkFontSelection *fontsel,
822 const gchar *fontname)
824 PangoFontDescription *new_desc;
825 PangoFontDescription **descs;
827 gboolean found = FALSE;
829 g_return_val_if_fail (fontsel != NULL, FALSE);
830 g_return_val_if_fail (GTK_IS_FONT_SELECTION (fontsel), FALSE);
832 new_desc = pango_font_description_from_string (fontname);
834 /* Check to make sure that this is in the list of allowed fonts */
836 pango_context_list_fonts (gtk_widget_get_pango_context (GTK_WIDGET (fontsel)),
837 new_desc->family_name, &descs, &n_descs);
839 for (i=0; i<n_descs; i++)
841 if (descs[i]->weight == new_desc->weight &&
842 descs[i]->style == new_desc->style &&
843 descs[i]->stretch == new_desc->stretch &&
844 descs[i]->variant == new_desc->variant)
851 pango_font_descriptions_free (descs, n_descs);
856 pango_font_description_free (fontsel->font_desc);
857 fontsel->font_desc = new_desc;
863 /* This returns the text in the preview entry. You should copy the returned
864 text if you need it. */
866 gtk_font_selection_get_preview_text (GtkFontSelection *fontsel)
868 return gtk_entry_get_text (GTK_ENTRY (fontsel->preview_entry));
872 /* This sets the text in the preview entry. */
874 gtk_font_selection_set_preview_text (GtkFontSelection *fontsel,
877 gtk_entry_set_text (GTK_ENTRY (fontsel->preview_entry), text);
880 /*****************************************************************************
881 * GtkFontSelectionDialog
882 *****************************************************************************/
885 gtk_font_selection_dialog_get_type (void)
887 static guint font_selection_dialog_type = 0;
889 if (!font_selection_dialog_type)
891 GtkTypeInfo fontsel_diag_info =
893 "GtkFontSelectionDialog",
894 sizeof (GtkFontSelectionDialog),
895 sizeof (GtkFontSelectionDialogClass),
896 (GtkClassInitFunc) gtk_font_selection_dialog_class_init,
897 (GtkObjectInitFunc) gtk_font_selection_dialog_init,
898 /* reserved_1 */ NULL,
899 /* reserved_2 */ NULL,
900 (GtkClassInitFunc) NULL,
903 font_selection_dialog_type = gtk_type_unique (GTK_TYPE_WINDOW, &fontsel_diag_info);
906 return font_selection_dialog_type;
910 gtk_font_selection_dialog_class_init (GtkFontSelectionDialogClass *klass)
912 GtkObjectClass *object_class;
914 object_class = (GtkObjectClass*) klass;
916 font_selection_dialog_parent_class = gtk_type_class (GTK_TYPE_WINDOW);
920 gtk_font_selection_dialog_init (GtkFontSelectionDialog *fontseldiag)
922 fontseldiag->dialog_width = -1;
923 fontseldiag->auto_resize = TRUE;
925 gtk_widget_set_events(GTK_WIDGET(fontseldiag), GDK_STRUCTURE_MASK);
926 gtk_signal_connect (GTK_OBJECT (fontseldiag), "configure_event",
927 (GtkSignalFunc) gtk_font_selection_dialog_on_configure,
930 gtk_container_set_border_width (GTK_CONTAINER (fontseldiag), 4);
931 gtk_window_set_policy(GTK_WINDOW(fontseldiag), FALSE, TRUE, TRUE);
933 fontseldiag->main_vbox = gtk_vbox_new (FALSE, 4);
934 gtk_widget_show (fontseldiag->main_vbox);
935 gtk_container_add (GTK_CONTAINER (fontseldiag), fontseldiag->main_vbox);
937 fontseldiag->fontsel = gtk_font_selection_new();
938 gtk_container_set_border_width (GTK_CONTAINER (fontseldiag->fontsel), 4);
939 gtk_widget_show (fontseldiag->fontsel);
940 gtk_box_pack_start (GTK_BOX (fontseldiag->main_vbox),
941 fontseldiag->fontsel, TRUE, TRUE, 0);
943 /* Create the action area */
944 fontseldiag->action_area = gtk_hbutton_box_new ();
945 gtk_button_box_set_layout(GTK_BUTTON_BOX(fontseldiag->action_area),
947 gtk_button_box_set_spacing(GTK_BUTTON_BOX(fontseldiag->action_area), 5);
948 gtk_box_pack_start (GTK_BOX (fontseldiag->main_vbox),
949 fontseldiag->action_area, FALSE, FALSE, 0);
950 gtk_widget_show (fontseldiag->action_area);
952 fontseldiag->ok_button = gtk_button_new_with_label(_("OK"));
953 GTK_WIDGET_SET_FLAGS (fontseldiag->ok_button, GTK_CAN_DEFAULT);
954 gtk_widget_show(fontseldiag->ok_button);
955 gtk_box_pack_start (GTK_BOX (fontseldiag->action_area),
956 fontseldiag->ok_button, TRUE, TRUE, 0);
957 gtk_widget_grab_default (fontseldiag->ok_button);
959 fontseldiag->apply_button = gtk_button_new_with_label(_("Apply"));
960 GTK_WIDGET_SET_FLAGS (fontseldiag->apply_button, GTK_CAN_DEFAULT);
961 /*gtk_widget_show(fontseldiag->apply_button);*/
962 gtk_box_pack_start (GTK_BOX(fontseldiag->action_area),
963 fontseldiag->apply_button, TRUE, TRUE, 0);
965 fontseldiag->cancel_button = gtk_button_new_with_label(_("Cancel"));
966 GTK_WIDGET_SET_FLAGS (fontseldiag->cancel_button, GTK_CAN_DEFAULT);
967 gtk_widget_show(fontseldiag->cancel_button);
968 gtk_box_pack_start (GTK_BOX(fontseldiag->action_area),
969 fontseldiag->cancel_button, TRUE, TRUE, 0);
975 gtk_font_selection_dialog_new (const gchar *title)
977 GtkFontSelectionDialog *fontseldiag;
979 fontseldiag = gtk_type_new (GTK_TYPE_FONT_SELECTION_DIALOG);
980 gtk_window_set_title (GTK_WINDOW (fontseldiag),
981 title ? title : _("Font Selection"));
983 return GTK_WIDGET (fontseldiag);
987 gtk_font_selection_dialog_get_font_name (GtkFontSelectionDialog *fsd)
989 return gtk_font_selection_get_font_name(GTK_FONT_SELECTION(fsd->fontsel));
993 gtk_font_selection_dialog_get_font (GtkFontSelectionDialog *fsd)
995 return gtk_font_selection_get_font(GTK_FONT_SELECTION(fsd->fontsel));
999 gtk_font_selection_dialog_set_font_name (GtkFontSelectionDialog *fsd,
1000 const gchar *fontname)
1002 return gtk_font_selection_set_font_name(GTK_FONT_SELECTION(fsd->fontsel),
1007 gtk_font_selection_dialog_get_preview_text (GtkFontSelectionDialog *fsd)
1009 return gtk_font_selection_get_preview_text(GTK_FONT_SELECTION(fsd->fontsel));
1013 gtk_font_selection_dialog_set_preview_text (GtkFontSelectionDialog *fsd,
1016 gtk_font_selection_set_preview_text(GTK_FONT_SELECTION(fsd->fontsel), text);
1020 /* This turns auto-shrink off if the user resizes the width of the dialog.
1021 It also turns it back on again if the user resizes it back to its normal
1024 gtk_font_selection_dialog_on_configure (GtkWidget *widget,
1025 GdkEventConfigure *event,
1026 GtkFontSelectionDialog *fsd)
1028 /* This sets the initial width. */
1029 if (fsd->dialog_width == -1)
1030 fsd->dialog_width = event->width;
1031 else if (fsd->auto_resize && fsd->dialog_width != event->width)
1033 fsd->auto_resize = FALSE;
1034 gtk_window_set_policy(GTK_WINDOW(fsd), FALSE, TRUE, FALSE);
1036 else if (!fsd->auto_resize && fsd->dialog_width == event->width)
1038 fsd->auto_resize = TRUE;
1039 gtk_window_set_policy(GTK_WINDOW(fsd), FALSE, TRUE, TRUE);