widget-font-selector.c 8.04 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13
/*
 * A font selector widget.  This is a simplified version of the
 * GnomePrint font selector widget.
 *
 * Author:
 *   Miguel de Icaza (miguel@gnu.org)
 */
#include <config.h>
#include <stdlib.h>
#include <stdio.h>
#include "widget-font-selector.h"
#include <libgnome/gnome-defs.h>
#include <libgnome/gnome-i18n.h>
Arturo Espinosa's avatar
Arturo Espinosa committed
14
#include <string.h>
15
#include "../global-gnome-font.h"
16 17 18 19 20 21 22 23

/* 
 * Inside this file we define a number of aliases for the
 * FontSelector object, a short hand for it is FS
 *
 * I do want to avoid typing.
 */ 
#define FS(x) FONT_SELECTOR(x)
Arturo Espinosa's avatar
Arturo Espinosa committed
24

25 26 27 28 29
typedef FontSelector Fs;
typedef FontSelectorClass FsClass;

static GtkHBoxClass *fs_parent_class;

30 31 32
static void
reload_preview (FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
33 34 35 36 37 38 39 40 41 42 43
	 char *name = gtk_entry_get_text (GTK_ENTRY (fs->font_name_entry));
	 GtkStyle *style;
	 GnomeFont *gnome_font;
	 GnomeDisplayFont *display_font;

	 gnome_font = gnome_font_new_closest (
		 name,
		 fs->is_bold ? GNOME_FONT_BOLD : GNOME_FONT_BOOK,
		 fs->is_italic,
		 fs->size);
	 if (!gnome_font){
Morten Welinder's avatar
Morten Welinder committed
44
		 g_warning ("Uh oh, cannot get the font!");
Arturo Espinosa's avatar
Arturo Espinosa committed
45 46 47 48 49 50 51 52 53 54 55
		 return;
	 }

	 display_font = gnome_get_display_font (
		 name,
		 fs->is_bold ? GNOME_FONT_BOLD : GNOME_FONT_BOOK,
		 fs->is_italic,
		 fs->size,
		 1.0);

	 if (!display_font){
Morten Welinder's avatar
Morten Welinder committed
56
		 g_warning ("Uh oh, cannot get the display font");
Arturo Espinosa's avatar
Arturo Espinosa committed
57 58 59 60 61 62 63 64 65 66 67
		 return;
	 }

	 if (!display_font->gdk_font){
		 gtk_object_unref (GTK_OBJECT (gnome_font));
		 return;
	 }

	 fs->gnome_font = gnome_font;
	 fs->display_font = display_font;

68
	 style = gtk_style_copy (fs->font_preview->style);
Arturo Espinosa's avatar
Arturo Espinosa committed
69 70 71 72 73 74
	 gdk_font_unref (style->font);
	 style->font = fs->display_font->gdk_font;
	 gdk_font_ref (style->font);

	 gtk_widget_set_style (fs->font_preview, style);
	 gtk_style_unref (style);
75
}
Arturo Espinosa's avatar
Arturo Espinosa committed
76

77 78 79 80 81 82 83 84 85 86 87 88 89 90
/*
 * We can not moveto a list element until it is realized.
 */
static void
list_realized (GtkWidget *widget, gpointer user_data)
{
	GtkCList * clist = GTK_CLIST (widget);
	int row = 0;
	if (clist->selection)
		row = GPOINTER_TO_UINT (clist->selection->data);
	if (!gtk_clist_row_is_visible (clist, row))
		gtk_clist_moveto (clist, row, 0, 0.5, 0.0);
}

91 92 93
static void
font_selected (GtkCList *font_list, int col, int row, GdkEvent *event, FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
94 95 96 97 98 99
	 gchar *text;

	 gtk_clist_get_text (font_list, GPOINTER_TO_INT (font_list->selection->data), 0, &text);
	 gtk_entry_set_text (GTK_ENTRY (fs->font_name_entry), text);

	 reload_preview (fs);
100
}
Arturo Espinosa's avatar
Arturo Espinosa committed
101

102 103 104
static void
fs_fill_font_name_list (FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
105 106
	 GList *l;

107
	 for (l = gnumeric_font_family_list; l; l = l->next){
Arturo Espinosa's avatar
Arturo Espinosa committed
108 109 110 111 112 113 114 115 116 117
		 char *name = l->data;
		 char *array [1];

		 array [0] = name;

		 gtk_clist_append (GTK_CLIST (fs->font_name_list), array);
	 }

	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_name_list), "select_row",
