]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libcontrol/radiobutton.c
qer(8): correct man page example (thanks, kenji)
[plan9front.git] / sys / src / libcontrol / radiobutton.c
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
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
66 radiofree(Radio*)
67 {
68 }
69
70 static void
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
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*
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 }