widget-font-selector.c 8.81 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
		 gtk_object_unref (GTK_OBJECT (gnome_font));
Morten Welinder's avatar
Morten Welinder committed
57
		 g_warning ("Uh oh, cannot get the display font");
Arturo Espinosa's avatar
Arturo Espinosa committed
58 59 60
		 return;
	 }

61
	 if (!display_font->gdk_font) {
Arturo Espinosa's avatar
Arturo Espinosa committed
62 63 64 65
		 gtk_object_unref (GTK_OBJECT (gnome_font));
		 return;
	 }

Morten Welinder's avatar
Morten Welinder committed
66 67 68
	 if (fs->gnome_font)
		 gtk_object_unref (GTK_OBJECT (fs->gnome_font));

Arturo Espinosa's avatar
Arturo Espinosa committed
69 70 71
	 fs->gnome_font = gnome_font;
	 fs->display_font = display_font;

72
	 style = gtk_style_copy (fs->font_preview->style);
Arturo Espinosa's avatar
Arturo Espinosa committed
73 74 75 76 77 78
	 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);
79
}
Arturo Espinosa's avatar
Arturo Espinosa committed
80

81 82 83 84 85 86 87 88 89 90 91 92 93 94
/*
 * 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);
}

95 96 97
static void
font_selected (GtkCList *font_list, int col, int row, GdkEvent *event, FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
98 99 100 101 102 103
	 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);
104
}
Arturo Espinosa's avatar
Arturo Espinosa committed
105

106 107 108
static void
fs_fill_font_name_list (FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
109 110
	 GList *l;

111
	 for (l = gnumeric_font_family_list; l; l = l->next) {
Arturo Espinosa's avatar
Arturo Espinosa committed
112 113 114 115 116 117 118 119 120 121
		 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",
122 123 124 125
		 GTK_SIGNAL_FUNC (font_selected), fs);
	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_name_list), "realize",
		 GTK_SIGNAL_FUNC (list_realized), NULL);
126
}
Arturo Espinosa's avatar
Arturo Espinosa committed
127

128
static char *styles [] = {
Arturo Espinosa's avatar
Arturo Espinosa committed
129 130 131 132 133
	 N_("Normal"),
	 N_("Bold"),
	 N_("Bold italic"),
	 N_("Italic"),
	 NULL
134
};
Arturo Espinosa's avatar
Arturo Espinosa committed
135

136 137 138
static void
style_selected (GtkCList *style_list, int col, int row, GdkEvent *event, FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
139 140
	 row = GPOINTER_TO_INT (style_list->selection->data);

141
	 switch (row) {
Arturo Espinosa's avatar
Arturo Espinosa committed
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
	 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);
161
}
Arturo Espinosa's avatar
Arturo Espinosa committed
162

163 164 165
static void
fs_fill_font_style_list (FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
166 167 168
	 GtkCList *style_list = GTK_CLIST (fs->font_style_list);
	 int i;

169
	 for (i = 0; styles [i] != NULL; i++) {
Arturo Espinosa's avatar
Arturo Espinosa committed
170 171 172 173 174 175 176 177
		 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);
178 179 180
	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_name_list), "realize",
		 GTK_SIGNAL_FUNC(list_realized), NULL);
181
}
Arturo Espinosa's avatar
Arturo Espinosa committed
182

183 184 185
static void
size_selected (GtkCList *size_list, int col, int row, GdkEvent *event, FontSelector *fs)
{
Arturo Espinosa's avatar
Arturo Espinosa committed
186 187 188 189 190
	 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);
191
	 fs->size = atof (text);
192
}
Arturo Espinosa's avatar
Arturo Espinosa committed
193

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

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

208 209 210 211 212
static void
fs_fill_font_size_list (FontSelector *fs)
{
	int i;
	
213
	for (i = 0; gnumeric_point_sizes [i] != 0; i++) {
214 215
		char buffer [10];
		char *array [1];
216
		
217
		sprintf (buffer, "%d", gnumeric_point_sizes [i]);
218 219 220 221 222 223
		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);
224 225 226
	 gtk_signal_connect (
		 GTK_OBJECT (fs->font_name_list), "realize",
		 GTK_SIGNAL_FUNC (list_realized), NULL);
227
	
228 229 230 231 232 233 234 235 236 237
	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;
Morten Welinder's avatar
Morten Welinder committed
238 239 240 241

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

242
	fs->gui = glade_xml_new (GNUMERIC_GLADEDIR "/font-sel.glade", NULL);
Michael Meeks's avatar
Michael Meeks committed
243 244
	if (!fs->gui) {
		g_warning ("Could not load font-sel.glade");
245
                return;
246
	}
247

248 249 250 251 252 253
	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);

254
	fs->size = 10;
255
	fs->is_bold = fs->is_italic = FALSE;
256
	fs->resolution_adjustment_factor = 1.;
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279
	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
280
fs_class_init (GtkObjectClass *Class)
281
{
Jody Goldberg's avatar
Jody Goldberg committed
282
	Class->destroy = fs_destroy;
283 284 285 286 287 288 289 290 291

	fs_parent_class = gtk_type_class (gtk_hbox_get_type ());
}

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

292
	if (!fs_type) {
293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317
		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
318 319 320 321 322 323 324 325 326 327

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

void
328 329
font_selector_set_name (FontSelector *fs,
			const char *font_name)
Arturo Espinosa's avatar
Arturo Espinosa committed
330 331 332
{
	GList *l;
	int row;
333

Arturo Espinosa's avatar
Arturo Espinosa committed
334 335
	g_return_if_fail (fs != NULL);
	g_return_if_fail (IS_FONT_SELECTOR (fs));
336
	g_return_if_fail (font_name != NULL);
Arturo Espinosa's avatar
Arturo Espinosa committed
337

338 339
	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
340 341 342 343
			break;
	}

	if (l != NULL)
344
		select_row (fs->font_name_list, row);
Arturo Espinosa's avatar
Arturo Espinosa committed
345

346 347 348 349 350 351 352 353 354 355 356 357 358
}

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
359 360 361 362 363 364 365 366 367 368 369
		if (is_italic)
			n = 2;
		else
			n = 1;
	} else {
		if (is_italic)
			n = 3;
		else
			n = 0;
	}
	select_row (fs->font_style_list, n);
370 371 372 373 374 375 376 377 378 379
}

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
380

381
	for (i = 0; gnumeric_point_sizes [i] != 0; i++) {
382
		if (gnumeric_point_sizes [i] == point_size) {
Arturo Espinosa's avatar
Arturo Espinosa committed
383
			select_row (fs->font_size_list, i);
384
			break;
Arturo Espinosa's avatar
Arturo Espinosa committed
385 386 387
		}
	}

388
	if (gnumeric_point_sizes [i] == 0) {
Arturo Espinosa's avatar
Arturo Espinosa committed
389 390
		char buffer [20];

391
		sprintf (buffer, "%g", point_size);
Arturo Espinosa's avatar
Arturo Espinosa committed
392 393 394 395 396
		
		gtk_entry_set_text (GTK_ENTRY (fs->font_size_entry), buffer);
	}
}

397 398 399 400 401 402 403 404 405
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);
}