123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- #include <u.h>
- #include <libc.h>
- #include <draw.h>
- #include <thread.h>
- #include <mouse.h>
- #include <keyboard.h>
- #include <control.h>
- typedef struct Radio Radio;
- struct Radio
- {
- Control;
- int value;
- int lastbut;
- Control **buttons;
- int nbuttons;
- char *eventstr;
- };
- enum{
- EAdd,
- EButton,
- EFocus,
- EFormat,
- EHide,
- ERect,
- EReveal,
- EShow,
- ESize,
- EValue,
- };
- static char *cmds[] = {
- [EAdd] = "add",
- [EButton] = "button",
- [EFocus] = "focus",
- [EFormat] = "format",
- [EHide] = "hide",
- [ERect] = "rect",
- [EReveal] = "reveal",
- [EShow] = "show",
- [ESize] = "size",
- [EValue] = "value",
- nil
- };
- static void radioshow(Radio*);
- static void radiofree(Radio*);
- static void
- radiomouse(Control *c, Mouse *m)
- {
- Radio *r;
- int i;
- r = (Radio*)c;
- for(i=0; i<r->nbuttons; i++)
- if(ptinrect(m->xy, r->buttons[i]->rect) && r->buttons[i]->mouse){
- (r->buttons[i]->mouse)(r->buttons[i], m);
- break;
- }
- }
- static void
- radiofree(Radio*)
- {
- }
- static void
- radioshow(Radio *r)
- {
- int i;
- if (r->hidden)
- return;
- for(i=0; i<r->nbuttons; i++){
- _ctlprint(r->buttons[i], "value %d", (r->value==i));
- _ctlprint(r->buttons[i], "show");
- }
- }
- static void
- radioctl(Control *c, CParse *cp)
- {
- int cmd, i;
- Rectangle rect;
- Radio *r;
- char fmt[256];
- r = (Radio*)c;
- cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
- switch(cmd){
- default:
- ctlerror("%q: unrecognized message '%s'", r->name, cp->str);
- break;
- case EAdd:
- _ctlargcount(r, cp, 2);
- c = controlcalled(cp->args[1]);
- if(c == nil)
- ctlerror("%q: can't add %s: %r", r->name, cp->args[1]);
- snprint(fmt, sizeof fmt, "%%q: %q button %%d", r->name);
- _ctlprint(c, "format %q", fmt);
- controlwire(c, "event", c->controlset->ctl);
- r->buttons = ctlrealloc(r->buttons, (r->nbuttons+1)*sizeof(Control*));
- r->buttons[r->nbuttons] = c;
- r->nbuttons++;
- r->value = -1;
- radioshow(r);
- break;
- case EButton:
- if (cp->sender == nil)
- ctlerror("%q: senderless buttonevent: %q", r->name, cp->str);
- c = controlcalled(cp->sender);
- for(i=0; i<r->nbuttons; i++)
- if (c == r->buttons[i])
- break;
- if (i == r->nbuttons)
- ctlerror("%q: not my event: %q", r->name, cp->str);
- if(cp->iargs[1] == 0){
- /* button was turned off; turn it back on */
- _ctlprint(c, "value 1");
- }else{
- r->value = i;
- chanprint(r->event, r->format, r->name, i);
- radioshow(r);
- }
- break;
- case EFormat:
- _ctlargcount(r, cp, 2);
- r->format = ctlstrdup(cp->args[1]);
- break;
- case EHide:
- _ctlargcount(r, cp, 1);
- r->hidden = 1;
- break;
- case EFocus:
- /* ignore focus change */
- break;
- case ERect:
- _ctlargcount(r, cp, 5);
- rect.min.x = cp->iargs[1];
- rect.min.y = cp->iargs[2];
- rect.max.x = cp->iargs[3];
- rect.max.y = cp->iargs[4];
- r->rect = rect;
- break;
- case EReveal:
- _ctlargcount(r, cp, 1);
- r->hidden = 0;
- radioshow(r);
- break;
- case EShow:
- _ctlargcount(r, cp, 1);
- radioshow(r);
- break;
- case ESize:
- if (cp->nargs == 3)
- rect.max = Pt(0x7fffffff, 0x7fffffff);
- else{
- _ctlargcount(r, cp, 5);
- rect.max.x = cp->iargs[3];
- rect.max.y = cp->iargs[4];
- }
- rect.min.x = cp->iargs[1];
- rect.min.y = cp->iargs[2];
- if(rect.min.x<=0 || rect.min.y<=0 || rect.max.x<=0 || rect.max.y<=0 || rect.max.x < rect.min.x || rect.max.y < rect.min.y)
- ctlerror("%q: bad sizes: %s", r->name, cp->str);
- r->size.min = rect.min;
- r->size.max = rect.max;
- break;
- case EValue:
- _ctlargcount(r, cp, 2);
- r->value = cp->iargs[1];
- radioshow(r);
- break;
- }
- }
- Control*
- createradiobutton(Controlset *cs, char *name)
- {
- Radio *r;
- r = (Radio*)_createctl(cs, "label", sizeof(Radio), name);
- r->format = ctlstrdup("%q: value %d");
- r->value = -1; /* nobody set at first */
- r->mouse = radiomouse;
- r->ctl = radioctl;
- return (Control*)r;
- }
|