widget-font-selector.c 8.63 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
	 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);
43
	 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
		 return;
	 }

	 display_font = gnome_get_display_font (
		 name,
		 fs->is_bold ? GNOME_FONT_BOLD : GNOME_FONT_BOOK,
		 fs->is_italic,
		 fs->size,
53
		 fs->resolution_adjustment_factor);
Arturo Espinosa's avatar
Arturo Espinosa committed
54

55
	 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
		 return;
	 }

60
	 if (!display_font->gdk_font) {
Arturo Espinosa's avatar
Arturo Espinosa committed
61 62 63 64 65 66 67
		 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
	 row = GPOINTER_TO_INT (style_list->selection->data);

137
	 switch (row) {
Arturo Espinosa's avatar
Arturo Espinosa committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
	 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
	 GtkCList *style_list = GTK_CLIST (fs->font_style_list);
	 int i;

165
	 for (i = 0; styles [i] != NULL; i++) {
Arturo Espinosa's avatar
Arturo Espinosa committed
166 167 168 169 170 171 172 173
		 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
	 char *text;
	 double size;

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

204 205 206 207 208
static void
fs_fill_font_size_list (FontSelector *fs)
{
	int i;
	
209
	for (i = 0; gnumeric_point_sizes [i] != 0; i++) {
210 211
		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
	fs->resolution_adjustment_factor = 1.;
249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271
	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
272
fs_class_init (GtkObjectClass *Class)
273
{
Jody Goldberg's avatar
Jody Goldberg committed
274
	Class->destroy = fs_destroy;
275 276 277 278 279 280 281 282 283

	fs_parent_class = gtk_type_class (gtk_hbox_get_type ());
}

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

284
	if (!fs_type) {
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309
		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
310 311 312 313 314 315 316 317 318 319

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

void
320 321
font_selector_set_name (FontSelector *fs,
			const char *font_name)
Arturo Espinosa's avatar
Arturo Espinosa committed
322 323 324
{
	GList *l;
	int row;
325

Arturo Espinosa's avatar
Arturo Espinosa committed
326 327
	g_return_if_fail (fs != NULL);
	g_return_if_fail (IS_FONT_SELECTOR (fs));
328
	g_return_if_fail (font_name != NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
329

330 331
	for (row = 0, l = gnumeric_font_family_list; l; l = l->next, row++) {
		if (strcasecmp (font_name, l->data) == 0)
Arturo Espinosa's avatar
Arturo Espinosa committed
332 333 334 335
			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
}

void
font_selector_set_style (FontSelector *fs,
			 gboolean is_bold,
			 gboolean is_italic)
{
	int n;

	g_return_if_fail (fs != NULL);
	g_return_if_fail (IS_FONT_SELECTOR (fs));

	if (is_bold) {
Arturo Espinosa's avatar
Arturo Espinosa committed
351 352 353 354 355 356 357 358 359 360 361
		if (is_italic)
			n = 2;
		else
			n = 1;
	} else {
		if (is_italic)
			n = 3;
		else
			n = 0;
	}
	select_row (fs->font_style_list, n);
362 363 364 365 366 367 368 369 370 371
}

void
font_selector_set_points (FontSelector *fs,
			  double point_size)
{
	int i;

	g_return_if_fail (fs != NULL);
	g_return_if_fail (IS_FONT_SELECTOR (fs));
Arturo Espinosa's avatar
Arturo Espinosa committed
372

373
	for (i = 0; gnumeric_point_sizes [i] != 0; i++) {
374
		if (gnumeric_point_sizes [i] == point_size) {
Arturo Espinosa's avatar
Arturo Espinosa committed
375
			select_row (fs->font_size_list, i);
376
			break;
Arturo Espinosa's avatar
Arturo Espinosa committed
377 378 379
		}
	}

380
	if (gnumeric_point_sizes [i] == 0) {
Arturo Espinosa's avatar
Arturo Espinosa committed
381 382
		char buffer [20];

383
		sprintf (buffer, "%g", point_size);
Arturo Espinosa's avatar
Arturo Espinosa committed
384 385 386 387 388
		
		gtk_entry_set_text (GTK_ENTRY (fs->font_size_entry), buffer);
	}
}

389 390 391 392 393 394 395 396 397
void
font_selector_set_screen_res (FontSelector *fs, float h_dpi, float v_dpi)
{
	g_return_if_fail (IS_FONT_SELECTOR (fs));

	fs->resolution_adjustment_factor = MIN(h_dpi, v_dpi) / 72.;
	reload_preview (fs);
}