- Removed the following 3 options from configuration: SelectWindowsMouseButton,
[wmaker-crm.git] / WINGs / wfontpanel.c
blobb68902d9a943af739dc05b3cd09cc4b859ab3611
5 #include "WINGsP.h"
6 #include "WUtil.h"
8 #include <ctype.h>
9 #include <string.h>
12 typedef struct W_FontPanel {
13 WMWindow *win;
15 WMFrame *upperF;
16 WMTextField *sampleT;
18 WMSplitView *split;
20 WMFrame *lowerF;
21 WMLabel *famL;
22 WMList *famLs;
23 WMLabel *typL;
24 WMList *typLs;
25 WMLabel *sizL;
26 WMTextField *sizT;
27 WMList *sizLs;
29 WMButton *revertB;
30 WMButton *setB;
32 proplist_t fdb;
33 } FontPanel;
36 #define MIN_UPPER_HEIGHT 20
37 #define MIN_LOWER_HEIGHT 140
40 #define MAX_FONTS_TO_RETRIEVE 2000
42 #define BUTTON_SPACE_HEIGHT 40
44 #define MIN_WIDTH 250
45 #define MIN_HEIGHT (MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+BUTTON_SPACE_HEIGHT)
47 #define DEF_UPPER_HEIGHT 60
48 #define DEF_LOWER_HEIGHT 310
50 #define DEF_WIDTH 320
51 #define DEF_HEIGHT (DEF_UPPER_HEIGHT+DEF_LOWER_HEIGHT)
56 static int scalableFontSizes[] = {
57 8,
58 10,
59 11,
60 12,
61 14,
62 16,
63 18,
64 20,
65 24,
66 36,
67 48,
73 static void getSelectedFont(FontPanel *panel, char buffer[]);
76 static void arrangeLowerFrame(FontPanel *panel);
78 static void familyClick(WMWidget *, void *);
79 static void typefaceClick(WMWidget *, void *);
80 static void sizeClick(WMWidget *, void *);
83 static void listFamilies(WMScreen *scr, WMFontPanel *panel);
86 static void
87 splitViewConstrainCallback(WMSplitView *sPtr, int indView, int *min, int *max)
89 if (indView == 0)
90 *min = MIN_UPPER_HEIGHT;
91 else
92 *min = MIN_LOWER_HEIGHT;
95 static void
96 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),
116 MIN_UPPER_HEIGHT);
117 } else {
118 WMResizeWidget(panel->sampleT, WMWidgetWidth(panel->upperF)-20,
119 WMWidgetHeight(panel->upperF)-10);
122 } else if (object == WMWidgetView(panel->lowerF)) {
124 if (WMWidgetHeight(panel->lowerF) < MIN_LOWER_HEIGHT) {
125 WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF),
126 MIN_UPPER_HEIGHT);
128 WMMoveWidget(panel->lowerF, 0, WMWidgetHeight(panel->upperF)
129 + WMGetSplitViewDividerThickness(panel->split));
131 WMResizeWidget(panel->lowerF, WMWidgetWidth(panel->lowerF),
132 WMWidgetWidth(panel->split) - MIN_UPPER_HEIGHT
133 - WMGetSplitViewDividerThickness(panel->split));
134 } else {
135 arrangeLowerFrame(panel);
142 static void
143 closeWindow(WMWidget *w, void *data)
145 FontPanel *panel = (FontPanel*)data;
147 WMHideFontPanel(panel);
152 WMFontPanel*
153 WMGetFontPanel(WMScreen *scr)
155 FontPanel *panel;
156 WMColor *dark, *white;
157 WMFont *font;
158 int divThickness;
160 if (scr->sharedFontPanel)
161 return scr->sharedFontPanel;
164 panel = wmalloc(sizeof(FontPanel));
165 memset(panel, 0, sizeof(FontPanel));
167 panel->win = WMCreateWindow(scr, "fontPanel");
168 /* WMSetWidgetBackgroundColor(panel->win, WMWhiteColor(scr));*/
169 WMResizeWidget(panel->win, DEF_WIDTH, DEF_HEIGHT);
170 WMSetWindowMinSize(panel->win, MIN_WIDTH, MIN_HEIGHT);
171 WMSetViewNotifySizeChanges(WMWidgetView(panel->win), True);
173 WMSetWindowCloseAction(panel->win, closeWindow, panel);
175 panel->split = WMCreateSplitView(panel->win);
176 WMResizeWidget(panel->split, DEF_WIDTH, DEF_HEIGHT - BUTTON_SPACE_HEIGHT);
177 WMSetSplitViewConstrainProc(panel->split, splitViewConstrainCallback);
179 divThickness = WMGetSplitViewDividerThickness(panel->split);
181 panel->upperF = WMCreateFrame(panel->win);
182 WMSetFrameRelief(panel->upperF, WRFlat);
183 WMSetViewNotifySizeChanges(WMWidgetView(panel->upperF), True);
184 panel->lowerF = WMCreateFrame(panel->win);
185 /* WMSetWidgetBackgroundColor(panel->lowerF, WMBlackColor(scr));*/
186 WMSetFrameRelief(panel->lowerF, WRFlat);
187 WMSetViewNotifySizeChanges(WMWidgetView(panel->lowerF), True);
189 WMAddSplitViewSubview(panel->split, W_VIEW(panel->upperF));
190 WMAddSplitViewSubview(panel->split, W_VIEW(panel->lowerF));
192 WMResizeWidget(panel->upperF, DEF_WIDTH, DEF_UPPER_HEIGHT);
194 WMResizeWidget(panel->lowerF, DEF_WIDTH, DEF_LOWER_HEIGHT);
196 WMMoveWidget(panel->lowerF, 0, 60+divThickness);
198 white = WMWhiteColor(scr);
199 dark = WMDarkGrayColor(scr);
201 panel->sampleT = WMCreateTextField(panel->upperF);
202 WMResizeWidget(panel->sampleT, DEF_WIDTH - 20, 50);
203 WMMoveWidget(panel->sampleT, 10, 10);
204 WMSetTextFieldText(panel->sampleT, "Test!!!");
206 font = WMBoldSystemFontOfSize(scr, 12);
208 panel->famL = WMCreateLabel(panel->lowerF);
209 WMSetWidgetBackgroundColor(panel->famL, dark);
210 WMSetLabelText(panel->famL, "Family");
211 WMSetLabelFont(panel->famL, font);
212 WMSetLabelTextColor(panel->famL, white);
213 WMSetLabelRelief(panel->famL, WRSunken);
214 WMSetLabelTextAlignment(panel->famL, WACenter);
216 panel->famLs = WMCreateList(panel->lowerF);
217 WMSetListAction(panel->famLs, familyClick, panel);
219 panel->typL = WMCreateLabel(panel->lowerF);
220 WMSetWidgetBackgroundColor(panel->typL, dark);
221 WMSetLabelText(panel->typL, "Typeface");
222 WMSetLabelFont(panel->typL, font);
223 WMSetLabelTextColor(panel->typL, white);
224 WMSetLabelRelief(panel->typL, WRSunken);
225 WMSetLabelTextAlignment(panel->typL, WACenter);
227 panel->typLs = WMCreateList(panel->lowerF);
228 WMSetListAction(panel->typLs, typefaceClick, panel);
230 panel->sizL = WMCreateLabel(panel->lowerF);
231 WMSetWidgetBackgroundColor(panel->sizL, dark);
232 WMSetLabelText(panel->sizL, "Size");
233 WMSetLabelFont(panel->sizL, font);
234 WMSetLabelTextColor(panel->sizL, white);
235 WMSetLabelRelief(panel->sizL, WRSunken);
236 WMSetLabelTextAlignment(panel->sizL, WACenter);
238 panel->sizT = WMCreateTextField(panel->lowerF);
239 /* WMSetTextFieldAlignment(panel->sizT, WARight);*/
241 panel->sizLs = WMCreateList(panel->lowerF);
242 WMSetListAction(panel->sizLs, sizeClick, panel);
244 WMReleaseFont(font);
245 WMReleaseColor(white);
246 WMReleaseColor(dark);
248 panel->setB = WMCreateCommandButton(panel->win);
249 WMResizeWidget(panel->setB, 70, 24);
250 WMMoveWidget(panel->setB, 240, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT-5));
251 WMSetButtonText(panel->setB, "Set");
253 panel->revertB = WMCreateCommandButton(panel->win);
254 WMResizeWidget(panel->revertB, 70, 24);
255 WMMoveWidget(panel->revertB, 80, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT-5));
256 WMSetButtonText(panel->revertB, "Revert");
258 WMRealizeWidget(panel->win);
260 WMMapSubwidgets(panel->upperF);
261 WMMapSubwidgets(panel->lowerF);
262 WMMapSubwidgets(panel->split);
263 WMMapSubwidgets(panel->win);
265 WMUnmapWidget(panel->revertB);
267 arrangeLowerFrame(panel);
269 scr->sharedFontPanel = panel;
272 /* register notification observers */
273 WMAddNotificationObserver(notificationObserver, panel,
274 WMViewSizeDidChangeNotification,
275 WMWidgetView(panel->win));
276 WMAddNotificationObserver(notificationObserver, panel,
277 WMViewSizeDidChangeNotification,
278 WMWidgetView(panel->upperF));
279 WMAddNotificationObserver(notificationObserver, panel,
280 WMViewSizeDidChangeNotification,
281 WMWidgetView(panel->lowerF));
284 listFamilies(scr, panel);
287 return panel;
291 void
292 WMFreeFontPanel(WMFontPanel *panel)
294 if (panel == WMWidgetScreen(panel->win)->sharedFontPanel) {
295 WMWidgetScreen(panel->win)->sharedFontPanel = NULL;
297 WMRemoveNotificationObserver(panel);
298 WMUnmapWidget(panel->win);
299 WMDestroyWidget(panel->win);
300 wfree(panel);
304 void
305 WMShowFontPanel(WMFontPanel *panel)
307 WMMapWidget(panel->win);
311 void
312 WMHideFontPanel(WMFontPanel *panel)
314 WMUnmapWidget(panel->win);
318 void
319 WMSetFontPanelFont(WMFontPanel *panel, WMFont *font)
325 Bool
326 WMSetFontPanelFontName(WMFontPanel *panel, char *fontName)
329 return True;
333 WMFont*
334 WMGetFontPanelFont(WMFontPanel *panel)
336 return WMGetTextFieldFont(panel->sampleT);
340 char*
341 WMGetFontPanelFontName(WMFontPanel *panel)
343 char name[256];
345 getSelectedFont(panel, name);
347 return wstrdup(name);
352 static void
353 arrangeLowerFrame(FontPanel *panel)
355 int width = WMWidgetWidth(panel->lowerF) - 55 - 30;
356 int height = WMWidgetHeight(panel->split) - WMWidgetHeight(panel->upperF);
357 int fw, tw, sw;
359 #define LABEL_HEIGHT 20
361 height -= WMGetSplitViewDividerThickness(panel->split);
364 height -= LABEL_HEIGHT + 8;
366 fw = (125*width) / 235;
367 tw = (110*width) / 235;
368 sw = 55;
370 WMMoveWidget(panel->famL, 10, 0);
371 WMResizeWidget(panel->famL, fw, LABEL_HEIGHT);
373 WMMoveWidget(panel->famLs, 10, 23);
374 WMResizeWidget(panel->famLs, fw, height);
376 WMMoveWidget(panel->typL, 10+fw+3, 0);
377 WMResizeWidget(panel->typL, tw, LABEL_HEIGHT);
379 WMMoveWidget(panel->typLs, 10+fw+3, 23);
380 WMResizeWidget(panel->typLs, tw, height);
382 WMMoveWidget(panel->sizL, 10+fw+3+tw+3, 0);
383 WMResizeWidget(panel->sizL, sw+4, LABEL_HEIGHT);
385 WMMoveWidget(panel->sizT, 10+fw+3+tw+3, 23);
386 WMResizeWidget(panel->sizT, sw+4, 20);
388 WMMoveWidget(panel->sizLs, 10+fw+3+tw+3, 46);
389 WMResizeWidget(panel->sizLs, sw+4, height-23);
395 #define ALL_FONTS_MASK "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
397 #define FOUNDRY 0
398 #define FAMILY 1
399 #define WEIGHT 2
400 #define SLANT 3
401 #define SETWIDTH 4
402 #define ADD_STYLE 5
403 #define PIXEL_SIZE 6
404 #define POINT_SIZE 7
405 #define RES_X 8
406 #define RES_Y 9
407 #define SPACING 10
408 #define AV_WIDTH 11
409 #define REGISTRY 12
410 #define ENCODING 13
412 #define NUM_FIELDS 14
416 static Bool
417 parseFont(char *font, char values[NUM_FIELDS][256])
419 char *ptr;
420 int part;
421 char buffer[256], *bptr;
423 part = FOUNDRY;
424 ptr = font;
425 ptr++; /* skip first - */
426 bptr = buffer;
427 while (*ptr) {
428 if (*ptr == '-') {
429 *bptr = 0;
430 strcpy(values[part], buffer);
431 bptr = buffer;
432 part++;
433 } else {
434 *bptr++ = *ptr;
436 ptr++;
438 *bptr = 0;
439 strcpy(values[part], buffer);
441 return True;
446 static int
447 isXLFD(char *font, int *length_ret)
449 int c = 0;
451 *length_ret = 0;
452 while (*font) {
453 (*length_ret)++;
454 if (*font++ == '-')
455 c++;
458 return c==NUM_FIELDS;
464 typedef struct {
465 char *weight;
466 char *slant;
468 char *setWidth;
469 char *addStyle;
471 char showSetWidth; /* when duplicated */
472 char showAddStyle; /* when duplicated */
474 WMArray *sizes;
475 } Typeface;
478 typedef struct {
479 char *name;
481 char *foundry;
482 char *registry, *encoding;
484 char showFoundry; /* when duplicated */
485 char showRegistry; /* when duplicated */
487 WMArray *typefaces;
488 } Family;
493 static int
494 compare_int(const void *a, const void *b)
496 int i1 = *(int*)a;
497 int i2 = *(int*)b;
499 if (i1 < i2)
500 return -1;
501 else if (i1 > i2)
502 return 1;
503 else
504 return 0;
509 static void
510 addSizeToTypeface(Typeface *face, int size)
512 if (size == 0) {
513 int j;
515 for (j = 0; j < sizeof(scalableFontSizes)/sizeof(int); j++) {
516 size = scalableFontSizes[j];
518 if (!WMCountInArray(face->sizes, (void*)size)) {
519 WMAddToArray(face->sizes, (void*)size);
522 WMSortArray(face->sizes, compare_int);
523 } else {
524 if (!WMCountInArray(face->sizes, (void*)size)) {
525 WMAddToArray(face->sizes, (void*)size);
526 WMSortArray(face->sizes, compare_int);
533 static void
534 addTypefaceToFamily(Family *family, char fontFields[NUM_FIELDS][256])
536 Typeface *face;
537 WMArrayIterator i;
539 if (family->typefaces) {
540 WM_ITERATE_ARRAY(family->typefaces, face, i) {
541 int size;
543 if (strcmp(face->weight, fontFields[WEIGHT]) != 0) {
544 continue;
546 if (strcmp(face->slant, fontFields[SLANT]) != 0) {
547 continue;
550 size = atoi(fontFields[PIXEL_SIZE]);
552 addSizeToTypeface(face, size);
554 return;
556 } else {
557 family->typefaces = WMCreateArray(4);
560 face = wmalloc(sizeof(Typeface));
561 memset(face, 0, sizeof(Typeface));
563 face->weight = wstrdup(fontFields[WEIGHT]);
564 face->slant = wstrdup(fontFields[SLANT]);
565 face->setWidth = wstrdup(fontFields[SETWIDTH]);
566 face->addStyle = wstrdup(fontFields[ADD_STYLE]);
568 face->sizes = WMCreateArray(4);
569 addSizeToTypeface(face, atoi(fontFields[PIXEL_SIZE]));
571 WMAddToArray(family->typefaces, face);
577 * families (same family name) (Hashtable of family -> array)
578 * registries (same family but different registries)
582 static void
583 addFontToFamily(WMHashTable *families, char fontFields[NUM_FIELDS][256])
585 WMArrayIterator i;
586 Family *fam;
587 WMArray *family;
590 family = WMHashGet(families, fontFields[FAMILY]);
592 if (family) {
593 /* look for same encoding/registry and foundry */
594 WM_ITERATE_ARRAY(family, fam, i) {
595 int enc, reg, found;
597 enc = (strcmp(fam->encoding, fontFields[ENCODING]) == 0);
598 reg = (strcmp(fam->registry, fontFields[REGISTRY]) == 0);
599 found = (strcmp(fam->foundry, fontFields[FOUNDRY]) == 0);
601 if (enc && reg && found) {
602 addTypefaceToFamily(fam, fontFields);
603 return;
606 /* look for same encoding/registry */
607 WM_ITERATE_ARRAY(family, fam, i) {
608 int enc, reg;
610 enc = (strcmp(fam->encoding, fontFields[ENCODING]) == 0);
611 reg = (strcmp(fam->registry, fontFields[REGISTRY]) == 0);
613 if (enc && reg) {
614 /* has the same encoding, but the foundry is different */
615 fam->showFoundry = 1;
617 fam = wmalloc(sizeof(Family));
618 memset(fam, 0, sizeof(Family));
620 fam->name = wstrdup(fontFields[FAMILY]);
621 fam->foundry = wstrdup(fontFields[FOUNDRY]);
622 fam->registry = wstrdup(fontFields[REGISTRY]);
623 fam->encoding = wstrdup(fontFields[ENCODING]);
624 fam->showFoundry = 1;
626 addTypefaceToFamily(fam, fontFields);
628 WMAddToArray(family, fam);
629 return;
632 /* look for same foundry */
633 WM_ITERATE_ARRAY(family, fam, i) {
634 int found;
636 found = (strcmp(fam->foundry, fontFields[FOUNDRY]) == 0);
638 if (found) {
639 /* has the same foundry, but encoding is different */
640 fam->showRegistry = 1;
642 fam = wmalloc(sizeof(Family));
643 memset(fam, 0, sizeof(Family));
645 fam->name = wstrdup(fontFields[FAMILY]);
646 fam->foundry = wstrdup(fontFields[FOUNDRY]);
647 fam->registry = wstrdup(fontFields[REGISTRY]);
648 fam->encoding = wstrdup(fontFields[ENCODING]);
649 fam->showRegistry = 1;
651 addTypefaceToFamily(fam, fontFields);
653 WMAddToArray(family, fam);
654 return;
657 /* foundry and encoding do not match anything known */
658 fam = wmalloc(sizeof(Family));
659 memset(fam, 0, sizeof(Family));
661 fam->name = wstrdup(fontFields[FAMILY]);
662 fam->foundry = wstrdup(fontFields[FOUNDRY]);
663 fam->registry = wstrdup(fontFields[REGISTRY]);
664 fam->encoding = wstrdup(fontFields[ENCODING]);
665 fam->showFoundry = 1;
666 fam->showRegistry = 1;
668 addTypefaceToFamily(fam, fontFields);
670 WMAddToArray(family, fam);
671 return;
674 family = WMCreateArray(8);
676 fam = wmalloc(sizeof(Family));
677 memset(fam, 0, sizeof(Family));
679 fam->name = wstrdup(fontFields[FAMILY]);
680 fam->foundry = wstrdup(fontFields[FOUNDRY]);
681 fam->registry = wstrdup(fontFields[REGISTRY]);
682 fam->encoding = wstrdup(fontFields[ENCODING]);
684 addTypefaceToFamily(fam, fontFields);
686 WMAddToArray(family, fam);
688 WMHashInsert(families, fam->name, family);
693 static void
694 listFamilies(WMScreen *scr, WMFontPanel *panel)
696 char **fontList;
697 int count;
698 int i;
699 WMHashTable *families = WMCreateHashTable(WMStringPointerHashCallbacks);
700 char fields[NUM_FIELDS][256];
701 WMHashEnumerator enumer;
702 WMArray *array;
704 fontList = XListFonts(scr->display, ALL_FONTS_MASK, MAX_FONTS_TO_RETRIEVE,
705 &count);
706 if (!fontList) {
707 WMRunAlertPanel(scr, panel->win, "Error",
708 "Could not retrieve font list", "OK", NULL, NULL);
709 return;
712 for (i = 0; i < count; i++) {
713 int fname_len;
715 if (!isXLFD(fontList[i], &fname_len)) {
716 *fontList[i] = '\0';
717 continue;
719 if (fname_len > 255) {
720 wwarning("font name %s is longer than 256, which is invalid.",
721 fontList[i]);
722 *fontList[i] = '\0';
723 continue;
725 if (!parseFont(fontList[i], fields)) {
726 *fontList[i] = '\0';
727 continue;
729 addFontToFamily(families, fields);
732 enumer = WMEnumerateHashTable(families);
734 while ((array = WMNextHashEnumeratorItem(&enumer))) {
735 WMArrayIterator i;
736 Family *fam;
737 char buffer[256];
738 WMListItem *item;
740 WM_ITERATE_ARRAY(array, fam, i) {
741 strcpy(buffer, fam->name);
743 if (fam->showFoundry) {
744 strcat(buffer, " ");
745 strcat(buffer, fam->foundry);
746 strcat(buffer, " ");
748 if (fam->showRegistry) {
749 strcat(buffer, " (");
750 strcat(buffer, fam->registry);
751 strcat(buffer, "-");
752 strcat(buffer, fam->encoding);
753 strcat(buffer, ")");
755 item = WMAddListItem(panel->famLs, buffer);
757 item->clientData = fam;
759 /* Isn't this going to memleak since items weren't released? --Dan */
760 WMFreeArray(array);
762 WMSortListItems(panel->famLs);
764 WMFreeHashTable(families);
768 static void
769 getSelectedFont(FontPanel *panel, char buffer[])
771 WMListItem *item;
772 Family *family;
773 Typeface *face;
774 char *size;
777 item = WMGetListSelectedItem(panel->famLs);
778 if (!item)
779 return;
780 family = (Family*)item->clientData;
782 item = WMGetListSelectedItem(panel->typLs);
783 if (!item)
784 return;
785 face = (Typeface*)item->clientData;
787 size = WMGetTextFieldText(panel->sizT);
789 sprintf(buffer, "-%s-%s-%s-%s-%s-%s-%s-*-*-*-*-*-%s-%s",
790 family->foundry,
791 family->name,
792 face->weight,
793 face->slant,
794 face->setWidth,
795 face->addStyle,
796 size,
797 family->registry,
798 family->encoding);
803 static void
804 preview(FontPanel *panel)
806 char buffer[256];
807 WMFont *font;
809 getSelectedFont(panel, buffer);
811 font = WMCreateFont(WMWidgetScreen(panel->win), buffer);
812 if (font) {
813 WMSetTextFieldFont(panel->sampleT, font);
814 WMReleaseFont(font);
820 static void
821 familyClick(WMWidget *w, void *data)
823 WMList *lPtr = (WMList*)w;
824 WMListItem *item;
825 Family *family;
826 FontPanel *panel = (FontPanel*)data;
827 Typeface *face;
828 WMArrayIterator i;
829 /* current typeface and size */
830 char *oface = NULL;
831 char *osize = NULL;
832 int facei = -1;
833 int sizei = -1;
835 /* must try to keep the same typeface and size for the new family */
836 item = WMGetListSelectedItem(panel->typLs);
837 if (item)
838 oface = wstrdup(item->text);
840 osize = WMGetTextFieldText(panel->sizT);
843 item = WMGetListSelectedItem(lPtr);
844 family = (Family*)item->clientData;
846 WMClearList(panel->typLs);
849 WM_ITERATE_ARRAY(family->typefaces, face, i) {
850 char buffer[256];
851 int top=0;
852 WMListItem *fitem;
854 if (strcmp(face->weight, "medium") == 0) {
855 buffer[0] = 0;
856 } else {
857 if (*face->weight) {
858 strcpy(buffer, face->weight);
859 buffer[0] = toupper(buffer[0]);
860 strcat(buffer, " ");
861 } else {
862 buffer[0] = 0;
866 if (strcmp(face->slant, "r") == 0) {
867 strcat(buffer, "Roman");
868 top = 1;
869 } else if (strcmp(face->slant, "i") == 0) {
870 strcat(buffer, "Italic");
871 } else if (strcmp(face->slant, "o") == 0) {
872 strcat(buffer, "Oblique");
873 } else if (strcmp(face->slant, "ri") == 0) {
874 strcat(buffer, "Rev Italic");
875 } else if (strcmp(face->slant, "ro") == 0) {
876 strcat(buffer, "Rev Oblique");
877 } else {
878 strcat(buffer, face->slant);
881 if (buffer[0] == 0) {
882 strcpy(buffer, "Normal");
885 if (top)
886 fitem = WMInsertListItem(panel->typLs, 0, buffer);
887 else
888 fitem = WMAddListItem(panel->typLs, buffer);
889 fitem->clientData = face;
892 if (oface) {
893 facei = WMFindRowOfListItemWithTitle(panel->typLs, oface);
894 wfree(oface);
896 if (facei < 0) {
897 facei = 0;
899 WMSelectListItem(panel->typLs, facei);
900 typefaceClick(panel->typLs, panel);
902 if (osize) {
903 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
905 if (sizei >= 0) {
906 WMSelectListItem(panel->sizLs, sizei);
907 sizeClick(panel->sizLs, panel);
910 if (osize)
911 wfree(osize);
914 preview(panel);
918 static void
919 typefaceClick(WMWidget *w, void *data)
921 FontPanel *panel = (FontPanel*)data;
922 WMListItem *item;
923 Typeface *face;
924 WMArrayIterator i;
925 char buffer[32];
927 char *osize = NULL;
928 int sizei = -1;
929 void *size;
931 osize = WMGetTextFieldText(panel->sizT);
934 item = WMGetListSelectedItem(panel->typLs);
935 face = (Typeface*)item->clientData;
937 WMClearList(panel->sizLs);
939 WM_ITERATE_ARRAY(face->sizes, size, i) {
940 if ((int)size != 0) {
941 sprintf(buffer, "%i", (int)size);
943 WMAddListItem(panel->sizLs, buffer);
947 if (osize) {
948 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, osize);
950 if (sizei < 0) {
951 sizei = WMFindRowOfListItemWithTitle(panel->sizLs, "12");
953 if (sizei < 0) {
954 sizei = 0;
956 WMSelectListItem(panel->sizLs, sizei);
957 WMSetListPosition(panel->sizLs, sizei);
958 sizeClick(panel->sizLs, panel);
960 if (osize)
961 wfree(osize);
963 preview(panel);
967 static void
968 sizeClick(WMWidget *w, void *data)
970 FontPanel *panel = (FontPanel*)data;
971 WMListItem *item;
973 item = WMGetListSelectedItem(panel->sizLs);
975 WMSetTextFieldText(panel->sizT, item->text);
977 WMSelectTextFieldRange(panel->sizT, wmkrange(0, strlen(item->text)));
979 preview(panel);