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 Radio Radio;
10
11 struct Radio
12 {
13 Control;
14 int value;
15 int lastbut;
16 Control **buttons;
17 int nbuttons;
18 char *eventstr;
19 };
20
21 enum{
22 EAdd,
23 EButton,
24 EFocus,
25 EFormat,
26 EHide,
27 ERect,
28 EReveal,
29 EShow,
30 ESize,
31 EValue,
32 };
33
34 static char *cmds[] = {
35 [EAdd] = "add",
36 [EButton] = "button",
37 [EFocus] = "focus",
38 [EFormat] = "format",
39 [EHide] = "hide",
40 [ERect] = "rect",
41 [EReveal] = "reveal",
42 [EShow] = "show",
43 [ESize] = "size",
44 [EValue] = "value",
45 nil
46 };
47
48 static void radioshow(Radio*);
49 static void radiofree(Radio*);
50
51 static void
radiomouse(Control * c,Mouse * m)52 radiomouse(Control *c, Mouse *m)
53 {
54 Radio *r;
55 int i;
56
57 r = (Radio*)c;
58 for(i=0; i<r->nbuttons; i++)
59 if(ptinrect(m->xy, r->buttons[i]->rect) && r->buttons[i]->mouse){
60 (r->buttons[i]->mouse)(r->buttons[i], m);
61 break;
62 }
63 }
64
65 static void
radiofree(Radio *)66 radiofree(Radio*)
67 {
68 }
69
70 static void
radioshow(Radio * r)71 radioshow(Radio *r)
72 {
73 int i;
74
75 if (r->hidden)
76 return;
77 for(i=0; i<r->nbuttons; i++){
78 _ctlprint(r->buttons[i], "value %d", (r->value==i));
79 _ctlprint(r->buttons[i], "show");
80 }
81 }
82
83 static void
radioctl(Control * c,CParse * cp)84 radioctl(Control *c, CParse *cp)
85 {
86 int cmd, i;
87 Rectangle rect;
88 Radio *r;
89 char fmt[256];
90
91 r = (Radio*)c;
92
93 cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
94 switch(cmd){
95 default:
96 ctlerror("%q: unrecognized message '%s'", r->name, cp->str);
97 break;
98 case EAdd:
99 _ctlargcount(r, cp, 2);
100 c = controlcalled(cp->args[1]);
101 if(c == nil)
102 ctlerror("%q: can't add %s: %r", r->name, cp->args[1]);
103 snprint(fmt, sizeof fmt, "%%q: %q button %%d", r->name);
104 _ctlprint(c, "format %q", fmt);
105 controlwire(c, "event", c->controlset->ctl);
106 r->buttons = ctlrealloc(r->buttons, (r->nbuttons+1)*sizeof(Control*));
107 r->buttons[r->nbuttons] = c;
108 r->nbuttons++;
109 r->value = -1;
110 radioshow(r);
111 break;
112 case EButton:
113 if (cp->sender == nil)
114 ctlerror("%q: senderless buttonevent: %q", r->name, cp->str);
115 c = controlcalled(cp->sender);
116 for(i=0; i<r->nbuttons; i++)
117 if (c == r->buttons[i])
118 break;
119 if (i == r->nbuttons)
120 ctlerror("%q: not my event: %q", r->name, cp->str);
121 if(cp->iargs[1] == 0){
122 /* button was turned off; turn it back on */
123 _ctlprint(c, "value 1");
124 }else{
125 r->value = i;
126 chanprint(r->event, r->format, r->name, i);
127 radioshow(r);
128 }
129 break;
130 case EFormat:
131 _ctlargcount(r, cp, 2);
132 r->format = ctlstrdup(cp->args[1]);
133 break;
134 case EHide:
135 _ctlargcount(r, cp, 1);
136 r->hidden = 1;
137 break;
138 case EFocus:
139 /* ignore focus change */
140 break;
141 case ERect:
142 _ctlargcount(r, cp, 5);
143 rect.min.x = cp->iargs[1];
144 rect.min.y = cp->iargs[2];
145 rect.max.x = cp->iargs[3];
146 rect.max.y = cp->iargs[4];
147 r->rect = rect;
148 break;
149 case EReveal:
150 _ctlargcount(r, cp, 1);
151 r->hidden = 0;
152 radioshow(r);
153 break;
154 case EShow:
155 _ctlargcount(r, cp, 1);
156 radioshow(r);
157 break;
158 case ESize:
159 if (cp->nargs == 3)
160 rect.max = Pt(0x7fffffff, 0x7fffffff);
161 else{
162 _ctlargcount(r, cp, 5);
163 rect.max.x = cp->iargs[3];
164 rect.max.y = cp->iargs[4];
165 }
166 rect.min.x = cp->iargs[1];
167 rect.min.y = cp->iargs[2];
168 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)
169 ctlerror("%q: bad sizes: %s", r->name, cp->str);
170 r->size.min = rect.min;
171 r->size.max = rect.max;
172 break;
173 case EValue:
174 _ctlargcount(r, cp, 2);
175 r->value = cp->iargs[1];
176 radioshow(r);
177 break;
178 }
179 }
180
181 Control*
createradiobutton(Controlset * cs,char * name)182 createradiobutton(Controlset *cs, char *name)
183 {
184 Radio *r;
185
186 r = (Radio*)_createctl(cs, "label", sizeof(Radio), name);
187 r->format = ctlstrdup("%q: value %d");
188 r->value = -1; /* nobody set at first */
189 r->mouse = radiomouse;
190 r->ctl = radioctl;
191 return (Control*)r;
192 }
193