Include screen.h in dialog.h for definition of WScreen
[wmaker-crm.git] / WINGs / wfontpanel.c
blobdf01ed65fad510789ca5d9723aa04841f64e6824
2 #include "WINGsP.h"
3 #include "WUtil.h"
4 #include "wconfig.h"
6 #include <ctype.h>
7 #include <string.h>
8 #include <strings.h>
9 #include <stdint.h>
11 #include <X11/Xft/Xft.h>
12 #include <fontconfig/fontconfig.h>
14 /* XXX TODO */
15 char *WMFontPanelFontChangedNotification = "WMFontPanelFontChangedNotification";
17 typedef struct W_FontPanel {
18 WMWindow *win;
20 WMFrame *upperF;
21 WMTextField *sampleT;
23 WMSplitView *split;
25 WMFrame *lowerF;
26 WMLabel *famL;
27 WMList *famLs;
28 WMLabel *typL;
29 WMList *typLs;
30 WMLabel *sizL;
31 WMTextField *sizT;
32 WMList *sizLs;
34 WMAction2 *action;
35 void *data;
37 WMButton *revertB;
38 WMButton *setB;
40 WMPropList *fdb;
41 } FontPanel;
43 #define MIN_UPPER_HEIGHT 20
44 #define MIN_LOWER_HEIGHT 140
46 #define BUTTON_SPACE_HEIGHT 40
48 #define MIN_WIDTH 250
49 #define MIN_HEIGHT (MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+BUTTON_SPACE_HEIGHT)
51 #define DEF_UPPER_HEIGHT 60
52 #define DEF_LOWER_HEIGHT 310
54 #define DEF_WIDTH 320
55 #define DEF_HEIGHT (DEF_UPPER_HEIGHT+DEF_LOWER_HEIGHT)
57 static const int scalableFontSizes[] = {
59 10,
60 11,
61 12,
62 14,
63 16,
64 18,
65 20,
66 24,
67 36,
68 48,
72 static void setFontPanelFontName(FontPanel * panel, const char *family, const char *style, double size);
74 static int isXLFD(const char *font, int *length_ret);
76 static void arrangeLowerFrame(FontPanel * panel);
78 static void familyClick(WMWidget *, void *);
79 static void typefaceClick(WMWidget *, void *);
80 static void sizeClick(WMWidget *, void *);
82 static void listFamilies(WMScreen * scr, WMFontPanel * panel);
84 static void splitViewConstrainCallback(WMSplitView * sPtr, int indView, int *min, int *max)
86 /* Parameter not used, but tell the compiler that it is ok */
87 (void) sPtr;
88 (void) max;
90 if (indView == 0)
91 *min = MIN_UPPER_HEIGHT;
92 else
93 *min = MIN_LOWER_HEIGHT;
96 static void notificationObserver(void *self, WMNotification * notif)
98 WMFontPanel *panel = (WMFontPanel *) self;
99 void *object = WMGetNotificationObject(notif);
101 if (WMGetNotificationName(notif) == WMViewSizeDidChangeNotification) {
102 if (object == WMWidgetView(panel->win)) {
103 int h = WMWidgetHeight(panel->win);
104 int w = WMWidgetWidth(panel->win);
106 WMResizeWidget(panel->split, w, h - BUTTON_SPACE_HEIGHT);
108 WMMoveWidget(panel->setB, w - 80, h - (BUTTON_SPACE_HEIGHT - 5));
110 WMMoveWidget(panel->revertB, w - 240, h - (BUTTON_SPACE_HEIGHT - 5));
112 } else if (object == WMWidgetView(panel->upperF)) {
114 if (WMWidgetHeight(panel->upperF) < MIN_UPPER_HEIGHT) {
115 WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF), MIN_UPPER_HEIGHT);
116 } else {
117 WMResizeWidget(panel->sampleT, WMWidgetWidth(panel->upperF) - 20,
118 WMWidgetHeight(panel->upperF) - 10);
121 } else if (object == WMWidgetView(panel->lowerF)) {
123 if (WMWidgetHeight(panel->lowerF) < MIN_LOWER_HEIGHT) {
124 WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF), MIN_UPPER_HEIGHT);
126 WMMoveWidget(panel->lowerF, 0, WMWidgetHeight(panel->upperF)
127 + WMGetSplitViewDividerThickness(panel->split));
129 WMResizeWidget(panel->lowerF, WMWidgetWidth(panel->lowerF),
130 WMWidgetWidth(panel->split) - MIN_UPPER_HEIGHT
131 - WMGetSplitViewDividerThickness(panel->split));
132 } else {
133 arrangeLowerFrame(panel);
139 static void closeWindow(WMWidget * w, void *data)
141 FontPanel *panel = (FontPanel *) data;
143 /* Parameter not used, but tell the compiler that it is ok */
144 (void) w;
146 WMHideFontPanel(panel);
149 static void setClickedAction(WMWidget * w, void *data)
151 FontPanel *panel = (FontPanel *) data;
153 /* Parameter not used, but tell the compiler that it is ok */
154 (void) w;
156 if (panel->action)
157 (*panel->action) (panel, panel->data);
160 static void revertClickedAction(WMWidget * w, void *data)
162 /* Parameter not used, but tell the compiler that it is ok */
163 (void) w;
164 (void) data;
166 /*FontPanel *panel = (FontPanel*)data; */
167 /* XXX TODO */
170 WMFontPanel *WMGetFontPanel(WMScreen * scr)
172 FontPanel *panel;
173 WMColor *dark, *white;
174 WMFont *font;
175 int divThickness;
177 if (scr->sharedFontPanel)
178 return scr->sharedFontPanel;
180 panel = wmalloc(sizeof(FontPanel));
182 panel->win = WMCreateWindow(scr, "fontPanel");
183 /* WMSetWidgetBackgroundColor(panel->win, WMWhiteColor(scr)); */
184 WMSetWindowTitle(panel->win, _("Font Panel"));
185 WMResizeWidget(panel->win, DEF_WIDTH, DEF_HEIGHT);
186 WMSetWindowMinSize(panel->win, MIN_WIDTH, MIN_HEIGHT);
187 WMSetViewNotifySizeChanges(WMWidgetView(panel->win), True);
189 WMSetWindowCloseAction(panel->win, closeWindow, panel);
191 panel->split = WMCreateSplitView(panel->win);
192 WMResizeWidget(panel->split, DEF_WIDTH, DEF_HEIGHT - BUTTON_SPACE_HEIGHT);
193 WMSetSplitViewConstrainProc(panel->split, splitViewConstrainCallback);
195 divThickness = WMGetSplitViewDividerThickness(panel->split);
197 panel->upperF = WMCreateFrame(panel->win);
198 WMSetFrameRelief(panel->upperF, WRFlat);
199 WMSetViewNotifySizeChanges(WMWidgetView(panel->upperF), True);
200 panel->lowerF = WMCreateFrame(panel->win);
201 /* WMSetWidgetBackgroundColor(panel->lowerF, WMBlackColor(scr)); */
202 WMSetFrameRelief(panel->lowerF, WRFlat);
203 WMSetViewNotifySizeChanges(WMWidgetView(panel->lowerF), True);
205 WMAddSplitViewSubview(panel->split, W_VIEW(panel->upperF));
206 WMAddSplitViewSubview(panel->split, W_VIEW(panel->lowerF));
208 WMResizeWidget(panel->upperF, DEF_WIDTH, DEF_UPPER_HEIGHT);
210 WMResizeWidget(panel->lowerF, DEF_WIDTH, DEF_LOWER_HEIGHT);
212 WMMoveWidget(panel->lowerF, 0, 60 + divThickness);
214 white = WMWhiteColor(scr);
215 dark = WMDarkGrayColor(scr);
217 panel->sampleT = WMCreateTextField(panel->upperF);
218 WMResizeWidget(panel->sampleT, DEF_WIDTH - 20, 50);
219 WMMoveWidget(panel->sampleT, 10, 10);
220 WMSetTextFieldText(panel->sampleT, _("The quick brown fox jumps over the lazy dog"));
222 font = WMBoldSystemFontOfSize(scr, 12);
224 panel->famL = WMCreateLabel(panel->lowerF);
225 WMSetWidgetBackgroundColor(panel->famL, dark);
226 WMSetLabelText(panel->famL, _("Family"));
227 WMSetLabelFont(panel->famL, font);
228 WMSetLabelTextColor(panel->famL, white);
229 WMSetLabelRelief(panel->famL, WRSunken);
230 WMSetLabelTextAlignment(panel->famL, WACenter);
232 panel->famLs = WMCreateList(panel->lowerF);
233 WMSetListAction(panel->famLs, familyClick, panel);
235 panel->typL = WMCreateLabel(panel->lowerF);
236 WMSetWidgetBackgroundColor(panel->typL, dark);
237 WMSetLabelText(panel->typL, _("Typeface"));
238 WMSetLabelFont(panel->typL, font);
239 WMSetLabelTextColor(panel->typL, white);
240 WMSetLabelRelief(panel->typL, WRSunken);
241 WMSetLabelTextAlignment(panel->typL, WACenter);
243 panel->typLs = WMCreateList(panel->lowerF);
244 WMSetListAction(panel->typLs, typefaceClick, panel);
246 panel->sizL = WMCreateLabel(panel->lowerF);
247 WMSetWidgetBackgroundColor(panel->sizL, dark);
248 WMSetLabelText(panel->sizL, _("Size"));
249 WMSetLabelFont(panel->sizL, font);
250 WMSetLabelTextColor(panel->sizL, white);
251 WMSetLabelRelief(panel->sizL, WRSunken);
252 WMSetLabelTextAlignment(panel->sizL, WACenter);
254 panel->sizT = WMCreateTextField(panel->lowerF);
255 /* WMSetTextFieldAlignment(panel->sizT, WARight); */
257 panel->sizLs = WMCreateList(panel->lowerF);
258 WMSetListAction(panel->sizLs, sizeClick, panel);
260 WMReleaseFont(font);
261 WMReleaseColor(white);
262 WMReleaseColor(dark);
264 panel->setB = WMCreateCommandButton(panel->win);
265 WMResizeWidget(panel->setB, 70, 24);
266 WMMoveWidget(panel->setB, 240, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT - 5));
267 WMSetButtonText(panel->setB, _("Set"));
268 WMSetButtonAction(panel->setB, setClickedAction, panel);
270 panel->revertB = WMCreateCommandButton(panel->win);
271 WMResizeWidget(panel->revertB, 70, 24);
272 WMMoveWidget(panel->revertB, 80, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT - 5));
273 WMSetButtonText(panel->revertB, _("Revert"));
274 WMSetButtonAction(panel->revertB, revertClickedAction, panel);
276 WMRealizeWidget(panel->win);
278 WMMapSubwidgets(panel->upperF);
279 WMMapSubwidgets(panel->lowerF);
280 WMMapSubwidgets(panel->split);
281 WMMapSubwidgets(panel->win);
283 WMUnmapWidget(panel->revertB);
285 arrangeLowerFrame(panel);
287 scr->sharedFontPanel = panel;
289 /* register notification observers */
290 WMAddNotificationObserver(notificationObserver, panel,
291 WMViewSizeDidChangeNotification, WMWidgetView(panel->win));
292 WMAddNotificationObserver(notificationObserver, panel,
293 WMViewSizeDidChangeNotification, WMWidgetView(panel->upperF));
294 WMAddNotificationObserver(notificationObserver, panel,
295 WMViewSizeDidChangeNotification, WMWidgetView(panel->lowerF));
297 listFamilies(scr, panel);
299 return panel;
302 void WMFreeFontPanel(WMFontPanel * panel)
304 if (panel == WMWidgetScreen(panel->win)->sharedFontPanel) {
305 WMWidgetScreen(panel->win)->sharedFontPanel = NULL;
307 WMRemoveNotificationObserver(panel);
308 WMUnmapWidget(panel->win);
309 WMDestroyWidget(panel->win);
310 wfree(panel);
313 void WMShowFontPanel(WMFontPanel * panel)
315 WMMapWidget(panel->win);
318 void WMHideFontPanel(WMFontPanel * panel)
320 WMUnmapWidget(panel->win);
323 WMFont *WMGetFontPanelFont(WMFontPanel * panel)
325 return WMGetTextFieldFont(panel->sampleT);
328 void WMSetFontPanelFont(WMFontPanel * panel, const char *fontName)
330 int fname_len;
331 FcPattern *pattern;
332 FcChar8 *family, *style;
333 double size;
335 if (!isXLFD(fontName, &fname_len)) {
336 /* maybe its proper fontconfig and we can parse it */
337 pattern = FcNameParse((const FcChar8 *) fontName);
338 } else {
339 /* maybe its proper xlfd and we can convert it to an FcPattern */
340 pattern = XftXlfdParse(fontName, False, False);
341 /*//FcPatternPrint(pattern); */
344 if (!pattern)
345 return;
347 if (FcPatternGetString(pattern, FC_FAMILY, 0, &family) == FcResultMatch)
348 if (FcPatternGetString(pattern, FC_STYLE, 0, &style) == FcResultMatch)
349 if (FcPatternGetDouble(pattern, "pixelsize", 0, &size) == FcResultMatch)
350 setFontPanelFontName(panel, (char *)family, (char *)style, size);
352 FcPatternDestroy(pattern);
355 void WMSetFontPanelAction(WMFontPanel * panel, WMAction2 * action, void *data)
357 panel->action = action;
358 panel->data = data;
361 static void arrangeLowerFrame(FontPanel * panel)
363 int width = WMWidgetWidth(panel->lowerF) - 55 - 30;
364 int height = WMWidgetHeight(panel->split) - WMWidgetHeight(panel->upperF);
365 int fw, tw, sw;
367 #define LABEL_HEIGHT 20
369 height -= WMGetSplitViewDividerThickness(panel->split);
371 height -= LABEL_HEIGHT + 8;
373 fw = (125 * width) / 235;
374 tw = (110 * width) / 235;
375 sw = 55;
377 WMMoveWidget(panel->famL, 10, 0);
378 WMResizeWidget(panel->famL, fw, LABEL_HEIGHT);
380 WMMoveWidget(panel->famLs, 10, 23);
381 WMResizeWidget(panel->famLs, fw, height);
383 WMMoveWidget(panel->typL, 10 + fw + 3, 0);
384 WMResizeWidget(panel->typL, tw, LABEL_HEIGHT);
386 WMMoveWidget(panel->typLs, 10 + fw + 3, 23);
387 WMResizeWidget(panel->typLs, tw, height);
389 WMMoveWidget(panel->sizL, 10 + fw + 3 + tw + 3, 0);
390 WMResizeWidget(panel->sizL, sw + 4, LABEL_HEIGHT);
392 WMMoveWidget(panel->sizT, 10 + fw + 3 + tw + 3, 23);
393 WMResizeWidget(panel->sizT, sw + 4, 20);
395 WMMoveWidget(panel->sizLs, 10 + fw + 3 + tw + 3, 46);
396 WMResizeWidget(panel->sizLs, sw + 4, height - 23);
399 #define NUM_FIELDS 14
401 static int isXLFD(const char *font, int *length_ret)
403 int c = 0;
405 *length_ret = 0;
406 while (*font) {
407 (*length_ret)++;
408 if (*font++ == '-')
409 c++;
412 return c == NUM_FIELDS;
415 typedef struct {
416 char *typeface;
417 WMArray *sizes;
418 } Typeface;
420 typedef struct {
421 char *name; /* gotta love simplicity */
422 WMArray *typefaces;
423 } Family;
425 static int compare_int(const void *a, const void *b)
427 int i1 = *(int *)a;
428 int i2 = *(int *)b;
430 if (i1 < i2)
431 return -1;
432 else if (i1 > i2)
433 return 1;
434 else
435 return 0;
438 static void addSizeToTypeface(Typeface * face, int size)
440 if (size == 0) {
441 int j;
443 for (j = 0; j < wlengthof(scalableFontSizes); j++) {
444 size = scalableFontSizes[j];
446 if (!WMCountInArray(face->sizes, (void *)(uintptr_t) size)) {
447 WMAddToArray(face->sizes, (void *)(uintptr_t) size);
450 WMSortArray(face->sizes, compare_int);
451 } else {
452 if (!WMCountInArray(face->sizes, (void *)(uintptr_t) size)) {
453 WMAddToArray(face->sizes, (void *)(uintptr_t) size);
454 WMSortArray(face->sizes, compare_int);
459 static void addTypefaceToXftFamily(Family * fam, const char *style)
461 Typeface *face;
462 WMArrayIterator i;
464 if (fam->typefaces) {
465 WM_ITERATE_ARRAY(fam->typefaces, face, i) {
466 if (strcmp(face->typeface, style) != 0)
467 continue; /* go to next interation */
468 addSizeToTypeface(face, 0);
469 return;
471 } else {
472 fam->typefaces = WMCreateArray(4);
475 face = wmalloc(sizeof(Typeface));
477 face->typeface = wstrdup(style);
478 face->sizes = WMCreateArray(4);
479 addSizeToTypeface(face, 0);
481 WMAddToArray(fam->typefaces, face);
485 * families (same family name) (Hashtable of family -> array)
486 * registries (same family but different registries)
489 static void addFontToXftFamily(WMHashTable * families, const char *name, const char *style)
491 WMArrayIterator i;
492 WMArray *array;
493 Family *fam;
495 array = WMHashGet(families, name);
496 if (array) {
497 WM_ITERATE_ARRAY(array, fam, i) {
498 if (strcmp(fam->name, name) == 0)
499 addTypefaceToXftFamily(fam, style);
500 return;
504 array = WMCreateArray(8);
506 fam = wmalloc(sizeof(Family));
508 fam->name = wstrdup(name);
510 addTypefaceToXftFamily(fam, style);
512 WMAddToArray(array, fam);
514 WMHashInsert(families, fam->name, array);
517 static void listFamilies(WMScreen * scr, WMFontPanel * panel)
519 FcObjectSet *os = 0;
520 FcFontSet *fs;
521 FcPattern *pat;
522 WMHashTable *families;
523 WMHashEnumerator enumer;
524 WMArray *array;
525 int i;
527 pat = FcPatternCreate();
528 os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL);
529 fs = FcFontList(0, pat, os);
530 if (!fs) {
531 WMRunAlertPanel(scr, panel->win, _("Error"),
532 _("Could not init font config library\n"), _("OK"), NULL, NULL);
533 return;
535 if (pat)
536 FcPatternDestroy(pat);
538 families = WMCreateHashTable(WMStringPointerHashCallbacks);
540 if (fs) {
541 for (i = 0; i < fs->nfont; i++) {
542 FcChar8 *family;
543 FcChar8 *style;
545 if (FcPatternGetString(fs->fonts[i], FC_FAMILY, 0, &family) == FcResultMatch)
546 if (FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch)
547 addFontToXftFamily(families, (char *)family, (char *)style);
549 FcFontSetDestroy(fs);
552 enumer = WMEnumerateHashTable(families);
554 while ((array = WMNextHashEnumeratorItem(&enumer))) {
555 WMArrayIterator i;
556 Family *fam;
557 char buffer[256];
558 WMListItem *item;
560 WM_ITERATE_ARRAY(array, fam, i) {
561 wstrlcpy(buffer, fam->name, sizeof(buffer));
562 item = WMAddListItem(panel->famLs, buffer);
564 item->clientData = fam;
567 WMFreeArray(array);
570 WMSortListItems(panel->famLs);
572 WMFreeHashTable(families);
575 static void getSelectedFont(FontPanel * panel, char buffer[], int bufsize)
577 WMListItem *item;
578 Family *family;
579 Typeface *face;
580 char *size;
582 item = WMGetListSelectedItem(panel->famLs);
583 if (!item)
584 return;
585 family = (Family *) item->clientData;
587 item = WMGetListSelectedItem(panel->typLs);
588 if (!item)
589 return;
590 face = (Typeface *) item->clientData;
592 size = WMGetTextFieldText(panel->sizT);
594 snprintf(buffer, bufsize, "%s:style=%s:pixelsize=%s", family->name, face->typeface, size);
596 wfree(size);
599 static void preview(FontPanel * panel)
601 char buffer[512];
602 WMFont *font;
604 getSelectedFont(panel, buffer, sizeof(buffer));
605 font = WMCreateFont(WMWidgetScreen(panel->win), buffer);
606 if (font) {
607 WMSetTextFieldFont(panel->sampleT, font);
608 WMReleaseFont(font);
612 static void familyClick(WMWidget * w, void *data)
614 WMList *lPtr = (WMList *) w;
615 WMListItem *item;
616 Family *family;
617 Typeface *face;
618 FontPanel *panel = (FontPanel *) data;
619 WMArrayIterator i;
620 /* current typeface and size */
621 char *oface = NULL;
622 char *osize = NULL;
623 int facei = -1;
624 int sizei = -1;
626 /* must try to keep the same typeface and size for the new family */
627 item = WMGetListSelectedItem(panel->typLs);
628 if (item)
629 oface = wstrdup(item->text);
631 osize = WMGetTextFieldText(panel->sizT);
633 item = WMGetListSelectedItem(lPtr);
634 family = (Family *) item->clientData;
636 WMClearList(panel->typLs);
638 WM_ITERATE_ARRAY(family->typefaces, face, i) {
639 char buffer[256];
640 int top = 0;
641 WMListItem *fitem;
643 wstrlcpy(buffer, face->typeface, sizeof(buffer));
644 if (strcasecmp(face->typeface, "Roman") == 0)
645 top = 1;
646 if (strcasecmp(face->typeface, "Regular") == 0)
647 top = 1;
648 if (top)
649 fitem = WMInsertListItem(panel->typLs, 0, buffer);
650 else
651 fitem = WMAddListItem(panel->typLs, buffer);
652 fitem->clientData = face;
655 if (oface) {
656 facei = WMFindRowOfListItemWithTitle(panel->typLs, oface);
657 wfree(oface);
659 if (facei < 0) {
660 facei = 0;
662 WMSelectListItem(panel->typLs, facei);
663 typefaceClick(panel->typLs, panel);
665 if (osize) {
666 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
668 if (sizei >= 0) {
669 WMSelectListItem(panel->sizLs, sizei);
670 sizeClick(panel->sizLs, panel);
673 if (osize)
674 wfree(osize);
676 preview(panel);
679 static void typefaceClick(WMWidget * w, void *data)
681 FontPanel *panel = (FontPanel *) data;
682 WMListItem *item;
683 Typeface *face;
684 WMArrayIterator i;
685 char buffer[32];
687 char *osize = NULL;
688 int sizei = -1;
689 void *size;
691 /* Parameter not used, but tell the compiler that it is ok */
692 (void) w;
694 osize = WMGetTextFieldText(panel->sizT);
696 item = WMGetListSelectedItem(panel->typLs);
697 face = (Typeface *) item->clientData;
699 WMClearList(panel->sizLs);
701 WM_ITERATE_ARRAY(face->sizes, size, i) {
702 if (size != NULL) {
703 int size_int = (intptr_t) size;
705 sprintf(buffer, "%i", size_int);
707 WMAddListItem(panel->sizLs, buffer);
711 if (osize) {
712 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
714 if (sizei < 0) {
715 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, "12");
717 if (sizei < 0) {
718 sizei = 0;
720 WMSelectListItem(panel->sizLs, sizei);
721 WMSetListPosition(panel->sizLs, sizei);
722 sizeClick(panel->sizLs, panel);
724 if (osize)
725 wfree(osize);
727 preview(panel);
730 static void sizeClick(WMWidget * w, void *data)
732 FontPanel *panel = (FontPanel *) data;
733 WMListItem *item;
735 /* Parameter not used, but tell the compiler that it is ok */
736 (void) w;
738 item = WMGetListSelectedItem(panel->sizLs);
739 WMSetTextFieldText(panel->sizT, item->text);
741 WMSelectTextFieldRange(panel->sizT, wmkrange(0, strlen(item->text)));
743 preview(panel);
746 static void setFontPanelFontName(FontPanel * panel, const char *family, const char *style, double size)
748 int famrow;
749 int stlrow;
750 int sz;
751 char asize[64];
752 void *vsize;
753 WMListItem *item;
754 Family *fam;
755 Typeface *face;
756 WMArrayIterator i;
758 famrow = WMFindRowOfListItemWithTitle(panel->famLs, family);
759 if (famrow < 0) {
760 famrow = 0;
761 return;
763 WMSelectListItem(panel->famLs, famrow);
764 WMSetListPosition(panel->famLs, famrow);
766 WMClearList(panel->typLs);
768 item = WMGetListSelectedItem(panel->famLs);
770 fam = (Family *) item->clientData;
771 WM_ITERATE_ARRAY(fam->typefaces, face, i) {
772 char buffer[256];
773 int top = 0;
774 WMListItem *fitem;
776 wstrlcpy(buffer, face->typeface, sizeof(buffer));
777 if (strcasecmp(face->typeface, "Roman") == 0)
778 top = 1;
779 if (top)
780 fitem = WMInsertListItem(panel->typLs, 0, buffer);
781 else
782 fitem = WMAddListItem(panel->typLs, buffer);
783 fitem->clientData = face;
786 stlrow = WMFindRowOfListItemWithTitle(panel->typLs, style);
788 if (stlrow < 0) {
789 stlrow = 0;
790 return;
793 WMSelectListItem(panel->typLs, stlrow);
795 item = WMGetListSelectedItem(panel->typLs);
797 face = (Typeface *) item->clientData;
799 WMClearList(panel->sizLs);
801 WM_ITERATE_ARRAY(face->sizes, vsize, i) {
802 char buffer[32];
804 if (vsize != NULL) {
805 int size_int = (intptr_t) vsize;
807 sprintf(buffer, "%i", size_int);
809 WMAddListItem(panel->sizLs, buffer);
813 snprintf(asize, sizeof(asize) - 1, "%d", (int)(size + 0.5));
815 sz = WMFindRowOfListItemWithTitle(panel->sizLs, asize);
817 if (sz < 0) {
818 return;
821 WMSelectListItem(panel->sizLs, sz);
822 sizeClick(panel->sizLs, panel);
824 return;