fixed a memleak in the font panel in WINGs
[wmaker-crm.git] / WINGs / wfontpanel.c
blob168a8a02420b56eea4d5160d5a3f1b5babc19f0c
5 #include "WINGsP.h"
6 #include "WUtil.h"
7 #include "wconfig.h"
9 #include <ctype.h>
10 #include <string.h>
13 typedef struct W_FontPanel {
14 WMWindow *win;
16 WMFrame *upperF;
17 WMTextField *sampleT;
19 WMSplitView *split;
21 WMFrame *lowerF;
22 WMLabel *famL;
23 WMList *famLs;
24 WMLabel *typL;
25 WMList *typLs;
26 WMLabel *sizL;
27 WMTextField *sizT;
28 WMList *sizLs;
30 WMButton *revertB;
31 WMButton *setB;
33 WMPropList *fdb;
34 } FontPanel;
37 #define MIN_UPPER_HEIGHT 20
38 #define MIN_LOWER_HEIGHT 140
41 #define MAX_FONTS_TO_RETRIEVE 2000
43 #define BUTTON_SPACE_HEIGHT 40
45 #define MIN_WIDTH 250
46 #define MIN_HEIGHT (MIN_UPPER_HEIGHT+MIN_LOWER_HEIGHT+BUTTON_SPACE_HEIGHT)
48 #define DEF_UPPER_HEIGHT 60
49 #define DEF_LOWER_HEIGHT 310
51 #define DEF_WIDTH 320
52 #define DEF_HEIGHT (DEF_UPPER_HEIGHT+DEF_LOWER_HEIGHT)
57 static int scalableFontSizes[] = {
58 8,
59 10,
60 11,
61 12,
62 14,
63 16,
64 18,
65 20,
66 24,
67 36,
68 48,
74 static void getSelectedFont(FontPanel *panel, char buffer[], int bufsize);
77 static void arrangeLowerFrame(FontPanel *panel);
79 static void familyClick(WMWidget *, void *);
80 static void typefaceClick(WMWidget *, void *);
81 static void sizeClick(WMWidget *, void *);
84 static void listFamilies(WMScreen *scr, WMFontPanel *panel);
87 static void
88 splitViewConstrainCallback(WMSplitView *sPtr, int indView, int *min, int *max)
90 if (indView == 0)
91 *min = MIN_UPPER_HEIGHT;
92 else
93 *min = MIN_LOWER_HEIGHT;
96 static void
97 notificationObserver(void *self, WMNotification *notif)
99 WMFontPanel *panel = (WMFontPanel*)self;
100 void *object = WMGetNotificationObject(notif);
102 if (WMGetNotificationName(notif) == WMViewSizeDidChangeNotification) {
103 if (object == WMWidgetView(panel->win)) {
104 int h = WMWidgetHeight(panel->win);
105 int w = WMWidgetWidth(panel->win);
107 WMResizeWidget(panel->split, w, h-BUTTON_SPACE_HEIGHT);
109 WMMoveWidget(panel->setB, w-80, h-(BUTTON_SPACE_HEIGHT-5));
111 WMMoveWidget(panel->revertB, w-240, h-(BUTTON_SPACE_HEIGHT-5));
113 } else if (object == WMWidgetView(panel->upperF)) {
115 if (WMWidgetHeight(panel->upperF) < MIN_UPPER_HEIGHT) {
116 WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF),
117 MIN_UPPER_HEIGHT);
118 } else {
119 WMResizeWidget(panel->sampleT, WMWidgetWidth(panel->upperF)-20,
120 WMWidgetHeight(panel->upperF)-10);
123 } else if (object == WMWidgetView(panel->lowerF)) {
125 if (WMWidgetHeight(panel->lowerF) < MIN_LOWER_HEIGHT) {
126 WMResizeWidget(panel->upperF, WMWidgetWidth(panel->upperF),
127 MIN_UPPER_HEIGHT);
129 WMMoveWidget(panel->lowerF, 0, WMWidgetHeight(panel->upperF)
130 + WMGetSplitViewDividerThickness(panel->split));
132 WMResizeWidget(panel->lowerF, WMWidgetWidth(panel->lowerF),
133 WMWidgetWidth(panel->split) - MIN_UPPER_HEIGHT
134 - WMGetSplitViewDividerThickness(panel->split));
135 } else {
136 arrangeLowerFrame(panel);
143 static void
144 closeWindow(WMWidget *w, void *data)
146 FontPanel *panel = (FontPanel*)data;
148 WMHideFontPanel(panel);
153 WMFontPanel*
154 WMGetFontPanel(WMScreen *scr)
156 FontPanel *panel;
157 WMColor *dark, *white;
158 WMFont *font;
159 int divThickness;
161 if (scr->sharedFontPanel)
162 return scr->sharedFontPanel;
165 panel = wmalloc(sizeof(FontPanel));
166 memset(panel, 0, sizeof(FontPanel));
168 panel->win = WMCreateWindow(scr, "fontPanel");
169 /* WMSetWidgetBackgroundColor(panel->win, WMWhiteColor(scr));*/
170 WMResizeWidget(panel->win, DEF_WIDTH, DEF_HEIGHT);
171 WMSetWindowMinSize(panel->win, MIN_WIDTH, MIN_HEIGHT);
172 WMSetViewNotifySizeChanges(WMWidgetView(panel->win), True);
174 WMSetWindowCloseAction(panel->win, closeWindow, panel);
176 panel->split = WMCreateSplitView(panel->win);
177 WMResizeWidget(panel->split, DEF_WIDTH, DEF_HEIGHT - BUTTON_SPACE_HEIGHT);
178 WMSetSplitViewConstrainProc(panel->split, splitViewConstrainCallback);
180 divThickness = WMGetSplitViewDividerThickness(panel->split);
182 panel->upperF = WMCreateFrame(panel->win);
183 WMSetFrameRelief(panel->upperF, WRFlat);
184 WMSetViewNotifySizeChanges(WMWidgetView(panel->upperF), True);
185 panel->lowerF = WMCreateFrame(panel->win);
186 /* WMSetWidgetBackgroundColor(panel->lowerF, WMBlackColor(scr));*/
187 WMSetFrameRelief(panel->lowerF, WRFlat);
188 WMSetViewNotifySizeChanges(WMWidgetView(panel->lowerF), True);
190 WMAddSplitViewSubview(panel->split, W_VIEW(panel->upperF));
191 WMAddSplitViewSubview(panel->split, W_VIEW(panel->lowerF));
193 WMResizeWidget(panel->upperF, DEF_WIDTH, DEF_UPPER_HEIGHT);
195 WMResizeWidget(panel->lowerF, DEF_WIDTH, DEF_LOWER_HEIGHT);
197 WMMoveWidget(panel->lowerF, 0, 60+divThickness);
199 white = WMWhiteColor(scr);
200 dark = WMDarkGrayColor(scr);
202 panel->sampleT = WMCreateTextField(panel->upperF);
203 WMResizeWidget(panel->sampleT, DEF_WIDTH - 20, 50);
204 WMMoveWidget(panel->sampleT, 10, 10);
205 WMSetTextFieldText(panel->sampleT, _("Test!!!"));
207 font = WMBoldSystemFontOfSize(scr, 12);
209 panel->famL = WMCreateLabel(panel->lowerF);
210 WMSetWidgetBackgroundColor(panel->famL, dark);
211 WMSetLabelText(panel->famL, _("Family"));
212 WMSetLabelFont(panel->famL, font);
213 WMSetLabelTextColor(panel->famL, white);
214 WMSetLabelRelief(panel->famL, WRSunken);
215 WMSetLabelTextAlignment(panel->famL, WACenter);
217 panel->famLs = WMCreateList(panel->lowerF);
218 WMSetListAction(panel->famLs, familyClick, panel);
220 panel->typL = WMCreateLabel(panel->lowerF);
221 WMSetWidgetBackgroundColor(panel->typL, dark);
222 WMSetLabelText(panel->typL, _("Typeface"));
223 WMSetLabelFont(panel->typL, font);
224 WMSetLabelTextColor(panel->typL, white);
225 WMSetLabelRelief(panel->typL, WRSunken);
226 WMSetLabelTextAlignment(panel->typL, WACenter);
228 panel->typLs = WMCreateList(panel->lowerF);
229 WMSetListAction(panel->typLs, typefaceClick, panel);
231 panel->sizL = WMCreateLabel(panel->lowerF);
232 WMSetWidgetBackgroundColor(panel->sizL, dark);
233 WMSetLabelText(panel->sizL, _("Size"));
234 WMSetLabelFont(panel->sizL, font);
235 WMSetLabelTextColor(panel->sizL, white);
236 WMSetLabelRelief(panel->sizL, WRSunken);
237 WMSetLabelTextAlignment(panel->sizL, WACenter);
239 panel->sizT = WMCreateTextField(panel->lowerF);
240 /* WMSetTextFieldAlignment(panel->sizT, WARight);*/
242 panel->sizLs = WMCreateList(panel->lowerF);
243 WMSetListAction(panel->sizLs, sizeClick, panel);
245 WMReleaseFont(font);
246 WMReleaseColor(white);
247 WMReleaseColor(dark);
249 panel->setB = WMCreateCommandButton(panel->win);
250 WMResizeWidget(panel->setB, 70, 24);
251 WMMoveWidget(panel->setB, 240, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT-5));
252 WMSetButtonText(panel->setB, _("Set"));
254 panel->revertB = WMCreateCommandButton(panel->win);
255 WMResizeWidget(panel->revertB, 70, 24);
256 WMMoveWidget(panel->revertB, 80, DEF_HEIGHT - (BUTTON_SPACE_HEIGHT-5));
257 WMSetButtonText(panel->revertB, _("Revert"));
259 WMRealizeWidget(panel->win);
261 WMMapSubwidgets(panel->upperF);
262 WMMapSubwidgets(panel->lowerF);
263 WMMapSubwidgets(panel->split);
264 WMMapSubwidgets(panel->win);
266 WMUnmapWidget(panel->revertB);
268 arrangeLowerFrame(panel);
270 scr->sharedFontPanel = panel;
273 /* register notification observers */
274 WMAddNotificationObserver(notificationObserver, panel,
275 WMViewSizeDidChangeNotification,
276 WMWidgetView(panel->win));
277 WMAddNotificationObserver(notificationObserver, panel,
278 WMViewSizeDidChangeNotification,
279 WMWidgetView(panel->upperF));
280 WMAddNotificationObserver(notificationObserver, panel,
281 WMViewSizeDidChangeNotification,
282 WMWidgetView(panel->lowerF));
285 listFamilies(scr, panel);
288 return panel;
292 void
293 WMFreeFontPanel(WMFontPanel *panel)
295 if (panel == WMWidgetScreen(panel->win)->sharedFontPanel) {
296 WMWidgetScreen(panel->win)->sharedFontPanel = NULL;
298 WMRemoveNotificationObserver(panel);
299 WMUnmapWidget(panel->win);
300 WMDestroyWidget(panel->win);
301 wfree(panel);
305 void
306 WMShowFontPanel(WMFontPanel *panel)
308 WMMapWidget(panel->win);
312 void
313 WMHideFontPanel(WMFontPanel *panel)
315 WMUnmapWidget(panel->win);
319 void
320 WMSetFontPanelFont(WMFontPanel *panel, WMFont *font)
326 Bool
327 WMSetFontPanelFontName(WMFontPanel *panel, char *fontName)
330 return True;
334 WMFont*
335 WMGetFontPanelFont(WMFontPanel *panel)
337 return WMGetTextFieldFont(panel->sampleT);
341 char*
342 WMGetFontPanelFontName(WMFontPanel *panel)
344 char name[512];
346 getSelectedFont(panel, name, sizeof(name));
348 return wstrdup(name);
353 static void
354 arrangeLowerFrame(FontPanel *panel)
356 int width = WMWidgetWidth(panel->lowerF) - 55 - 30;
357 int height = WMWidgetHeight(panel->split) - WMWidgetHeight(panel->upperF);
358 int fw, tw, sw;
360 #define LABEL_HEIGHT 20
362 height -= WMGetSplitViewDividerThickness(panel->split);
365 height -= LABEL_HEIGHT + 8;
367 fw = (125*width) / 235;
368 tw = (110*width) / 235;
369 sw = 55;
371 WMMoveWidget(panel->famL, 10, 0);
372 WMResizeWidget(panel->famL, fw, LABEL_HEIGHT);
374 WMMoveWidget(panel->famLs, 10, 23);
375 WMResizeWidget(panel->famLs, fw, height);
377 WMMoveWidget(panel->typL, 10+fw+3, 0);
378 WMResizeWidget(panel->typL, tw, LABEL_HEIGHT);
380 WMMoveWidget(panel->typLs, 10+fw+3, 23);
381 WMResizeWidget(panel->typLs, tw, height);
383 WMMoveWidget(panel->sizL, 10+fw+3+tw+3, 0);
384 WMResizeWidget(panel->sizL, sw+4, LABEL_HEIGHT);
386 WMMoveWidget(panel->sizT, 10+fw+3+tw+3, 23);
387 WMResizeWidget(panel->sizT, sw+4, 20);
389 WMMoveWidget(panel->sizLs, 10+fw+3+tw+3, 46);
390 WMResizeWidget(panel->sizLs, sw+4, height-23);
396 #define ALL_FONTS_MASK "-*-*-*-*-*-*-*-*-*-*-*-*-*-*"
398 #define FOUNDRY 0
399 #define FAMILY 1
400 #define WEIGHT 2
401 #define SLANT 3
402 #define SETWIDTH 4
403 #define ADD_STYLE 5
404 #define PIXEL_SIZE 6
405 #define POINT_SIZE 7
406 #define RES_X 8
407 #define RES_Y 9
408 #define SPACING 10
409 #define AV_WIDTH 11
410 #define REGISTRY 12
411 #define ENCODING 13
413 #define NUM_FIELDS 14
417 static Bool
418 parseFont(char *font, char values[NUM_FIELDS][256])
420 char *ptr;
421 int part;
422 char buffer[256], *bptr;
424 part = FOUNDRY;
425 ptr = font;
426 ptr++; /* skip first - */
427 bptr = buffer;
428 while (*ptr) {
429 if (*ptr == '-') {
430 *bptr = 0;
431 strcpy(values[part], buffer);
432 bptr = buffer;
433 part++;
434 } else {
435 *bptr++ = *ptr;
437 ptr++;
439 *bptr = 0;
440 strcpy(values[part], buffer);
442 return True;
447 static int
448 isXLFD(char *font, int *length_ret)
450 int c = 0;
452 *length_ret = 0;
453 while (*font) {
454 (*length_ret)++;
455 if (*font++ == '-')
456 c++;
459 return c==NUM_FIELDS;
465 typedef struct {
466 char *weight;
467 char *slant;
469 char *setWidth;
470 char *addStyle;
472 char showSetWidth; /* when duplicated */
473 char showAddStyle; /* when duplicated */
475 WMArray *sizes;
476 } Typeface;
479 typedef struct {
480 char *name;
482 char *foundry;
483 char *registry, *encoding;
485 char showFoundry; /* when duplicated */
486 char showRegistry; /* when duplicated */
488 WMArray *typefaces;
489 } Family;
494 static int
495 compare_int(const void *a, const void *b)
497 int i1 = *(int*)a;
498 int i2 = *(int*)b;
500 if (i1 < i2)
501 return -1;
502 else if (i1 > i2)
503 return 1;
504 else
505 return 0;
510 static void
511 addSizeToTypeface(Typeface *face, int size)
513 if (size == 0) {
514 int j;
516 for (j = 0; j < sizeof(scalableFontSizes)/sizeof(int); j++) {
517 size = scalableFontSizes[j];
519 if (!WMCountInArray(face->sizes, (void*)size)) {
520 WMAddToArray(face->sizes, (void*)size);
523 WMSortArray(face->sizes, compare_int);
524 } else {
525 if (!WMCountInArray(face->sizes, (void*)size)) {
526 WMAddToArray(face->sizes, (void*)size);
527 WMSortArray(face->sizes, compare_int);
534 static void
535 addTypefaceToFamily(Family *family, char fontFields[NUM_FIELDS][256])
537 Typeface *face;
538 WMArrayIterator i;
540 if (family->typefaces) {
541 WM_ITERATE_ARRAY(family->typefaces, face, i) {
542 int size;
544 if (strcmp(face->weight, fontFields[WEIGHT]) != 0) {
545 continue;
547 if (strcmp(face->slant, fontFields[SLANT]) != 0) {
548 continue;
551 size = atoi(fontFields[PIXEL_SIZE]);
553 addSizeToTypeface(face, size);
555 return;
557 } else {
558 family->typefaces = WMCreateArray(4);
561 face = wmalloc(sizeof(Typeface));
562 memset(face, 0, sizeof(Typeface));
564 face->weight = wstrdup(fontFields[WEIGHT]);
565 face->slant = wstrdup(fontFields[SLANT]);
566 face->setWidth = wstrdup(fontFields[SETWIDTH]);
567 face->addStyle = wstrdup(fontFields[ADD_STYLE]);
569 face->sizes = WMCreateArray(4);
570 addSizeToTypeface(face, atoi(fontFields[PIXEL_SIZE]));
572 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 WMHashTable *families;
698 char fields[NUM_FIELDS][256];
699 WMHashEnumerator enumer;
700 WMArray *array;
701 int i, count;
703 fontList = XListFonts(scr->display, ALL_FONTS_MASK, MAX_FONTS_TO_RETRIEVE,
704 &count);
705 if (!fontList) {
706 WMRunAlertPanel(scr, panel->win, _("Error"),
707 _("Could not retrieve font list"), _("OK"), NULL, NULL);
708 return;
711 families = WMCreateHashTable(WMStringPointerHashCallbacks);
713 for (i = 0; i < count; i++) {
714 int fname_len;
716 if (!isXLFD(fontList[i], &fname_len)) {
717 *fontList[i] = '\0';
718 continue;
720 if (fname_len > 255) {
721 wwarning(_("font name %s is longer than 256, which is invalid."),
722 fontList[i]);
723 *fontList[i] = '\0';
724 continue;
726 if (!parseFont(fontList[i], fields)) {
727 *fontList[i] = '\0';
728 continue;
730 addFontToFamily(families, fields);
733 enumer = WMEnumerateHashTable(families);
735 while ((array = WMNextHashEnumeratorItem(&enumer))) {
736 WMArrayIterator i;
737 Family *fam;
738 char buffer[256];
739 WMListItem *item;
741 WM_ITERATE_ARRAY(array, fam, i) {
742 strcpy(buffer, fam->name);
744 if (fam->showFoundry) {
745 strcat(buffer, " ");
746 strcat(buffer, fam->foundry);
747 strcat(buffer, " ");
749 if (fam->showRegistry) {
750 strcat(buffer, " (");
751 strcat(buffer, fam->registry);
752 strcat(buffer, "-");
753 strcat(buffer, fam->encoding);
754 strcat(buffer, ")");
756 item = WMAddListItem(panel->famLs, buffer);
758 item->clientData = fam;
760 WMFreeArray(array);
762 WMSortListItems(panel->famLs);
764 WMFreeHashTable(families);
768 static void
769 getSelectedFont(FontPanel *panel, char buffer[], int bufsize)
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 snprintf(buffer, bufsize, "-%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[512];
807 WMFont *font;
809 getSelectedFont(panel, buffer, sizeof(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);