7 #define PWID 1 /* width of label border */
8 #define BWID 1 /* width of button relief */
9 #define FWID 2 /* width of frame relief */
10 #define SPACE 1 /* space inside relief of button or frame */
11 #define CKSIZE 3 /* size of check mark */
12 #define CKSPACE 2 /* space around check mark */
13 #define CKWID 1 /* width of frame around check mark */
14 #define CKINSET 1 /* space around check mark frame */
15 #define CKBORDER 2 /* space around X inside frame */
17 static Image *pl_white, *pl_light, *pl_dark, *pl_black, *pl_hilit;
18 int pl_drawinit(int ldepth){
20 pl_white=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xFFFFFFFF);
21 pl_light=allocimagemix(display, DPalebluegreen, DWhite);
22 pl_dark =allocimage(display, Rect(0,0,1,1), screen->chan, 1, DPurpleblue);
23 pl_black=allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x000000FF);
24 pl_hilit=allocimage(display, Rect(0,0,1,1), CHAN1(CAlpha,8), 1, 0x80);
25 if(pl_white==0 || pl_light==0 || pl_black==0 || pl_dark==0) return 0;
28 void pl_relief(Image *b, Image *ul, Image *lr, Rectangle r, int wid){
30 draw(b, Rect(r.min.x, r.max.y-wid, r.max.x, r.max.y), lr, 0, ZP); /* bottom */
31 draw(b, Rect(r.max.x-wid, r.min.y, r.max.x, r.max.y), lr, 0, ZP); /* right */
32 draw(b, Rect(r.min.x, r.min.y, r.min.x+wid, r.max.y), ul, 0, ZP); /* left */
33 draw(b, Rect(r.min.x, r.min.y, r.max.x, r.min.y+wid), ul, 0, ZP); /* top */
34 for(x=0;x!=wid;x++) for(y=wid-1-x;y!=wid;y++){
35 draw(b, rectaddpt(Rect(0,0,1,1), Pt(x+r.max.x-wid, y+r.min.y)), lr, 0, ZP);
36 draw(b, rectaddpt(Rect(0,0,1,1), Pt(x+r.min.x, y+r.max.y-wid)), lr, 0, ZP);
39 Rectangle pl_boxoutline(Image *b, Rectangle r, int style, int fill){
40 if(plldepth==0) switch(style){
42 pl_relief(b, pl_black, pl_black, r, BWID);
44 if(fill) draw(b, r, pl_white, 0, ZP);
45 else border(b, r, SPACE, pl_white, ZP);
51 pl_relief(b, pl_black, pl_black, r, BWID);
53 if(fill) draw(b, r, pl_black, 0, ZP);
54 border(b, r, SPACE, pl_black, ZP);
57 if(fill) draw(b, r, pl_white, 0, ZP);
59 if(!fill) border(b, r, SPACE, pl_white, ZP);
62 pl_relief(b, pl_white, pl_black, r, FWID);
64 pl_relief(b, pl_black, pl_white, r, FWID);
66 if(fill) draw(b, r, pl_white, 0, ZP);
67 else border(b, r, SPACE, pl_white, ZP);
72 pl_relief(b, pl_white, pl_black, r, BWID);
74 if(fill) draw(b, r, pl_light, 0, ZP);
75 else border(b, r, SPACE, pl_white, ZP);
81 pl_relief(b, pl_black, pl_white, r, BWID);
83 if(fill) draw(b, r, pl_dark, 0, ZP);
84 else border(b, r, SPACE, pl_black, ZP);
87 if(fill) draw(b, r, pl_light, 0, ZP);
89 if(!fill) border(b, r, SPACE, pl_white, ZP);
92 pl_relief(b, pl_white, pl_black, r, FWID);
94 pl_relief(b, pl_black, pl_white, r, FWID);
96 if(fill) draw(b, r, pl_light, 0, ZP);
97 else border(b, r, SPACE, pl_white, ZP);
100 return insetrect(r, SPACE);
102 Rectangle pl_outline(Image *b, Rectangle r, int style){
103 return pl_boxoutline(b, r, style, 0);
105 Rectangle pl_box(Image *b, Rectangle r, int style){
106 return pl_boxoutline(b, r, style, 1);
108 Point pl_boxsize(Point interior, int state){
115 return addpt(interior, Pt(2*(BWID+SPACE), 2*(BWID+SPACE)));
117 return addpt(interior, Pt(2*(PWID+SPACE), 2*(PWID+SPACE)));
119 return addpt(interior, Pt(4*FWID+2*SPACE, 4*FWID+2*SPACE));
123 void pl_interior(int state, Point *ul, Point *size){
130 *ul=addpt(*ul, Pt(BWID+SPACE, BWID+SPACE));
131 *size=subpt(*size, Pt(2*(BWID+SPACE), 2*(BWID+SPACE)));
134 *ul=addpt(*ul, Pt(PWID+SPACE, PWID+SPACE));
135 *size=subpt(*size, Pt(2*(PWID+SPACE), 2*(PWID+SPACE)));
138 *ul=addpt(*ul, Pt(2*FWID+SPACE, 2*FWID+SPACE));
139 *size=subpt(*size, Pt(4*FWID+2*SPACE, 4*FWID+2*SPACE));
143 void pl_drawicon(Image *b, Rectangle r, int stick, int flags, Icon *s){
147 offs=subpt(subpt(r.max, r.min), pl_iconsize(flags, s));
150 case PLACEN: ul.x+=offs.x/2; break;
151 case PLACENE: ul.x+=offs.x; break;
152 case PLACEW: ul.y+=offs.y/2; break;
153 case PLACECEN: ul.x+=offs.x/2; ul.y+=offs.y/2; break;
154 case PLACEE: ul.x+=offs.x; break;
155 case PLACESW: ul.y+=offs.y; break;
156 case PLACES: ul.x+=offs.x/2; ul.y+=offs.y; break;
157 case PLACESE: ul.x+=offs.x; ul.y+=offs.y; break;
160 if(!rectclip(&r, save))
162 replclipr(b, b->repl, r);
163 if(flags&BITMAP) draw(b, Rpt(ul, addpt(ul, pl_iconsize(flags, s))), s, 0, ZP);
164 else string(b, ul, pl_black, ZP, font, s);
165 replclipr(b, b->repl, save);
168 * Place a check mark at the left end of r. Return the unused space.
169 * Caller must guarantee that r.max.x-r.min.x>=r.max.y-r.min.y!
171 Rectangle pl_radio(Image *b, Rectangle r, int val){
174 r.max.x=r.min.x+r.max.y-r.min.y;
175 remainder.min.x=r.max.x;
176 r=insetrect(r, CKINSET);
178 pl_relief(b, pl_black, pl_black, r, CKWID);
180 pl_relief(b, pl_black, pl_white, r, CKWID);
181 r=insetrect(r, CKWID);
183 draw(b, r, pl_white, 0, ZP);
185 draw(b, r, pl_light, 0, ZP);
186 if(val) draw(b, insetrect(r, CKSPACE), pl_black, 0, ZP);
189 Rectangle pl_check(Image *b, Rectangle r, int val){
192 r.max.x=r.min.x+r.max.y-r.min.y;
193 remainder.min.x=r.max.x;
194 r=insetrect(r, CKINSET);
196 pl_relief(b, pl_black, pl_black, r, CKWID);
198 pl_relief(b, pl_black, pl_white, r, CKWID);
199 r=insetrect(r, CKWID);
201 draw(b, r, pl_white, 0, ZP);
203 draw(b, r, pl_light, 0, ZP);
204 r=insetrect(r, CKBORDER);
206 line(b, Pt(r.min.x, r.min.y+1), Pt(r.max.x-1, r.max.y ), Endsquare, Endsquare, 0, pl_black, ZP);
207 line(b, Pt(r.min.x, r.min.y ), Pt(r.max.x, r.max.y ), Endsquare, Endsquare, 0, pl_black, ZP);
208 line(b, Pt(r.min.x+1, r.min.y ), Pt(r.max.x, r.max.y-1), Endsquare, Endsquare, 0, pl_black, ZP);
209 line(b, Pt(r.min.x , r.max.y-2), Pt(r.max.x-1, r.min.y-1), Endsquare, Endsquare, 0, pl_black, ZP);
210 line(b, Pt(r.min.x, r.max.y-1), Pt(r.max.x, r.min.y-1), Endsquare, Endsquare, 0, pl_black, ZP);
211 line(b, Pt(r.min.x+1, r.max.y-1), Pt(r.max.x, r.min.y ), Endsquare, Endsquare, 0, pl_black, ZP);
216 return 2*(CKINSET+CKSPACE+CKWID)+CKSIZE;
218 void pl_sliderupd(Image *b, Rectangle r1, int dir, int lo, int hi){
226 r1.max.x=r1.min.x+lo;
228 r2.max.x=r1.min.x+hi;
229 if(r2.max.x>r3.max.x) r2.max.x=r3.max.x;
233 r1.max.y=r1.min.y+lo;
235 r2.max.y=r1.min.y+hi;
236 if(r2.max.y>r3.max.y) r2.max.y=r3.max.y;
240 draw(b, r1, pl_light, 0, ZP);
241 draw(b, r2, pl_dark, 0, ZP);
242 draw(b, r3, pl_light, 0, ZP);
244 void pl_draw1(Panel *p, Image *b);
245 void pl_drawall(Panel *p, Image *b){
246 if(p->flags&INVIS) return;
249 for(p=p->child;p;p=p->next) pl_draw1(p, b);
251 void pl_draw1(Panel *p, Image *b){
255 void pldraw(Panel *p, Image *b){
257 flushimage(display, 1);
259 void pl_invis(Panel *p, int v){
261 if(v) p->flags|=INVIS; else p->flags&=~INVIS;
262 pl_invis(p->child, v);
265 Point pl_iconsize(int flags, Icon *p){
266 if(flags&BITMAP) return subpt(((Image *)p)->r.max, ((Image *)p)->r.min);
267 return stringsize(font, (char *)p);
269 void pl_highlight(Image *b, Rectangle r){
270 draw(b, r, pl_dark, pl_hilit, ZP);
272 void pl_clr(Image *b, Rectangle r){
273 draw(b, r, display->white, 0, ZP);
275 void pl_fill(Image *b, Rectangle r){
276 draw(b, r, plldepth==0? pl_white : pl_light, 0, ZP);
278 void pl_cpy(Image *b, Point dst, Rectangle src){
279 draw(b, Rpt(dst, addpt(dst, subpt(src.max, src.min))), b, 0, src.min);