1 /* FontSimple.c- simplified font configuration panel
2  *
3  *  WPrefs - Window Maker Preferences Program
4  *
5  *  Copyright (c) 1998-2004 Alfredo K. Kojima
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License along
18  *  with this program; if not, write to the Free Software Foundation, Inc.,
19  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20  */
21 
22 #include "WPrefs.h"
23 #include <unistd.h>
24 #include <fontconfig/fontconfig.h>
25 
26 /* workaround for older fontconfig, that doesn't define these constants */
27 #ifndef FC_WEIGHT_NORMAL
28 /* Weights */
29 # define FC_WEIGHT_THIN              10
30 # define FC_WEIGHT_EXTRALIGHT        40
31 # define FC_WEIGHT_ULTRALIGHT        FC_WEIGHT_EXTRALIGHT
32 # define FC_WEIGHT_REGULAR           80
33 # define FC_WEIGHT_NORMAL            FC_WEIGHT_REGULAR
34 # define FC_WEIGHT_SEMIBOLD          FC_WEIGHT_DEMIBOLD
35 # define FC_WEIGHT_EXTRABOLD         205
36 # define FC_WEIGHT_ULTRABOLD         FC_WEIGHT_EXTRABOLD
37 # define FC_WEIGHT_HEAVY             FC_WEIGHT_BLACK
38 /* Widths */
39 # define FC_WIDTH                    "width"
40 # define FC_WIDTH_ULTRACONDENSED     50
41 # define FC_WIDTH_EXTRACONDENSED     63
42 # define FC_WIDTH_CONDENSED          75
43 # define FC_WIDTH_SEMICONDENSED      87
44 # define FC_WIDTH_NORMAL             100
45 # define FC_WIDTH_SEMIEXPANDED       113
46 # define FC_WIDTH_EXPANDED           125
47 # define FC_WIDTH_EXTRAEXPANDED      150
48 # define FC_WIDTH_ULTRAEXPANDED      200
49 #endif
50 
51 #define SAMPLE_TEXT "The Lazy Fox Jumped Ipsum Foobar 1234 - 56789"
52 
53 typedef struct {
54 	int weight;
55 	int width;
56 	int slant;
57 } FontStyle;
58 
59 typedef struct {
60 	char *name;
61 	int stylen;
62 	FontStyle *styles;
63 } FontFamily;
64 
65 typedef struct {
66 	int familyn;
67 	FontFamily *families;
68 } FontList;
69 
70 typedef struct _Panel {
71 	WMBox *box;
72 	char *sectionName;
73 
74 	char *description;
75 
76 	CallbackRec callbacks;
77 
78 	WMWidget *parent;
79 
80 	WMPopUpButton *optionP;
81 
82 	WMList *familyL;
83 	WMList *styleL;
84 
85 	WMList *sizeL;
86 
87 	WMTextField *sampleT;
88 
89 	FontList *fonts;
90 } _Panel;
91 
92 #define ICON_FILE	"fonts"
93 
94 static const struct {
95 	const char *option;
96 	const char *label;
97 } fontOptions[] = {
98 	{ "WindowTitleFont", N_("Window Title") },
99 	{ "MenuTitleFont", N_("Menu Title") },
100 	{ "MenuTextFont", N_("Menu Text") },
101 	{ "IconTitleFont", N_("Icon Title") },
102 	{ "ClipTitleFont", N_("Clip Title") },
103 	{ "LargeDisplayFont", N_("Desktop Caption") },
104 	{ "SystemFont", N_("System Font") },
105 	{ "BoldSystemFont", N_("Bold System Font")}
106 };
107 
108 static const char *standardSizes[] = {
109 	"6",
110 	"8",
111 	"9",
112 	"10",
113 	"11",
114 	"12",
115 	"13",
116 	"14",
117 	"15",
118 	"16",
119 	"18",
120 	"20",
121 	"22",
122 	"24",
123 	"28",
124 	"32",
125 	"36",
126 	"48",
127 	"64",
128 	"72",
129 	NULL
130 };
131 
132 static const struct {
133 	int weight;
134 	const char *name;
135 } fontWeights[] = {
136 	{ FC_WEIGHT_THIN, "Thin" },
137 	{ FC_WEIGHT_EXTRALIGHT, "ExtraLight" },
138 	{ FC_WEIGHT_LIGHT, "Light" },
139 	{ FC_WEIGHT_NORMAL, "Normal" },
140 	{ FC_WEIGHT_MEDIUM, "" },
141 	{ FC_WEIGHT_DEMIBOLD, "DemiBold" },
142 	{ FC_WEIGHT_BOLD, "Bold" },
143 	{ FC_WEIGHT_EXTRABOLD, "ExtraBold" },
144 	{ FC_WEIGHT_BLACK, "Black" }
145 };
146 
147 static const struct {
148 	int slant;
149 	const char *name;
150 } fontSlants[] = {
151 	{ FC_SLANT_ROMAN, "" },
152 	{ FC_SLANT_ITALIC, "Italic" },
153 	{ FC_SLANT_OBLIQUE, "Oblique" }
154 };
155 
156 static const struct {
157 	int width;
158 	const char *name;
159 } fontWidths[] = {
160 	{ FC_WIDTH_ULTRACONDENSED, "UltraCondensed" },
161 	{ FC_WIDTH_EXTRACONDENSED, "ExtraCondensed" },
162 	{ FC_WIDTH_CONDENSED, "Condensed" },
163 	{ FC_WIDTH_SEMICONDENSED, "SemiCondensed" },
164 	{ FC_WIDTH_NORMAL, "" },
165 	{ FC_WIDTH_SEMIEXPANDED, "SemiExpanded" },
166 	{ FC_WIDTH_EXPANDED, "Expanded" },
167 	{ FC_WIDTH_EXTRAEXPANDED, "ExtraExpanded" },
168 	{ FC_WIDTH_ULTRAEXPANDED, "UltraExpanded" },
169 };
170 
compare_family(const void * a,const void * b)171 static int compare_family(const void *a, const void *b)
172 {
173 	FontFamily *fa = (FontFamily *) a;
174 	FontFamily *fb = (FontFamily *) b;
175 	return strcmp(fa->name, fb->name);
176 }
177 
compare_styles(const void * a,const void * b)178 static int compare_styles(const void *a, const void *b)
179 {
180 	FontStyle *sa = (FontStyle *) a;
181 	FontStyle *sb = (FontStyle *) b;
182 	int compare;
183 
184 	compare = sa->weight - sb->weight;
185 	if (compare != 0)
186 		return compare;
187 	compare = sa->slant - sb->slant;
188 	if (compare != 0)
189 		return compare;
190 	return (sa->width - sb->width);
191 }
192 
lookup_available_fonts(_Panel * panel)193 static void lookup_available_fonts(_Panel * panel)
194 {
195 	FcPattern *pat = FcPatternCreate();
196 	FcObjectSet *os;
197 	FcFontSet *fonts;
198 	FontFamily *family;
199 
200 	os = FcObjectSetBuild(FC_FAMILY, FC_WEIGHT, FC_WIDTH, FC_SLANT, NULL);
201 
202 	fonts = FcFontList(0, pat, os);
203 
204 	if (fonts) {
205 		int i;
206 
207 		panel->fonts = wmalloc(sizeof(FontList));
208 		panel->fonts->familyn = 0;
209 		panel->fonts->families = wmalloc(sizeof(FontFamily) * fonts->nfont);
210 
211 		for (i = 0; i < fonts->nfont; i++) {
212 			char *name;
213 			int weight, slant, width;
214 			int j, found;
215 
216 			if (FcPatternGetString(fonts->fonts[i], FC_FAMILY, 0, (FcChar8 **) & name) !=
217 			    FcResultMatch)
218 				continue;
219 
220 			if (FcPatternGetInteger(fonts->fonts[i], FC_WEIGHT, 0, &weight) != FcResultMatch)
221 				weight = FC_WEIGHT_MEDIUM;
222 
223 			if (FcPatternGetInteger(fonts->fonts[i], FC_WIDTH, 0, &width) != FcResultMatch)
224 				width = FC_WIDTH_NORMAL;
225 
226 			if (FcPatternGetInteger(fonts->fonts[i], FC_SLANT, 0, &slant) != FcResultMatch)
227 				slant = FC_SLANT_ROMAN;
228 
229 			found = -1;
230 			for (j = 0; j < panel->fonts->familyn && found < 0; j++)
231 				if (strcasecmp(panel->fonts->families[j].name, name) == 0)
232 					found = j;
233 
234 			if (found < 0) {
235 				panel->fonts->families[panel->fonts->familyn++].name = wstrdup(name);
236 				family = panel->fonts->families + panel->fonts->familyn - 1;
237 				family->stylen = 0;
238 				family->styles = NULL;
239 			} else
240 				family = panel->fonts->families + found;
241 
242 			family->stylen++;
243 			family->styles = wrealloc(family->styles, sizeof(FontStyle) * family->stylen);
244 			family->styles[family->stylen - 1].weight = weight;
245 			family->styles[family->stylen - 1].slant = slant;
246 			family->styles[family->stylen - 1].width = width;
247 		}
248 		qsort(panel->fonts->families, panel->fonts->familyn, sizeof(FontFamily), compare_family);
249 
250 		for (i = 0; i < panel->fonts->familyn; i++) {
251 			qsort(panel->fonts->families[i].styles, panel->fonts->families[i].stylen,
252 			      sizeof(FontStyle), compare_styles);
253 		}
254 
255 		FcFontSetDestroy(fonts);
256 	}
257 	if (os)
258 		FcObjectSetDestroy(os);
259 	if (pat)
260 		FcPatternDestroy(pat);
261 
262 	panel->fonts->families[panel->fonts->familyn++].name = wstrdup("sans serif");
263 	family = panel->fonts->families + panel->fonts->familyn - 1;
264 	family->styles = wmalloc(sizeof(FontStyle) * 2);
265 	family->stylen = 2;
266 	family->styles[0].weight = FC_WEIGHT_MEDIUM;
267 	family->styles[0].slant = FC_SLANT_ROMAN;
268 	family->styles[0].width = FC_WIDTH_NORMAL;
269 	family->styles[1].weight = FC_WEIGHT_BOLD;
270 	family->styles[1].slant = FC_SLANT_ROMAN;
271 	family->styles[1].width = FC_WIDTH_NORMAL;
272 
273 	panel->fonts->families[panel->fonts->familyn++].name = wstrdup("serif");
274 	family = panel->fonts->families + panel->fonts->familyn - 1;
275 	family->styles = wmalloc(sizeof(FontStyle) * 2);
276 	family->stylen = 2;
277 	family->styles[0].weight = FC_WEIGHT_MEDIUM;
278 	family->styles[0].slant = FC_SLANT_ROMAN;
279 	family->styles[0].width = FC_WIDTH_NORMAL;
280 	family->styles[1].weight = FC_WEIGHT_BOLD;
281 	family->styles[1].slant = FC_SLANT_ROMAN;
282 	family->styles[1].width = FC_WIDTH_NORMAL;
283 }
284 
getSelectedFont(_Panel * panel,FcChar8 * curfont)285 static char *getSelectedFont(_Panel * panel, FcChar8 * curfont)
286 {
287 	WMListItem *item;
288 	FcPattern *pat;
289 	char *name;
290 
291 	if (curfont)
292 		pat = FcNameParse(curfont);
293 	else
294 		pat = FcPatternCreate();
295 
296 	item = WMGetListSelectedItem(panel->familyL);
297 	if (item) {
298 		FcPatternDel(pat, FC_FAMILY);
299 		FcPatternAddString(pat, FC_FAMILY, (FcChar8 *) item->text);
300 	}
301 
302 	item = WMGetListSelectedItem(panel->styleL);
303 	if (item) {
304 		FontStyle *style = (FontStyle *) item->clientData;
305 
306 		FcPatternDel(pat, FC_WEIGHT);
307 		FcPatternAddInteger(pat, FC_WEIGHT, style->weight);
308 
309 		FcPatternDel(pat, FC_WIDTH);
310 		FcPatternAddInteger(pat, FC_WIDTH, style->width);
311 
312 		FcPatternDel(pat, FC_SLANT);
313 		FcPatternAddInteger(pat, FC_SLANT, style->slant);
314 	}
315 
316 	item = WMGetListSelectedItem(panel->sizeL);
317 	if (item) {
318 		FcPatternDel(pat, FC_PIXEL_SIZE);
319 		FcPatternAddDouble(pat, FC_PIXEL_SIZE, atoi(item->text));
320 	}
321 
322 	name = (char *)FcNameUnparse(pat);
323 	FcPatternDestroy(pat);
324 
325 	return name;
326 }
327 
updateSampleFont(_Panel * panel)328 static void updateSampleFont(_Panel * panel)
329 {
330 	WMMenuItem *item = WMGetPopUpButtonMenuItem(panel->optionP,
331 						    WMGetPopUpButtonSelectedItem(panel->optionP));
332 	char *fn = WMGetMenuItemRepresentedObject(item);
333 
334 	if (fn) {
335 		WMFont *font = WMCreateFont(WMWidgetScreen(panel->box), fn);
336 		if (font) {
337 			WMSetTextFieldFont(panel->sampleT, font);
338 			WMReleaseFont(font);
339 		}
340 	}
341 }
342 
selectedFamily(WMWidget * w,void * data)343 static void selectedFamily(WMWidget * w, void *data)
344 {
345 	_Panel *panel = (_Panel *) data;
346 	WMListItem *item;
347 	FontStyle *oldStyle = NULL;
348 	char buffer[1024];
349 
350 	/* Parameter not used, but tell the compiler that it is ok */
351 	(void) w;
352 
353 	item = WMGetListSelectedItem(panel->styleL);
354 	if (item)
355 		oldStyle = (FontStyle *) item->clientData;
356 
357 	item = WMGetListSelectedItem(panel->familyL);
358 
359 	if (item) {
360 		FontFamily *family = (FontFamily *) item->clientData;
361 		int i, oldi = 0, oldscore = 0;
362 
363 		WMClearList(panel->styleL);
364 		for (i = 0; i < family->stylen; i++) {
365 			int j;
366 			const char *weight = "", *slant = "", *width = "";
367 			WMListItem *item;
368 
369 			for (j = 0; j < wlengthof(fontWeights); j++)
370 				if (fontWeights[j].weight == family->styles[i].weight) {
371 					weight = fontWeights[j].name;
372 					break;
373 				}
374 			for (j = 0; j < wlengthof(fontWidths); j++)
375 				if (fontWidths[j].width == family->styles[i].width) {
376 					width = fontWidths[j].name;
377 					break;
378 				}
379 			for (j = 0; j < wlengthof(fontSlants); j++)
380 				if (fontSlants[j].slant == family->styles[i].slant) {
381 					slant = fontSlants[j].name;
382 					break;
383 				}
384 			sprintf(buffer, "%s%s%s%s%s",
385 				weight, *weight ? " " : "", slant, (*slant || *weight) ? " " : "", width);
386 			if (!buffer[0])
387 				strcpy(buffer, "Roman");
388 
389 			item = WMAddListItem(panel->styleL, buffer);
390 			item->clientData = family->styles + i;
391 
392 			if (oldStyle) {
393 				int score = 0;
394 
395 				if (oldStyle->width == family->styles[i].width)
396 					score |= 1;
397 				if (oldStyle->weight == family->styles[i].weight)
398 					score |= 2;
399 				if (oldStyle->slant == family->styles[i].slant)
400 					score |= 4;
401 
402 				if (score > oldscore) {
403 					oldi = i;
404 					oldscore = score;
405 				}
406 			}
407 		}
408 		WMSelectListItem(panel->styleL, oldi);
409 
410 		{
411 			int index = WMGetPopUpButtonSelectedItem(panel->optionP);
412 			WMMenuItem *item = WMGetPopUpButtonMenuItem(panel->optionP, index);
413 			FcChar8 *ofont;
414 			char *nfont;
415 
416 			ofont = (FcChar8 *) WMGetMenuItemRepresentedObject(item);
417 			nfont = getSelectedFont(panel, ofont);
418 			if (ofont)
419 				wfree(ofont);
420 			WMSetMenuItemRepresentedObject(item, nfont);
421 		}
422 		updateSampleFont(panel);
423 	}
424 }
425 
selected(WMWidget * w,void * data)426 static void selected(WMWidget * w, void *data)
427 {
428 	_Panel *panel = (_Panel *) data;
429 	int index = WMGetPopUpButtonSelectedItem(panel->optionP);
430 	WMMenuItem *item = WMGetPopUpButtonMenuItem(panel->optionP, index);
431 	FcChar8 *ofont;
432 	char *nfont;
433 
434 	/* Parameter not used, but tell the compiler that it is ok */
435 	(void) w;
436 
437 	ofont = (FcChar8 *) WMGetMenuItemRepresentedObject(item);
438 	nfont = getSelectedFont(panel, ofont);
439 	if (ofont)
440 		wfree(ofont);
441 
442 	WMSetMenuItemRepresentedObject(item, nfont);
443 
444 	updateSampleFont(panel);
445 }
446 
selectedOption(WMWidget * w,void * data)447 static void selectedOption(WMWidget * w, void *data)
448 {
449 	_Panel *panel = (_Panel *) data;
450 	int index = WMGetPopUpButtonSelectedItem(panel->optionP);
451 	WMMenuItem *item = WMGetPopUpButtonMenuItem(panel->optionP, index);
452 	char *font;
453 
454 	/* Parameter not used, but tell the compiler that it is ok */
455 	(void) w;
456 
457 	font = (char *)WMGetMenuItemRepresentedObject(item);
458 	if (font) {
459 		FcPattern *pat;
460 
461 		pat = FcNameParse((FcChar8 *) font);
462 		if (pat) {
463 			char *name;
464 			int weight, slant, width;
465 			double size;
466 			int distance, closest, found;
467 			int i;
468 
469 			FcDefaultSubstitute(pat);
470 
471 			if (FcPatternGetString(pat, FC_FAMILY, 0, (FcChar8 **) & name) != FcResultMatch)
472 				name = "sans serif";
473 
474 			found = 0;
475 			/* select family */
476 			for (i = 0; i < WMGetListNumberOfRows(panel->familyL); i++) {
477 				WMListItem *item = WMGetListItem(panel->familyL, i);
478 				FontFamily *family = (FontFamily *) item->clientData;
479 
480 				if (strcasecmp(family->name, name) == 0) {
481 					found = 1;
482 					WMSelectListItem(panel->familyL, i);
483 					WMSetListPosition(panel->familyL, i);
484 					break;
485 				}
486 			}
487 			if (!found)
488 				WMSelectListItem(panel->familyL, -1);
489 			selectedFamily(panel->familyL, panel);
490 
491 			/* select style */
492 			if (FcPatternGetInteger(pat, FC_WEIGHT, 0, &weight) != FcResultMatch)
493 				weight = FC_WEIGHT_NORMAL;
494 			if (FcPatternGetInteger(pat, FC_WIDTH, 0, &width) != FcResultMatch)
495 				width = FC_WIDTH_NORMAL;
496 			if (FcPatternGetInteger(pat, FC_SLANT, 0, &slant) != FcResultMatch)
497 				slant = FC_SLANT_ROMAN;
498 
499 			if (FcPatternGetDouble(pat, FC_PIXEL_SIZE, 0, &size) != FcResultMatch)
500 				size = 10.0;
501 
502 			for (i = 0, found = 0, closest = 0; i < WMGetListNumberOfRows(panel->styleL); i++) {
503 				WMListItem *item = WMGetListItem(panel->styleL, i);
504 				FontStyle *style = (FontStyle *) item->clientData;
505 
506 				distance = ((abs(style->weight - weight) << 16) +
507 					    (abs(style->slant - slant) << 8) + (abs(style->width - width)));
508 
509 				if (i == 0 || distance < closest) {
510 					closest = distance;
511 					found = i;
512 					if (distance == 0) {
513 						break;	/* perfect match */
514 					}
515 				}
516 			}
517 			WMSelectListItem(panel->styleL, found);
518 			WMSetListPosition(panel->styleL, found);
519 
520 			for (i = 0, found = 0, closest = 0; i < WMGetListNumberOfRows(panel->sizeL); i++) {
521 				WMListItem *item = WMGetListItem(panel->sizeL, i);
522 				int distance;
523 
524 				distance = abs(size - atoi(item->text));
525 
526 				if (i == 0 || distance < closest) {
527 					closest = distance;
528 					found = i;
529 					if (distance == 0) {
530 						break;	/* perfect match */
531 					}
532 				}
533 			}
534 			WMSelectListItem(panel->sizeL, found);
535 			WMSetListPosition(panel->sizeL, found);
536 
537 			selected(NULL, panel);
538 		} else
539 			wwarning("Can't parse font '%s'", font);
540 	}
541 
542 	updateSampleFont(panel);
543 }
544 
createListLabel(WMScreen * scr,WMWidget * parent,const char * text)545 static WMLabel *createListLabel(WMScreen * scr, WMWidget * parent, const char *text)
546 {
547 	WMLabel *label;
548 	WMColor *color;
549 	WMFont *boldFont = WMBoldSystemFontOfSize(scr, 12);
550 
551 	label = WMCreateLabel(parent);
552 	WMSetLabelFont(label, boldFont);
553 	WMSetLabelText(label, text);
554 	WMSetLabelRelief(label, WRSunken);
555 	WMSetLabelTextAlignment(label, WACenter);
556 	color = WMDarkGrayColor(scr);
557 	WMSetWidgetBackgroundColor(label, color);
558 	WMReleaseColor(color);
559 	color = WMWhiteColor(scr);
560 	WMSetLabelTextColor(label, color);
561 	WMReleaseColor(color);
562 
563 	WMReleaseFont(boldFont);
564 
565 	return label;
566 }
567 
showData(_Panel * panel)568 static void showData(_Panel * panel)
569 {
570 	int i;
571 	WMMenuItem *item;
572 	WMScreen *scr;
573 
574 	scr = WMWidgetScreen(panel->parent);
575 
576 	for (i = 0; i < WMGetPopUpButtonNumberOfItems(panel->optionP); i++) {
577 		char *ofont, *font;
578 
579 		item = WMGetPopUpButtonMenuItem(panel->optionP, i);
580 
581 		ofont = WMGetMenuItemRepresentedObject(item);
582 		if (ofont)
583 			wfree(ofont);
584 
585 		if (strcmp(fontOptions[i].option, "SystemFont") == 0)
586 			font = WMGetFontName(WMDefaultSystemFont(scr));
587 		else if (strcmp(fontOptions[i].option, "BoldSystemFont") == 0)
588 			font = WMGetFontName(WMDefaultBoldSystemFont(scr));
589 		else
590 			font = GetStringForKey(fontOptions[i].option);
591 		if (font)
592 			font = wstrdup(font);
593 		WMSetMenuItemRepresentedObject(item, font);
594 	}
595 
596 	WMSetPopUpButtonSelectedItem(panel->optionP, 0);
597 	selectedOption(panel->optionP, panel);
598 }
599 
storeData(_Panel * panel)600 static void storeData(_Panel * panel)
601 {
602 	int i;
603 	WMMenuItem *item;
604 	for (i = 0; i < WMGetPopUpButtonNumberOfItems(panel->optionP); i++) {
605 		char *font;
606 
607 		item = WMGetPopUpButtonMenuItem(panel->optionP, i);
608 
609 		font = WMGetMenuItemRepresentedObject(item);
610 		if (font && *font) {
611 			if (strcmp(fontOptions[i].option, "SystemFont") == 0 ||
612 			    strcmp(fontOptions[i].option, "BoldSystemFont") == 0) {
613 				char *path;
614 				WMUserDefaults *defaults;
615 
616 				path = wdefaultspathfordomain("WMGLOBAL");
617 				defaults = WMGetDefaultsFromPath(path);
618 				wfree(path);
619 				WMSetUDStringForKey(defaults,
620 						    font,
621 						    fontOptions[i].option);
622 				WMSaveUserDefaults(defaults);
623 			} else {
624 				SetStringForKey(font, fontOptions[i].option);
625 			}
626 		}
627 	}
628 }
629 
createPanel(Panel * p)630 static void createPanel(Panel * p)
631 {
632 	_Panel *panel = (_Panel *) p;
633 	WMScreen *scr = WMWidgetScreen(panel->parent);
634 	WMLabel *label;
635 	WMBox *hbox, *vbox;
636 	int i;
637 
638 	lookup_available_fonts(panel);
639 
640 	panel->box = WMCreateBox(panel->parent);
641 	WMSetViewExpandsToParent(WMWidgetView(panel->box), 5, 2, 5, 5);
642 	WMSetBoxHorizontal(panel->box, False);
643 	WMSetBoxBorderWidth(panel->box, 8);
644 	WMMapWidget(panel->box);
645 
646 	hbox = WMCreateBox(panel->box);
647 	WMSetBoxHorizontal(hbox, True);
648 	WMAddBoxSubview(panel->box, WMWidgetView(hbox), False, True, 40, 22, 8);
649 
650 	vbox = WMCreateBox(hbox);
651 	WMAddBoxSubview(hbox, WMWidgetView(vbox), False, True, 130, 0, 10);
652 	WMSetBoxHorizontal(vbox, False);
653 	panel->optionP = WMCreatePopUpButton(vbox);
654 	WMAddBoxSubviewAtEnd(vbox, WMWidgetView(panel->optionP), False, True, 20, 0, 8);
655 	for (i = 0; i < wlengthof(fontOptions); i++)
656 		WMAddPopUpButtonItem(panel->optionP, _(fontOptions[i].label));
657 	WMSetPopUpButtonAction(panel->optionP, selectedOption, panel);
658 
659 	label = WMCreateLabel(hbox);
660 	WMSetLabelText(label, _("Sample Text"));
661 	WMSetLabelTextAlignment(label, WARight);
662 	WMAddBoxSubview(hbox, WMWidgetView(label), False, True, 80, 0, 2);
663 
664 	panel->sampleT = WMCreateTextField(hbox);
665 	WMSetViewExpandsToParent(WMWidgetView(panel->sampleT), 10, 18, 10, 10);
666 	WMSetTextFieldText(panel->sampleT, SAMPLE_TEXT);
667 	WMAddBoxSubview(hbox, WMWidgetView(panel->sampleT), True, True, 60, 0, 0);
668 
669 	hbox = WMCreateBox(panel->box);
670 	WMSetBoxHorizontal(hbox, True);
671 	WMAddBoxSubview(panel->box, WMWidgetView(hbox), True, True, 100, 0, 2);
672 
673 	vbox = WMCreateBox(hbox);
674 	WMSetBoxHorizontal(vbox, False);
675 	WMAddBoxSubview(hbox, WMWidgetView(vbox), False, True, 240, 20, 4);
676 
677 	label = createListLabel(scr, vbox, _("Family"));
678 	WMAddBoxSubview(vbox, WMWidgetView(label), False, True, 20, 0, 2);
679 
680 	/* family */
681 	panel->familyL = WMCreateList(vbox);
682 	WMAddBoxSubview(vbox, WMWidgetView(panel->familyL), True, True, 0, 0, 0);
683 	if (panel->fonts) {
684 		WMListItem *item;
685 		for (i = 0; i < panel->fonts->familyn; i++) {
686 			item = WMAddListItem(panel->familyL, panel->fonts->families[i].name);
687 			item->clientData = panel->fonts->families + i;
688 		}
689 	} else
690 		WMAddListItem(panel->familyL, "sans serif");
691 
692 	WMSetListAction(panel->familyL, selectedFamily, panel);
693 
694 	vbox = WMCreateBox(hbox);
695 	WMSetBoxHorizontal(vbox, False);
696 	WMAddBoxSubview(hbox, WMWidgetView(vbox), True, True, 10, 0, 0);
697 
698 	{
699 		WMBox *box = WMCreateBox(vbox);
700 		WMSetBoxHorizontal(box, True);
701 		WMAddBoxSubview(vbox, WMWidgetView(box), False, True, 20, 0, 2);
702 
703 		label = createListLabel(scr, box, _("Style"));
704 		WMAddBoxSubview(box, WMWidgetView(label), True, True, 20, 0, 4);
705 
706 		label = createListLabel(scr, box, _("Size"));
707 		WMAddBoxSubview(box, WMWidgetView(label), False, True, 60, 0, 0);
708 
709 		box = WMCreateBox(vbox);
710 		WMSetBoxHorizontal(box, True);
711 		WMAddBoxSubview(vbox, WMWidgetView(box), True, True, 20, 0, 0);
712 
713 		panel->styleL = WMCreateList(box);
714 		WMAddBoxSubview(box, WMWidgetView(panel->styleL), True, True, 0, 0, 4);
715 		WMSetListAction(panel->styleL, selected, panel);
716 
717 		panel->sizeL = WMCreateList(box);
718 		WMAddBoxSubview(box, WMWidgetView(panel->sizeL), False, True, 60, 0, 0);
719 		for (i = 0; standardSizes[i]; i++) {
720 			WMAddListItem(panel->sizeL, standardSizes[i]);
721 		}
722 		WMSetListAction(panel->sizeL, selected, panel);
723 	}
724 
725 	WMMapSubwidgets(panel->box);
726 	WMMapWidget(panel->box);
727 	WMRealizeWidget(panel->box);
728 
729 	showData(panel);
730 }
731 
InitFontSimple(WMWidget * parent)732 Panel *InitFontSimple(WMWidget *parent)
733 {
734 	_Panel *panel;
735 
736 	panel = wmalloc(sizeof(_Panel));
737 
738 	panel->sectionName = _("Font Configuration");
739 
740 	panel->description = _("Configure fonts for Window Maker titlebars, menus etc.");
741 
742 	panel->parent = parent;
743 
744 	panel->callbacks.createWidgets = createPanel;
745 	panel->callbacks.updateDomain = storeData;
746 
747 	AddSection(panel, ICON_FILE);
748 
749 	return panel;
750 }
751