9 typedef struct Menu0 Menu0; /* Menu is taken by mouse.h */
18 CImage *selecttextcolor;
25 int visible; /* state of menu */
26 int selection; /* currently selected line; -1 == none */
27 int prevsel; /* previous selection */
28 int lastbut; /* previous state of mouse button */
51 static char *cmds[] = {
55 [EBordercolor] = "bordercolor",
63 [ESelectcolor] = "selectcolor",
64 [ESelecttextcolor] = "selecttextcolor",
67 [ETextcolor] = "textcolor",
72 static void menushow(Menu0*);
73 static void menuhide(Menu0*);
82 _putctlimage(m->image);
83 _putctlimage(m->textcolor);
84 _putctlimage(m->bordercolor);
85 _putctlimage(m->selectcolor);
86 _putctlimage(m->selecttextcolor);
98 if(m->hidden || m->window == nil)
103 draw(m->window, m->rect, m->image->image, nil, m->image->image->r.min);
105 border(m->window, m->rect, m->border, m->bordercolor->image, ZP);
108 for(i=0; i<m->nline; i++){
109 w = stringwidth(f, m->line[i]);
113 dy = m->nline*f->height;
114 clipr = insetrect(m->rect, m->border);
115 p = _ctlalignpoint(clipr, dx, dy, m->align);
116 im = m->textcolor->image;
118 // im = m->pressedtextcolor->image;
119 for(i=0; i<m->nline; i++){
122 r.max.y = p.y+f->height;
124 if(i == m->selection){
125 draw(m->window, r, m->selectcolor->image, nil, ZP);
126 c = m->selecttextcolor->image;
128 q = _ctlalignpoint(r, stringwidth(f, m->line[i]), f->height, m->align%3);
129 _string(m->window, q, c,
130 ZP, f, m->line[i], nil, strlen(m->line[i]),
131 clipr, nil, ZP, SoverD);
135 // draw(m->screen, m->rect, m->lighm->image, m->mask->image, m->mask->image->r.min);
136 flushimage(display, 1);
150 for(i=0; i<m->nline; i++){
151 p = stringsize(f, m->line[i]);
157 return Pt(x+2*m->border, y+2*m->border);
163 freeimage(m->window);
165 m->rect.max.y = m->rect.min.y; /* go to zero size */
168 if(m->selection >= 0)
169 m->prevsel = m->selection;
175 menutrack(Control *c, Mouse *ms)
184 if(m->lastbut && ms->buttons==0){ /* menu was released */
185 chanprint(m->event, "%q: value %d", m->name, m->selection);
189 m->lastbut = ms->buttons;
190 r = insetrect(m->rect, m->border);
191 if(!ptinrect(ms->xy, r))
194 s = (ms->xy.y - r.min.y)/m->font->font->height;
195 if(s < 0 || s >= m->nline)
198 if(m->visible== 0 || s!=m->selection){
205 menuctl(Control *c, CParse *cp)
213 cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
216 ctlerror("%q: unrecognized message '%s'", m->name, cp->str);
219 _ctlargcount(m, cp, 2);
220 m->line = ctlrealloc(m->line, (m->nline+1)*sizeof(char*));
221 m->line[m->nline++] = ctlstrdup(cp->args[1]);
225 _ctlargcount(m, cp, 2);
226 m->align = _ctlalignment(cp->args[1]);
230 _ctlargcount(m, cp, 2);
231 m->border = cp->iargs[1];
235 _ctlargcount(m, cp, 2);
236 _setctlimage(m, &m->bordercolor, cp->args[1]);
240 _ctlargcount(m, cp, 2);
241 if(atoi(cp->args[1]) == 0)
245 _ctlargcount(m, cp, 2);
246 _setctlfont(m, &m->font, cp->args[1]);
249 _ctlargcount(m, cp, 2);
250 m->format = ctlstrdup(cp->args[1]);
253 _ctlargcount(m, cp, 1);
257 _ctlargcount(m, cp, 2);
258 _setctlimage(m, &m->image, cp->args[1]);
262 _ctlargcount(m, cp, 5);
263 r.min.x = cp->iargs[1];
264 r.min.y = cp->iargs[2];
265 r.max.x = cp->iargs[3];
266 r.max.y = cp->iargs[4];
267 if(Dx(r)<0 || Dy(r)<0)
268 ctlerror("%q: bad rectangle: %s", m->name, cp->str);
273 _ctlargcount(m, cp, 1);
278 _ctlargcount(m, cp, 2);
279 _setctlimage(m, &m->selectcolor, cp->args[1]);
282 case ESelecttextcolor:
283 _ctlargcount(m, cp, 2);
284 _setctlimage(m, &m->selecttextcolor, cp->args[1]);
288 _ctlargcount(m, cp, 1);
293 r.max = Pt(0x7fffffff, 0x7fffffff);
295 _ctlargcount(m, cp, 5);
296 r.max.x = cp->iargs[3];
297 r.max.y = cp->iargs[4];
299 r.min.x = cp->iargs[1];
300 r.min.y = cp->iargs[2];
301 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)
302 ctlerror("%q: bad sizes: %s", m->name, cp->str);
307 _ctlargcount(m, cp, 2);
308 _setctlimage(m, &m->textcolor, cp->args[1]);
312 /* no args == toggle; otherwise 0 or 1 for state of window */
316 up = (m->window == nil);
317 if(!up){ /* take window down */
325 m->rect.max.x = m->rect.min.x + diag.x;
326 m->rect.max.y = m->rect.min.y + diag.y;
327 m->window = allocwindow(_screen, m->rect, Refbackup, DWhite);
329 m->window = m->screen;
331 if(up<0 || up>=m->nline)
335 h = m->font->font->height;
336 moveto(m->controlset->mousectl,
337 Pt(m->rect.min.x+Dx(m->rect)/2, m->rect.min.y+up*h+h/2));
344 createmenu(Controlset *cs, char *name)
348 m = (Menu0*)_createctl(cs, "menu", sizeof(Menu0), name);
349 m->font = _getctlfont("font");
350 m->image = _getctlimage("white");
351 m->textcolor = _getctlimage("black");
352 m->selectcolor = _getctlimage("yellow");
353 m->selecttextcolor = _getctlimage("black");
354 m->bordercolor = _getctlimage("black");
355 m->format = ctlstrdup("%q: value %d");
357 m->align = Aupperleft;
362 m->mouse = menutrack;