1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <thread.h>
5 #include <mouse.h>
6 #include <keyboard.h>
7 #include <control.h>
8
9 typedef struct Box Box;
10
11 struct Box
12 {
13 Control;
14 int border;
15 CImage *bordercolor;
16 CImage *image;
17 int align;
18 };
19
20 enum{
21 EAlign,
22 EBorder,
23 EBordercolor,
24 EFocus,
25 EHide,
26 EImage,
27 ERect,
28 EReveal,
29 EShow,
30 ESize,
31 };
32
33 static char *cmds[] = {
34 [EAlign] = "align",
35 [EBorder] = "border",
36 [EBordercolor] ="bordercolor",
37 [EFocus] = "focus",
38 [EHide] = "hide",
39 [EImage] = "image",
40 [ERect] = "rect",
41 [EReveal] = "reveal",
42 [EShow] = "show",
43 [ESize] = "size",
44 nil
45 };
46
47 static void
boxkey(Control * c,Rune * rp)48 boxkey(Control *c, Rune *rp)
49 {
50 Box *b;
51
52 b = (Box*)c;
53 chanprint(b->event, "%q: key 0x%x", b->name, rp[0]);
54 }
55
56 static void
boxmouse(Control * c,Mouse * m)57 boxmouse(Control *c, Mouse *m)
58 {
59 Box *b;
60
61 b = (Box*)c;
62 if (ptinrect(m->xy,b->rect))
63 chanprint(b->event, "%q: mouse %P %d %ld", b->name,
64 m->xy, m->buttons, m->msec);
65 }
66
67 static void
boxfree(Control * c)68 boxfree(Control *c)
69 {
70 _putctlimage(((Box*)c)->image);
71 }
72
73 static void
boxshow(Box * b)74 boxshow(Box *b)
75 {
76 Image *i;
77 Rectangle r;
78
79 if(b->hidden)
80 return;
81 if(b->border > 0){
82 border(b->screen, b->rect, b->border, b->bordercolor->image, ZP);
83 r = insetrect(b->rect, b->border);
84 }else
85 r = b->rect;
86 i = b->image->image;
87 /* BUG: ALIGNMENT AND CLIPPING */
88 draw(b->screen, r, i, nil, ZP);
89 }
90
91 static void
boxctl(Control * c,CParse * cp)92 boxctl(Control *c, CParse *cp)
93 {
94 int cmd;
95 Rectangle r;
96 Box *b;
97
98 b = (Box*)c;
99 cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
100 switch(cmd){
101 default:
102 ctlerror("%q: unrecognized message '%s'", b->name, cp->str);
103 break;
104 case EAlign:
105 _ctlargcount(b, cp, 2);
106 b->align = _ctlalignment(cp->args[1]);
107 break;
108 case EBorder:
109 _ctlargcount(b, cp, 2);
110 if(cp->iargs[1] < 0)
111 ctlerror("%q: bad border: %c", b->name, cp->str);
112 b->border = cp->iargs[1];
113 break;
114 case EBordercolor:
115 _ctlargcount(b, cp, 2);
116 _setctlimage(b, &b->bordercolor, cp->args[1]);
117 break;
118 case EFocus:
119 _ctlargcount(b, cp, 2);
120 chanprint(b->event, "%q: focus %s", b->name, cp->args[1]);
121 break;
122 case EHide:
123 _ctlargcount(b, cp, 1);
124 b->hidden = 1;
125 break;
126 case EImage:
127 _ctlargcount(b, cp, 2);
128 _setctlimage(b, &b->image, cp->args[1]);
129 break;
130 case ERect:
131 _ctlargcount(b, cp, 5);
132 r.min.x = cp->iargs[1];
133 r.min.y = cp->iargs[2];
134 r.max.x = cp->iargs[3];
135 r.max.y = cp->iargs[4];
136 if(Dx(r)<0 || Dy(r)<0)
137 ctlerror("%q: bad rectangle: %s", b->name, cp->str);
138 b->rect = r;
139 break;
140 case EReveal:
141 _ctlargcount(b, cp, 1);
142 b->hidden = 0;
143 boxshow(b);
144 break;
145 case EShow:
146 _ctlargcount(b, cp, 1);
147 boxshow(b);
148 break;
149 case ESize:
150 if (cp->nargs == 3)
151 r.max = Pt(0x7fffffff, 0x7fffffff);
152 else{
153 _ctlargcount(b, cp, 5);
154 r.max.x = cp->iargs[3];
155 r.max.y = cp->iargs[4];
156 }
157 r.min.x = cp->iargs[1];
158 r.min.y = cp->iargs[2];
159 if(r.min.x<=0 || r.min.y<=0 || r.max.x<=0 || r.max.y<=0 || r.max.x < r.min.x || r.max.y < r.min.y)
160 ctlerror("%q: bad sizes: %s", b->name, cp->str);
161 b->size.min = r.min;
162 b->size.max = r.max;
163 break;
164 }
165 }
166
167 Control*
createbox(Controlset * cs,char * name)168 createbox(Controlset *cs, char *name)
169 {
170 Box *b;
171
172 b = (Box *)_createctl(cs, "box", sizeof(Box), name);
173 b->image = _getctlimage("white");
174 b->bordercolor = _getctlimage("black");
175 b->align = Aupperleft;
176 b->key = boxkey;
177 b->mouse = boxmouse;
178 b->ctl = boxctl;
179 b->exit = boxfree;
180 return (Control *)b;
181 }
182