Fix some bugs, DisableMiniwindows, _KWM_WIN_ICON_GEOMETRY..
[wmaker-crm.git] / WPrefs.app / Appearance.c
blob9c81676637c5c796de7cde2569410e9c8257164b
1 /* Apperance.c- color/texture for titlebar etc.
2 *
3 * WPrefs - Window Maker Preferences Program
4 *
5 * Copyright (c) 1999 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.
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.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 * USA.
24 #include "WPrefs.h"
26 #include <unistd.h>
27 #include <errno.h>
28 #include <ctype.h>
29 #include <time.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include <fcntl.h>
33 #include <unistd.h>
38 #include "TexturePanel.h"
40 typedef struct _Panel {
41 WMFrame *frame;
42 char *sectionName;
44 CallbackRec callbacks;
46 WMWindow *win;
48 WMLabel *prevL;
50 WMPopUpButton *secP;
52 /* texture list */
53 WMLabel *texL;
54 WMList *texLs;
55 WMLabel *texsL;
57 WMButton *newB;
58 WMButton *editB;
59 WMButton *ripB;
60 WMButton *delB;
62 int textureIndex[8];
64 WMFont *smallFont;
65 WMFont *normalFont;
66 WMFont *boldFont;
68 TexturePanel *texturePanel;
70 WMPixmap *onLed;
71 WMPixmap *offLed;
73 Pixmap preview;
75 char *fprefix;
76 } _Panel;
79 typedef struct {
80 char *title;
81 char *texture;
82 proplist_t prop;
83 Pixmap preview;
85 char *path;
87 char selectedFor;
88 unsigned current:1;
89 unsigned ispixmap:1;
90 } TextureListItem;
93 static void showData(_Panel *panel);
96 static void OpenExtractPanelFor(_Panel *panel, char *path);
98 #define ICON_FILE "appearance"
100 #define TNEW_FILE "tnew"
101 #define TDEL_FILE "tdel"
102 #define TEDIT_FILE "tedit"
103 #define TEXTR_FILE "textr"
107 /* XPM */
108 static char * blueled_xpm[] = {
109 "8 8 17 1",
110 " c None",
111 ". c #020204",
112 "+ c #16B6FC",
113 "@ c #176AFC",
114 "# c #163AFC",
115 "$ c #72D2FC",
116 "% c #224CF4",
117 "& c #76D6FC",
118 "* c #16AAFC",
119 "= c #CEE9FC",
120 "- c #229EFC",
121 "; c #164CFC",
122 "> c #FAFEFC",
123 ", c #2482FC",
124 "' c #1652FC",
125 ") c #1E76FC",
126 "! c #1A60FC",
127 " .... ",
128 " .=>-@. ",
129 ".=>$@@'.",
130 ".=$@!;;.",
131 ".!@*+!#.",
132 ".#'*+*,.",
133 " .@)@,. ",
134 " .... "};
137 /* XPM */
138 static char *blueled2_xpm[] = {
139 /* width height num_colors chars_per_pixel */
140 " 8 8 17 1",
141 /* colors */
142 ". c None",
143 "# c #090909",
144 "a c #4b63a4",
145 "b c #011578",
146 "c c #264194",
147 "d c #04338c",
148 "e c #989dac",
149 "f c #011a7c",
150 "g c #465c9c",
151 "h c #03278a",
152 "i c #6175ac",
153 "j c #011e74",
154 "k c #043a90",
155 "l c #042f94",
156 "m c #0933a4",
157 "n c #022184",
158 "o c #012998",
159 /* pixels */
160 "..####..",
161 ".#aimn#.",
162 "#aechnf#",
163 "#gchnjf#",
164 "#jndknb#",
165 "#bjdddl#",
166 ".#nono#.",
167 "..####.."
172 #define FTITLE (1<<0)
173 #define UTITLE (1<<1)
174 #define OTITLE (1<<2)
175 #define MTITLE (1<<3)
176 #define MITEM (1<<4)
177 #define ICON (1<<5)
178 #define BACK (1<<6)
179 #define EVERYTHING 0xff
184 #define TEXPREV_WIDTH 40
185 #define TEXPREV_HEIGHT 24
191 static void
192 str2rcolor(RContext *rc, char *name, RColor *color)
194 XColor xcolor;
196 XParseColor(rc->dpy, rc->cmap, name, &xcolor);
198 color->alpha = 255;
199 color->red = xcolor.red >> 8;
200 color->green = xcolor.green >> 8;
201 color->blue = xcolor.blue >> 8;
206 static void
207 dumpRImage(char *path, RImage *image)
209 FILE *f;
211 f = fopen(path, "w");
212 if (!f) {
213 wsyserror(path);
214 return;
216 fprintf(f, "%02x%02x%1x", image->width, image->height,
217 image->data[3]!=NULL ? 4 : 3);
219 fwrite(image->data[0], 1, image->width * image->height, f);
220 fwrite(image->data[1], 1, image->width * image->height, f);
221 fwrite(image->data[2], 1, image->width * image->height, f);
222 if (image->data[3])
223 fwrite(image->data[3], 1, image->width * image->height, f);
225 if (fclose(f) < 0) {
226 wsyserror(path);
232 static int
233 isPixmap(proplist_t prop)
235 proplist_t p;
236 char *s;
238 p = PLGetArrayElement(prop, 0);
239 s = PLGetString(p);
240 if (strcasecmp(&s[1], "pixmap")==0)
241 return 1;
242 else
243 return 0;
248 static Pixmap
249 renderTexture(WMScreen *scr, proplist_t texture, int width, int height,
250 char *path, int border)
252 char *type;
253 RImage *image;
254 Pixmap pixmap;
255 RContext *rc = WMScreenRContext(scr);
256 char *str;
257 RColor rcolor;
260 type = PLGetString(PLGetArrayElement(texture, 0));
262 image = RCreateImage(width, height, False);
264 if (strcasecmp(type, "solid")==0) {
266 str = PLGetString(PLGetArrayElement(texture, 1));
268 str2rcolor(rc, str, &rcolor);
270 RClearImage(image, &rcolor);
271 } else if (strcasecmp(&type[1], "gradient")==0) {
272 int style;
273 RColor rcolor2;
275 switch (toupper(type[0])) {
276 case 'V':
277 style = RVerticalGradient;
278 break;
279 case 'H':
280 style = RHorizontalGradient;
281 break;
282 default:
283 case 'D':
284 style = RDiagonalGradient;
285 break;
288 str = PLGetString(PLGetArrayElement(texture, 1));
289 str2rcolor(rc, str, &rcolor);
290 str = PLGetString(PLGetArrayElement(texture, 2));
291 str2rcolor(rc, str, &rcolor2);
293 image = RRenderGradient(width, height, &rcolor, &rcolor2, style);
294 } else if (strcasecmp(&type[2], "gradient")==0 && toupper(type[0])=='T') {
295 int style;
296 RColor rcolor2;
297 int i;
298 RImage *grad, *timage;
299 char *path;
301 switch (toupper(type[1])) {
302 case 'V':
303 style = RVerticalGradient;
304 break;
305 case 'H':
306 style = RHorizontalGradient;
307 break;
308 default:
309 case 'D':
310 style = RDiagonalGradient;
311 break;
314 str = PLGetString(PLGetArrayElement(texture, 3));
315 str2rcolor(rc, str, &rcolor);
316 str = PLGetString(PLGetArrayElement(texture, 4));
317 str2rcolor(rc, str, &rcolor2);
319 str = PLGetString(PLGetArrayElement(texture, 1));
321 path = wfindfileinarray(GetObjectForKey("PixmapPath"), str);
322 timage = RLoadImage(rc, path, 0);
324 if (!timage) {
325 wwarning("could not load file '%s': %s", path,
326 RMessageForError(RErrorCode));
327 } else {
328 grad = RRenderGradient(width, height, &rcolor, &rcolor2, style);
330 image = RMakeTiledImage(timage, width, height);
331 RDestroyImage(timage);
333 i = atoi(PLGetString(PLGetArrayElement(texture, 2)));
335 RCombineImagesWithOpaqueness(image, grad, i);
336 RDestroyImage(grad);
338 } else if (strcasecmp(&type[2], "gradient")==0 && toupper(type[0])=='M') {
339 int style;
340 RColor **colors;
341 int i, j;
343 switch (toupper(type[1])) {
344 case 'V':
345 style = RVerticalGradient;
346 break;
347 case 'H':
348 style = RHorizontalGradient;
349 break;
350 default:
351 case 'D':
352 style = RDiagonalGradient;
353 break;
356 j = PLGetNumberOfElements(texture);
358 if (j > 0) {
359 colors = wmalloc(j * sizeof(RColor*));
361 for (i = 2; i < j; i++) {
362 str = PLGetString(PLGetArrayElement(texture, i));
363 colors[i-2] = wmalloc(sizeof(RColor));
364 str2rcolor(rc, str, colors[i-2]);
366 colors[i-2] = NULL;
368 image = RRenderMultiGradient(width, height, colors, style);
370 for (i = 0; colors[i]!=NULL; i++)
371 free(colors[i]);
372 free(colors);
374 } else if (strcasecmp(&type[1], "pixmap")==0) {
375 RImage *timage;
376 int w, h;
377 char *path;
378 RColor color;
380 str = PLGetString(PLGetArrayElement(texture, 1));
382 path = wfindfileinarray(GetObjectForKey("PixmapPath"), str);
383 timage = RLoadImage(rc, path, 0);
385 if (!timage) {
386 wwarning("could not load file '%s': %s", path,
387 RMessageForError(RErrorCode));
388 } else {
389 str = PLGetString(PLGetArrayElement(texture, 2));
390 str2rcolor(rc, str, &color);
392 switch (toupper(type[0])) {
393 case 'T':
394 image = RMakeTiledImage(timage, width, height);
395 RDestroyImage(timage);
396 timage = image;
397 break;
398 case 'C':
399 image = RMakeCenteredImage(timage, width, height, &color);
400 RDestroyImage(timage);
401 timage = image;
402 break;
403 case 'S':
404 case 'M':
405 image = RScaleImage(timage, width, height);
406 RDestroyImage(timage);
407 timage = image;
408 break;
412 free(path);
415 if (!image)
416 return None;
418 if (path) {
419 dumpRImage(path, image);
422 if (border) {
423 RBevelImage(image, border);
426 RConvertImage(rc, image, &pixmap);
427 RDestroyImage(image);
429 return pixmap;
435 static void
436 updatePreviewBox(_Panel *panel, int elements)
438 WMScreen *scr = WMWidgetScreen(panel->win);
439 Display *dpy = WMScreenDisplay(scr);
440 /* RContext *rc = WMScreenRContext(scr);*/
441 int refresh = 0;
442 Pixmap pix;
443 GC gc;
444 WMListItem *item;
445 TextureListItem *titem;
447 gc = XCreateGC(dpy, WMWidgetXID(panel->win), 0, NULL);
450 if (!panel->preview) {
451 WMColor *color;
453 panel->preview = XCreatePixmap(dpy, WMWidgetXID(panel->win),
454 260-4, 165-4, WMScreenDepth(scr));
456 color = WMGrayColor(scr);
457 XFillRectangle(dpy, panel->preview, WMColorGC(color),
458 0, 0, 260-4, 165-4);
459 WMReleaseColor(color);
461 refresh = -1;
464 if (elements & FTITLE) {
465 item = WMGetListItem(panel->texLs, panel->textureIndex[0]);
466 titem = (TextureListItem*)item->clientData;
468 pix = renderTexture(scr, titem->prop, 220, 20, NULL, RBEV_RAISED2);
470 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 220, 20, 5, 10);
472 XFreePixmap(dpy, pix);
474 if (elements & UTITLE) {
475 item = WMGetListItem(panel->texLs, panel->textureIndex[1]);
476 titem = (TextureListItem*)item->clientData;
478 pix = renderTexture(scr, titem->prop, 220, 20, NULL, RBEV_RAISED2);
480 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 220, 20, 15, 35);
482 XFreePixmap(dpy, pix);
484 if (elements & OTITLE) {
485 item = WMGetListItem(panel->texLs, panel->textureIndex[2]);
486 titem = (TextureListItem*)item->clientData;
488 pix = renderTexture(scr, titem->prop, 220, 20, NULL, RBEV_RAISED2);
490 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 220, 20, 25, 60);
492 XFreePixmap(dpy, pix);
494 if (elements & MTITLE) {
495 item = WMGetListItem(panel->texLs, panel->textureIndex[3]);
496 titem = (TextureListItem*)item->clientData;
498 pix = renderTexture(scr, titem->prop, 100, 20, NULL, RBEV_RAISED2);
500 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 100, 20, 20, 95);
502 XFreePixmap(dpy, pix);
504 if (elements & MITEM) {
505 item = WMGetListItem(panel->texLs, panel->textureIndex[4]);
506 titem = (TextureListItem*)item->clientData;
508 pix = renderTexture(scr, titem->prop, 100, 18, NULL, RBEV_RAISED2);
510 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 100, 18, 20, 115);
511 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 100, 18, 20, 115 + 18);
512 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 100, 18, 20, 115 + 36);
514 XFreePixmap(dpy, pix);
516 if (elements & (MITEM|MTITLE)) {
517 XDrawLine(dpy, panel->preview, gc, 19, 95, 19, 115+36+20);
518 XDrawLine(dpy, panel->preview, gc, 19, 94, 119, 94);
521 if (elements & ICON) {
522 item = WMGetListItem(panel->texLs, panel->textureIndex[5]);
523 titem = (TextureListItem*)item->clientData;
525 pix = renderTexture(scr, titem->prop, 64, 64, NULL,
526 titem->ispixmap ? 0 : RBEV_RAISED3);
528 XCopyArea(dpy, pix, panel->preview, gc, 0, 0, 64, 64, 150, 90);
530 XFreePixmap(dpy, pix);
534 if (refresh < 0) {
535 WMPixmap *p;
536 p = WMCreatePixmapFromXPixmaps(scr, panel->preview, None,
537 260-4, 165-4, WMScreenDepth(scr));
539 WMSetLabelImage(panel->prevL, p);
540 WMReleasePixmap(p);
541 } else {
542 WMRedisplayWidget(panel->prevL);
545 XFreeGC(dpy, gc);
551 static void
552 cancelNewTexture(void *data)
554 _Panel *panel = (_Panel*)data;
556 HideTexturePanel(panel->texturePanel);
562 static char*
563 makeFileName(char *prefix)
565 char *fname;
567 fname = wstrdup(prefix);
569 while (access(fname, F_OK)==0) {
570 char buf[30];
572 free(fname);
573 sprintf(buf, "%08lx.cache", time(NULL));
574 fname = wstrappend(prefix, buf);
577 return fname;
583 static void
584 okNewTexture(void *data)
586 _Panel *panel = (_Panel*)data;
587 WMListItem *item;
588 char *name;
589 char *str;
590 proplist_t prop;
591 TextureListItem *titem;
592 WMScreen *scr = WMWidgetScreen(panel->win);
594 titem = wmalloc(sizeof(TextureListItem));
595 memset(titem, 0, sizeof(TextureListItem));
597 HideTexturePanel(panel->texturePanel);
599 name = GetTexturePanelTextureName(panel->texturePanel);
601 prop = GetTexturePanelTexture(panel->texturePanel);
603 str = PLGetDescription(prop);
605 titem->title = name;
606 titem->prop = prop;
607 titem->texture = str;
608 titem->selectedFor = 0;
610 titem->ispixmap = isPixmap(prop);
612 titem->path = makeFileName(panel->fprefix);
613 titem->preview = renderTexture(scr, prop, TEXPREV_WIDTH, TEXPREV_HEIGHT,
614 titem->path, 0);
616 item = WMAddListItem(panel->texLs, "");
617 item->clientData = titem;
619 WMSetListPosition(panel->texLs, WMGetListNumberOfRows(panel->texLs));
623 static void
624 okEditTexture(void *data)
626 _Panel *panel = (_Panel*)data;
627 WMListItem *item;
628 char *name;
629 char *str;
630 proplist_t prop;
631 TextureListItem *titem;
633 item = WMGetListItem(panel->texLs, WMGetListSelectedItemRow(panel->texLs));
634 titem = (TextureListItem*)item->clientData;
636 HideTexturePanel(panel->texturePanel);
638 if (titem->current) {
639 name = GetTexturePanelTextureName(panel->texturePanel);
641 free(titem->title);
642 titem->title = name;
645 prop = GetTexturePanelTexture(panel->texturePanel);
647 str = PLGetDescription(prop);
649 PLRelease(titem->prop);
650 titem->prop = prop;
652 titem->ispixmap = isPixmap(prop);
654 free(titem->texture);
655 titem->texture = str;
657 XFreePixmap(WMScreenDisplay(WMWidgetScreen(panel->texLs)), titem->preview);
658 titem->preview = renderTexture(WMWidgetScreen(panel->texLs), titem->prop,
659 TEXPREV_WIDTH, TEXPREV_HEIGHT,
660 titem->path, 0);
662 WMRedisplayWidget(panel->texLs);
664 if (titem->selectedFor)
665 updatePreviewBox(panel, titem->selectedFor);
670 static void
671 editTexture(WMWidget *w, void *data)
673 _Panel *panel = (_Panel*)data;
674 WMListItem *item;
675 TextureListItem *titem;
677 item = WMGetListItem(panel->texLs, WMGetListSelectedItemRow(panel->texLs));
678 titem = (TextureListItem*)item->clientData;
680 SetTexturePanelPixmapPath(panel->texturePanel,
681 GetObjectForKey("PixmapPath"));
683 SetTexturePanelTexture(panel->texturePanel, titem->title, titem->prop);
685 SetTexturePanelCancelAction(panel->texturePanel, cancelNewTexture, panel);
686 SetTexturePanelOkAction(panel->texturePanel, okEditTexture, panel);
688 ShowTexturePanel(panel->texturePanel);
693 static void
694 newTexture(WMWidget *w, void *data)
696 _Panel *panel = (_Panel*)data;
698 SetTexturePanelPixmapPath(panel->texturePanel,
699 GetObjectForKey("PixmapPath"));
701 SetTexturePanelTexture(panel->texturePanel, "New Texture", NULL);
703 SetTexturePanelCancelAction(panel->texturePanel, cancelNewTexture, panel);
705 SetTexturePanelOkAction(panel->texturePanel, okNewTexture, panel);
707 ShowTexturePanel(panel->texturePanel);
712 static void
713 deleteTexture(WMWidget *w, void *data)
715 _Panel *panel = (_Panel*)data;
716 WMListItem *item;
717 TextureListItem *titem;
718 int row;
719 int section;
721 section = WMGetPopUpButtonSelectedItem(panel->secP);
722 row = WMGetListSelectedItemRow(panel->texLs);
723 item = WMGetListItem(panel->texLs, row);
724 titem = (TextureListItem*)item->clientData;
726 if (titem->selectedFor & (1 << section)) {
727 TextureListItem *titem2;
729 panel->textureIndex[section] = section;
730 item = WMGetListItem(panel->texLs, section);
731 titem2 = (TextureListItem*)item->clientData;
732 titem2->selectedFor |= 1 << section;
735 free(titem->title);
736 free(titem->texture);
737 PLRelease(titem->prop);
738 if (titem->path) {
739 if (remove(titem->path) < 0 && errno != ENOENT) {
740 wsyserror("could not remove file %s", titem->path);
742 free(titem->path);
745 free(titem);
747 WMRemoveListItem(panel->texLs, row);
748 WMSetButtonEnabled(panel->delB, False);
754 static void
755 extractTexture(WMWidget *w, void *data)
757 _Panel *panel = (_Panel*)data;
758 char *path;
759 WMOpenPanel *opanel;
760 WMScreen *scr = WMWidgetScreen(w);
762 opanel = WMGetOpenPanel(scr);
763 WMSetFilePanelCanChooseDirectories(opanel, False);
764 WMSetFilePanelCanChooseFiles(opanel, True);
766 if (WMRunModalFilePanelForDirectory(opanel, panel->win, wgethomedir(),
767 _("Select File"), NULL)) {
768 path = WMGetFilePanelFileName(opanel);
770 OpenExtractPanelFor(panel, path);
772 free(path);
779 static void
780 changePage(WMWidget *w, void *data)
782 _Panel *panel = (_Panel*)data;
783 int section;
784 WMListItem *item;
785 TextureListItem *titem;
786 char *str;
788 section = WMGetPopUpButtonSelectedItem(panel->secP);
790 WMSelectListItem(panel->texLs, panel->textureIndex[section]);
792 WMSetListPosition(panel->texLs, panel->textureIndex[section]
793 - WMGetListNumberOfRows(panel->texLs)/2);
795 item = WMGetListItem(panel->texLs, panel->textureIndex[section]);
797 titem = (TextureListItem*)item->clientData;
799 str = wmalloc(strlen(titem->title) + strlen(titem->texture) + 4);
800 sprintf(str, "%s: %s", titem->title, titem->texture);
801 WMSetLabelText(panel->texsL, str);
802 free(str);
807 static void
808 textureClick(WMWidget *w, void *data)
810 _Panel *panel = (_Panel*)data;
811 int i;
812 WMListItem *item;
813 TextureListItem *titem;
815 i = WMGetListSelectedItemRow(panel->texLs);
817 item = WMGetListItem(panel->texLs, i);
819 titem = (TextureListItem*)item->clientData;
821 if (titem->current) {
822 WMSetButtonEnabled(panel->delB, False);
823 } else {
824 WMSetButtonEnabled(panel->delB, True);
830 static void
831 textureDoubleClick(WMWidget *w, void *data)
833 _Panel *panel = (_Panel*)data;
834 int i, section;
835 WMListItem *item;
836 TextureListItem *titem;
837 char *str;
839 /* unselect old texture */
840 section = WMGetPopUpButtonSelectedItem(panel->secP);
842 item = WMGetListItem(panel->texLs, panel->textureIndex[section]);
843 titem = (TextureListItem*)item->clientData;
844 titem->selectedFor &= ~(1 << section);
846 /* select new texture */
847 i = WMGetListSelectedItemRow(panel->texLs);
849 item = WMGetListItem(panel->texLs, i);
851 titem = (TextureListItem*)item->clientData;
853 titem->selectedFor |= 1<<section;
855 panel->textureIndex[section] = i;
857 WMRedisplayWidget(panel->texLs);
859 str = wmalloc(strlen(titem->title) + strlen(titem->texture) + 4);
860 sprintf(str, "%s: %s", titem->title, titem->texture);
861 WMSetLabelText(panel->texsL, str);
862 free(str);
864 updatePreviewBox(panel, 1<<section);
870 static void
871 paintListItem(WMList *lPtr, int index, Drawable d, char *text, int state,
872 WMRect *rect)
874 _Panel *panel = (_Panel*)WMGetHangedData(lPtr);
875 WMScreen *scr = WMWidgetScreen(lPtr);
876 int width, height, x, y;
877 Display *dpy = WMScreenDisplay(scr);
878 WMColor *white = WMWhiteColor(scr);
879 WMListItem *item;
880 WMColor *black = WMBlackColor(scr);
881 TextureListItem *titem;
883 width = rect->size.width;
884 height = rect->size.height;
885 x = rect->pos.x;
886 y = rect->pos.y;
888 if (state & WLDSSelected)
889 XFillRectangle(dpy, d, WMColorGC(white), x, y, width, height);
890 else
891 XClearArea(dpy, d, x, y, width, height, False);
893 item = WMGetListItem(lPtr, index);
894 titem = (TextureListItem*)item->clientData;
896 if (titem->preview)
897 XCopyArea(dpy, titem->preview, d, WMColorGC(black), 0, 0, TEXPREV_WIDTH,
898 TEXPREV_HEIGHT, x + 5, y + 5);
900 if ((1 << WMGetPopUpButtonSelectedItem(panel->secP)) & titem->selectedFor)
901 WMDrawPixmap(panel->onLed, d, x + TEXPREV_WIDTH + 10, y + 6);
902 else if (titem->selectedFor)
903 WMDrawPixmap(panel->offLed, d, x + TEXPREV_WIDTH + 10, y + 6);
905 WMDrawString(scr, d, WMColorGC(black), panel->boldFont,
906 x + TEXPREV_WIDTH + 22, y + 2, titem->title,
907 strlen(titem->title));
909 WMDrawString(scr, d, WMColorGC(black), panel->smallFont,
910 x + TEXPREV_WIDTH + 14, y + 18, titem->texture,
911 strlen(titem->texture));
914 WMReleaseColor(white);
915 WMReleaseColor(black);
920 static Pixmap
921 loadRImage(WMScreen *scr, char *path)
923 FILE *f;
924 RImage *image;
925 int w, h, d;
926 int i;
927 Pixmap pixmap;
929 f = fopen(path, "r");
930 if (!f)
931 return None;
933 fscanf(f, "%02x%02x%1x", &w, &h, &d);
935 image = RCreateImage(w, h, d == 4);
936 for (i = 0; i < d; i++) {
937 fread(image->data[i], 1, w*h, f);
939 fclose(f);
941 RConvertImage(WMScreenRContext(scr), image, &pixmap);
942 RDestroyImage(image);
944 return pixmap;
949 static void
950 fillTextureList(WMList *lPtr)
952 proplist_t textureList;
953 proplist_t texture;
954 WMUserDefaults *udb = WMGetStandardUserDefaults();
955 int i;
956 TextureListItem *titem;
957 WMScreen *scr = WMWidgetScreen(lPtr);
959 textureList = WMGetUDObjectForKey(udb, "TextureList");
960 if (!textureList)
961 return;
963 for (i = 0; i < PLGetNumberOfElements(textureList); i++) {
964 WMListItem *item;
966 texture = PLGetArrayElement(textureList, i);
968 titem = wmalloc(sizeof(TextureListItem));
969 memset(titem, 0, sizeof(TextureListItem));
971 titem->title = wstrdup(PLGetString(PLGetArrayElement(texture, 0)));
972 titem->prop = PLRetain(PLGetArrayElement(texture, 1));
973 titem->texture = PLGetDescription(titem->prop);
974 titem->selectedFor = 0;
975 titem->path = wstrdup(PLGetString(PLGetArrayElement(texture, 2)));
977 titem->preview = loadRImage(scr, titem->path);
978 if (!titem->preview) {
979 titem->preview = renderTexture(scr, titem->prop, TEXPREV_WIDTH,
980 TEXPREV_HEIGHT, NULL, 0);
982 item = WMAddListItem(lPtr, "");
983 item->clientData = titem;
988 static void
989 createPanel(Panel *p)
991 _Panel *panel = (_Panel*)p;
992 WMColor *color;
993 WMFont *font;
994 WMScreen *scr = WMWidgetScreen(panel->win);
996 char *tmp;
997 Bool ok = True;
999 panel->fprefix = wstrappend(wusergnusteppath(), "/.AppInfo");
1001 if (access(panel->fprefix, F_OK)!=0) {
1002 if (mkdir(panel->fprefix, 0755) < 0) {
1003 wsyserror(panel->fprefix);
1004 ok = False;
1007 if (ok) {
1008 tmp = wstrappend(panel->fprefix, "/WPrefs/");
1009 free(panel->fprefix);
1010 panel->fprefix = tmp;
1011 if (access(panel->fprefix, F_OK)!=0) {
1012 if (mkdir(panel->fprefix, 0755) < 0) {
1013 wsyserror(panel->fprefix);
1018 panel->smallFont = WMSystemFontOfSize(scr, 10);
1019 panel->normalFont = WMSystemFontOfSize(scr, 12);
1020 panel->boldFont = WMBoldSystemFontOfSize(scr, 12);
1022 panel->onLed = WMCreatePixmapFromXPMData(scr, blueled_xpm);
1023 panel->offLed = WMCreatePixmapFromXPMData(scr, blueled2_xpm);
1025 panel->frame = WMCreateFrame(panel->win);
1026 WMResizeWidget(panel->frame, FRAME_WIDTH, FRAME_HEIGHT);
1027 WMMoveWidget(panel->frame, FRAME_LEFT, FRAME_TOP);
1029 /* preview box */
1030 panel->prevL = WMCreateLabel(panel->frame);
1031 WMResizeWidget(panel->prevL, 260, 165);
1032 WMMoveWidget(panel->prevL, 15, 10);
1033 WMSetLabelRelief(panel->prevL, WRSunken);
1034 WMSetLabelImagePosition(panel->prevL, WIPImageOnly);
1036 panel->secP = WMCreatePopUpButton(panel->frame);
1037 WMResizeWidget(panel->secP, 260, 20);
1038 WMMoveWidget(panel->secP, 15, 180);
1039 WMSetPopUpButtonSelectedItem(panel->secP, 0);
1040 WMAddPopUpButtonItem(panel->secP, _("Titlebar of Focused Window"));
1041 WMAddPopUpButtonItem(panel->secP, _("Titlebar of Unfocused Windows"));
1042 WMAddPopUpButtonItem(panel->secP, _("Titlebar of Focused Window's Owner"));
1043 WMAddPopUpButtonItem(panel->secP, _("Titlebar of Menus"));
1044 WMAddPopUpButtonItem(panel->secP, _("Menu Items"));
1045 WMAddPopUpButtonItem(panel->secP, _("Icon Background"));
1046 /* WMAddPopUpButtonItem(panel->secP, _("Workspace Backgrounds"));
1048 WMSetPopUpButtonAction(panel->secP, changePage, panel);
1051 panel->texsL = WMCreateLabel(panel->frame);
1052 WMResizeWidget(panel->texsL, 260, 20);
1053 WMMoveWidget(panel->texsL, 15, 205);
1054 WMSetLabelWraps(panel->texsL, False);
1056 /* texture list */
1057 font = WMBoldSystemFontOfSize(scr, 12);
1059 panel->texL = WMCreateLabel(panel->frame);
1060 WMResizeWidget(panel->texL, 225, 18);
1061 WMMoveWidget(panel->texL, 285, 10);
1062 WMSetLabelFont(panel->texL, font);
1063 WMSetLabelText(panel->texL, _("Textures"));
1064 WMSetLabelRelief(panel->texL, WRSunken);
1065 WMSetLabelTextAlignment(panel->texL, WACenter);
1066 color = WMDarkGrayColor(scr);
1067 WMSetWidgetBackgroundColor(panel->texL, color);
1068 WMReleaseColor(color);
1069 color = WMWhiteColor(scr);
1070 WMSetLabelTextColor(panel->texL, color);
1071 WMReleaseColor(color);
1073 WMReleaseFont(font);
1075 panel->texLs = WMCreateList(panel->frame);
1076 WMResizeWidget(panel->texLs, 225, 144);
1077 WMMoveWidget(panel->texLs, 285, 30);
1078 WMSetListUserDrawItemHeight(panel->texLs, 35);
1079 WMSetListUserDrawProc(panel->texLs, paintListItem);
1080 WMHangData(panel->texLs, panel);
1081 WMSetListAction(panel->texLs, textureClick, panel);
1082 WMSetListDoubleAction(panel->texLs, textureDoubleClick, panel);
1084 /* command buttons */
1086 font = WMSystemFontOfSize(scr, 10);
1089 panel->newB = WMCreateCommandButton(panel->frame);
1090 WMResizeWidget(panel->newB, 56, 48);
1091 WMMoveWidget(panel->newB, 285, 180);
1092 WMSetButtonFont(panel->newB, font);
1093 WMSetButtonImagePosition(panel->newB, WIPAbove);
1094 WMSetButtonText(panel->newB, _("New"));
1095 WMSetButtonAction(panel->newB, newTexture, panel);
1096 SetButtonAlphaImage(scr, panel->newB, TNEW_FILE);
1098 panel->ripB = WMCreateCommandButton(panel->frame);
1099 WMResizeWidget(panel->ripB, 56, 48);
1100 WMMoveWidget(panel->ripB, 341, 180);
1101 WMSetButtonFont(panel->ripB, font);
1102 WMSetButtonImagePosition(panel->ripB, WIPAbove);
1103 WMSetButtonText(panel->ripB, _("Extract..."));
1104 WMSetButtonAction(panel->ripB, extractTexture, panel);
1105 SetButtonAlphaImage(scr, panel->ripB, TEXTR_FILE);
1107 WMSetButtonEnabled(panel->ripB, False);
1109 panel->editB = WMCreateCommandButton(panel->frame);
1110 WMResizeWidget(panel->editB, 56, 48);
1111 WMMoveWidget(panel->editB, 397, 180);
1112 WMSetButtonFont(panel->editB, font);
1113 WMSetButtonImagePosition(panel->editB, WIPAbove);
1114 WMSetButtonText(panel->editB, _("Edit"));
1115 SetButtonAlphaImage(scr, panel->editB, TEDIT_FILE);
1116 WMSetButtonAction(panel->editB, editTexture, panel);
1118 panel->delB = WMCreateCommandButton(panel->frame);
1119 WMResizeWidget(panel->delB, 56, 48);
1120 WMMoveWidget(panel->delB, 453, 180);
1121 WMSetButtonFont(panel->delB, font);
1122 WMSetButtonImagePosition(panel->delB, WIPAbove);
1123 WMSetButtonText(panel->delB, _("Delete"));
1124 SetButtonAlphaImage(scr, panel->delB, TDEL_FILE);
1125 WMSetButtonEnabled(panel->delB, False);
1126 WMSetButtonAction(panel->delB, deleteTexture, panel);
1128 WMReleaseFont(font);
1130 /**/
1132 WMRealizeWidget(panel->frame);
1133 WMMapSubwidgets(panel->frame);
1135 WMSetPopUpButtonSelectedItem(panel->secP, 0);
1137 showData(panel);
1139 changePage(panel->secP, panel);
1141 fillTextureList(panel->texLs);
1143 panel->texturePanel = CreateTexturePanel(panel->win);
1148 static void
1149 setupTextureFor(WMList *list, char *key, char *defValue, char *title,
1150 int index)
1152 WMListItem *item;
1153 TextureListItem *titem;
1155 titem = wmalloc(sizeof(TextureListItem));
1156 memset(titem, 0, sizeof(TextureListItem));
1158 titem->title = wstrdup(title);
1159 titem->prop = GetObjectForKey(key);
1160 if (!titem->prop) {
1161 titem->prop = PLGetProplistWithDescription(defValue);
1162 } else {
1163 PLRetain(titem->prop);
1165 titem->texture = PLGetDescription((proplist_t)titem->prop);
1166 titem->current = 1;
1167 titem->selectedFor = 1<<index;
1169 titem->ispixmap = isPixmap(titem->prop);
1171 titem->preview = renderTexture(WMWidgetScreen(list), titem->prop,
1172 TEXPREV_WIDTH, TEXPREV_HEIGHT, NULL, 0);
1174 item = WMAddListItem(list, "");
1175 item->clientData = titem;
1180 static void
1181 showData(_Panel *panel)
1183 int i = 0;
1185 setupTextureFor(panel->texLs, "FTitleBack", "(solid, black)",
1186 "[Focused]", i);
1187 panel->textureIndex[i] = i++;
1189 setupTextureFor(panel->texLs, "UTitleBack", "(solid, gray)",
1190 "[Unfocused]", i);
1191 panel->textureIndex[i] = i++;
1193 setupTextureFor(panel->texLs, "PTitleBack", "(solid, \"#616161\")",
1194 "[Owner of Focused]", i);
1195 panel->textureIndex[i] = i++;
1197 setupTextureFor(panel->texLs, "MenuTitleBack", "(solid, black)",
1198 "[Menu Title]", i);
1199 panel->textureIndex[i] = i++;
1201 setupTextureFor(panel->texLs, "MenuTextBack", "(solid, gray)",
1202 "[Menu Item]", i);
1203 panel->textureIndex[i] = i++;
1205 setupTextureFor(panel->texLs, "IconBack", "(solid, gray)", "[Icon]", i);
1206 panel->textureIndex[i] = i++;
1208 setupTextureFor(panel->texLs, "WorkspaceBack", "(solid, black)",
1209 "[Workspace]", i);
1210 panel->textureIndex[i] = i++;
1213 updatePreviewBox(panel, EVERYTHING);
1218 static void
1219 storeData(_Panel *panel)
1221 TextureListItem *titem;
1222 WMListItem *item;
1224 item = WMGetListItem(panel->texLs, panel->textureIndex[0]);
1225 titem = (TextureListItem*)item->clientData;
1226 SetObjectForKey(titem->prop, "FTitleBack");
1228 item = WMGetListItem(panel->texLs, panel->textureIndex[1]);
1229 titem = (TextureListItem*)item->clientData;
1230 SetObjectForKey(titem->prop, "UTitleBack");
1232 item = WMGetListItem(panel->texLs, panel->textureIndex[2]);
1233 titem = (TextureListItem*)item->clientData;
1234 SetObjectForKey(titem->prop, "PTitleBack");
1236 item = WMGetListItem(panel->texLs, panel->textureIndex[3]);
1237 titem = (TextureListItem*)item->clientData;
1238 SetObjectForKey(titem->prop, "MenuTitleBack");
1240 item = WMGetListItem(panel->texLs, panel->textureIndex[4]);
1241 titem = (TextureListItem*)item->clientData;
1242 SetObjectForKey(titem->prop, "MenuTextBack");
1244 item = WMGetListItem(panel->texLs, panel->textureIndex[5]);
1245 titem = (TextureListItem*)item->clientData;
1246 SetObjectForKey(titem->prop, "IconBack");
1250 static void
1251 prepareForClose(_Panel *panel)
1253 proplist_t textureList;
1254 proplist_t texture;
1255 int i;
1256 TextureListItem *titem;
1257 WMListItem *item;
1258 WMUserDefaults *udb = WMGetStandardUserDefaults();
1260 textureList = PLMakeArrayFromElements(NULL, NULL);
1262 /* store list of textures */
1263 for (i = 6; i < WMGetListNumberOfRows(panel->texLs); i++) {
1264 item = WMGetListItem(panel->texLs, i);
1265 titem = (TextureListItem*)item->clientData;
1267 texture = PLMakeArrayFromElements(PLMakeString(titem->title),
1268 PLRetain(titem->prop),
1269 PLMakeString(titem->path),
1270 NULL);
1272 PLAppendArrayElement(textureList, texture);
1275 WMSetUDObjectForKey(udb, textureList, "TextureList");
1276 PLRelease(textureList);
1278 WMSynchronizeUserDefaults(udb);
1283 Panel*
1284 InitAppearance(WMScreen *scr, WMWindow *win)
1286 _Panel *panel;
1288 panel = wmalloc(sizeof(_Panel));
1289 memset(panel, 0, sizeof(_Panel));
1291 panel->sectionName = _("Appearance Preferences");
1293 panel->win = win;
1295 panel->callbacks.createWidgets = createPanel;
1296 panel->callbacks.updateDomain = storeData;
1297 panel->callbacks.prepareForClose = prepareForClose;
1299 AddSection(panel, ICON_FILE);
1301 return panel;
1306 /****************************************************************************/
1310 typedef struct ExtractPanel {
1311 WMWindow *win;
1313 WMLabel *label;
1314 WMList *list;
1316 WMButton *closeB;
1317 WMButton *extrB;
1318 } ExtractPanel;
1322 static void
1323 OpenExtractPanelFor(_Panel *panel, char *path)
1325 ExtractPanel *epanel;
1326 WMColor *color;
1327 WMFont *font;
1328 WMScreen *scr = WMWidgetScreen(panel->win);
1330 epanel = wmalloc(sizeof(ExtractPanel));
1331 epanel->win = WMCreatePanelWithStyleForWindow(panel->win, "extract",
1332 WMTitledWindowMask
1333 |WMClosableWindowMask);
1334 WMResizeWidget(epanel->win, 245, 250);
1335 WMSetWindowTitle(epanel->win, _("Extract Texture"));
1337 epanel->label = WMCreateLabel(epanel->win);
1338 WMResizeWidget(epanel->label, 225, 18);
1339 WMMoveWidget(epanel->label, 10, 10);
1340 WMSetLabelTextAlignment(epanel->label, WACenter);
1341 WMSetLabelRelief(epanel->label, WRSunken);
1343 color = WMDarkGrayColor(scr);
1344 WMSetWidgetBackgroundColor(epanel->label, color);
1345 WMReleaseColor(color);
1347 color = WMWhiteColor(scr);
1348 WMSetLabelTextColor(epanel->label, color);
1349 WMReleaseColor(color);
1351 font = WMBoldSystemFontOfSize(scr, 12);
1352 WMSetLabelFont(epanel->label, font);
1353 WMReleaseFont(font);
1355 WMSetLabelText(epanel->label, _("Textures"));
1357 epanel->list = WMCreateList(epanel->win);
1358 WMResizeWidget(epanel->list, 225, 165);
1359 WMMoveWidget(epanel->list, 10, 30);
1363 epanel->closeB = WMCreateCommandButton(epanel->win);
1364 WMResizeWidget(epanel->closeB, 74, 24);
1365 WMMoveWidget(epanel->closeB, 165, 215);
1366 WMSetButtonText(epanel->closeB, _("Close"));
1368 epanel->extrB = WMCreateCommandButton(epanel->win);
1369 WMResizeWidget(epanel->extrB, 74, 24);
1370 WMMoveWidget(epanel->extrB, 80, 215);
1371 WMSetButtonText(epanel->extrB, _("Extract"));
1373 WMMapSubwidgets(epanel->win);
1376 /* take textures from file */
1380 WMRealizeWidget(epanel->win);
1382 WMMapWidget(epanel->win);