118 119 120 121
		 GTK_SIGNAL_FUNC (font_selected), fs);
	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_name_list), "realize",
		 GTK_SIGNAL_FUNC (list_realized), NULL);
122
}
Arturo Espinosa's avatar
Arturo Espinosa committed
123

124
static char *styles [] = {
Arturo Espinosa's avatar
Arturo Espinosa committed
125 126 127 128 129
	 N_("Normal"),
	 N_("Bold"),
	 N_("Bold italic"),
	 N_("Italic"),
	 NULL
130
};
Arturo Espinosa's avatar
Arturo Espinosa committed
131

132 133 134
static void
style_selected (GtkCList *style_list, int col, int row, GdkEvent *event, FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	 row = GPOINTER_TO_INT (style_list->selection->data);

	 switch (row){
	 case 0:
		 fs->is_bold = fs->is_italic = FALSE;
		 break;
	 case 1:
		 fs->is_bold = TRUE;
		 fs->is_italic = FALSE;
		 break;

	 case 2:
		 fs->is_bold = fs->is_italic = TRUE;
		 break;
	 case 3:
		 fs->is_italic = TRUE;
		 fs->is_bold = FALSE;
		 break;
	 }

	 gtk_entry_set_text (GTK_ENTRY (fs->font_style_entry), _(styles [row]));
	 reload_preview (fs);
157
}
Arturo Espinosa's avatar
Arturo Espinosa committed
158

159 160 161
static void
fs_fill_font_style_list (FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
162 163 164 165 166 167 168 169 170 171 172 173
	 GtkCList *style_list = GTK_CLIST (fs->font_style_list);
	 int i;

	 for (i = 0; styles [i] != NULL; i++){
		 char *array [1];
		 array [0] = _(styles [i]);

		 gtk_clist_append (style_list, array);
	 }
	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_style_list), "select_row",
		 GTK_SIGNAL_FUNC(style_selected), fs);
174 175 176
	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_name_list), "realize",
		 GTK_SIGNAL_FUNC(list_realized), NULL);
177
}
Arturo Espinosa's avatar
Arturo Espinosa committed
178

179 180 181
static void
size_selected (GtkCList *size_list, int col, int row, GdkEvent *event, FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
182 183 184 185 186
	 gchar *text;

	 row = GPOINTER_TO_INT (size_list->selection->data);
	 gtk_clist_get_text (size_list, row, 0, &text);
	 gtk_entry_set_text (GTK_ENTRY (fs->font_size_entry), text);
187
	 fs->size = atof (text);
188
}
Arturo Espinosa's avatar
Arturo Espinosa committed
189

190 191 192
static void
size_changed (GtkEntry *entry, FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
193 194 195 196 197 198 199 200 201
	 char *text;
	 double size;

	 text = gtk_entry_get_text (entry);
	 size = atof (text);
	 if (size > 0 && size < 128){
		 fs->size = size;
		 reload_preview (fs);
	 }
202
}
Arturo Espinosa's avatar
Arturo Espinosa committed
203

204 205 206 207 208 209 210 211
static void
fs_fill_font_size_list (FontSelector *fs)
{
	int i;
	
	for (i = 0; gnumeric_point_sizes [i] != 0; i++){
		char buffer [10];
		char *array [1];
212
		
213
		sprintf (buffer, "%d", gnumeric_point_sizes [i]);
214 215 216 217 218 219
		array [0] = buffer;
		gtk_clist_append (GTK_CLIST (fs->font_size_list), array);
	}
	gtk_signal_connect (
		GTK_OBJECT (fs->font_size_list), "select_row",
		GTK_SIGNAL_FUNC(size_selected), fs);
220 221 222
	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_name_list), "realize",
		 GTK_SIGNAL_FUNC (list_realized), NULL);
223
	
224 225 226 227 228 229 230 231 232 233 234 235
	gtk_signal_connect (
		GTK_OBJECT (fs->font_size_entry), "changed",
		GTK_SIGNAL_FUNC (size_changed), fs);
}

static void
fs_init (FontSelector *fs)
{
	GtkWidget *toplevel;
	GtkWidget *old_parent;
	
	fs->gui = glade_xml_new (GNUMERIC_GLADEDIR "/font-sel.glade", NULL);
Michael Meeks's avatar
Michael Meeks committed
236 237
	if (!fs->gui) {
		g_warning ("Could not load font-sel.glade");
238 239 240 241 242 243 244 245
		return;
	}
	toplevel = glade_xml_get_widget (fs->gui, "toplevel-table");
	old_parent = gtk_widget_get_toplevel (toplevel);
	gtk_widget_reparent (toplevel, GTK_WIDGET (fs));
	gtk_widget_destroy (old_parent);
	gtk_widget_queue_resize (toplevel);

246
	fs->size = 10;
247
	fs->is_bold = fs->is_italic = FALSE;
248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270
	fs->font_name_entry  = glade_xml_get_widget (fs->gui, "font-name-entry");
	fs->font_style_entry = glade_xml_get_widget (fs->gui, "font-style-entry");
	fs->font_size_entry  = glade_xml_get_widget (fs->gui, "font-size-entry");
	fs->font_name_list  = glade_xml_get_widget (fs->gui, "font-name-list");
	fs->font_style_list = glade_xml_get_widget (fs->gui, "font-style-list");
	fs->font_size_list  = glade_xml_get_widget (fs->gui, "font-size-list");
	fs->font_preview = glade_xml_get_widget (fs->gui, "preview-entry");
	fs_fill_font_style_list (fs);
	fs_fill_font_name_list (fs);
	fs_fill_font_size_list (fs);
}

static void
fs_destroy (GtkObject *object)
{
	FontSelector *fs = FONT_SELECTOR (object);

	if (fs->gnome_font)
		gtk_object_unref (GTK_OBJECT (fs->gnome_font));
	((GtkObjectClass *)fs_parent_class)->destroy (object);
}

static void
Jody Goldberg's avatar
Jody Goldberg committed
271
fs_class_init (GtkObjectClass *Class)
272
{
Jody Goldberg's avatar
Jody Goldberg committed
273
	Class->destroy = fs_destroy;
274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308

	fs_parent_class = gtk_type_class (gtk_hbox_get_type ());
}

GtkType
font_selector_get_type (void)
{
	static GtkType fs_type = 0;

	if (!fs_type){
		GtkTypeInfo fs_info = {
			"FontSelector",
			sizeof (FontSelector),
			sizeof (FontSelectorClass),
			(GtkClassInitFunc) fs_class_init,
			(GtkObjectInitFunc) fs_init,
			NULL, /* reserved 1 */
			NULL, /* reserved 2 */
			(GtkClassInitFunc) NULL
		};

		fs_type = gtk_type_unique (gtk_hbox_get_type (), &fs_info);
	}

	return fs_type;
}

GtkWidget *
font_selector_new (void)
{
	GtkWidget *w;

	w = gtk_type_new (FONT_SELECTOR_TYPE);
	return w;
}
Arturo Espinosa's avatar
Arturo Espinosa committed
309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329

static void
select_row (GtkWidget *list, int row)
{
	GtkCList *cl = GTK_CLIST (list);
	
	gtk_clist_select_row (cl, row, 0);
}

void
font_selector_set (FontSelector *fs,
		   const char *name, gboolean is_bold, gboolean is_italic, double size)
{
	GList *l;
	int row;
	int n, i;
	
	g_return_if_fail (fs != NULL);
	g_return_if_fail (IS_FONT_SELECTOR (fs));
	g_return_if_fail (name != NULL);

330
	for (row = 0, l = gnumeric_font_family_list; l; l = l->next, row++){
Arturo Espinosa's avatar
Arturo Espinosa committed
331 332 333 334 335
		if (strcasecmp (name, l->data) == 0)
			break;
	}

	if (l != NULL)
336
		select_row (fs->font_name_list, row);
Arturo Espinosa's avatar
Arturo Espinosa committed
337 338 339 340 341 342 343 344 345 346 347 348 349 350

	if (is_bold){
		if (is_italic)
			n = 2;
		else
			n = 1;
	} else {
		if (is_italic)
			n = 3;
		else
			n = 0;
	}
	select_row (fs->font_style_list, n);

351 352
	for (i = 0; gnumeric_point_sizes [i] != 0; i++) {
		if (gnumeric_point_sizes [i] == size) {
Arturo Espinosa's avatar
Arturo Espinosa committed
353
			select_row (fs->font_size_list, i);
354
			break;
Arturo Espinosa's avatar
Arturo Espinosa committed
355 356 357
		}
	}

358
	if (gnumeric_point_sizes [i] == 0){
Arturo Espinosa's avatar
Arturo Espinosa committed
359 360 361 362 363 364 365 366
		char buffer [20];

		sprintf (buffer, "%g", size);
		
		gtk_entry_set_text (GTK_ENTRY (fs->font_size_entry), buffer);
	}
}