]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libcontrol/textbutton3.c
fix fuckup
[plan9front.git] / sys / src / libcontrol / textbutton3.c
1 /* use button 3 for a proper function to the application, that is not for plumber
2  *  as default control(2) supposes.
3  *  codes are mostly from /sys/src/libcontrol/textbutton.c
4  */
5 #include <u.h>
6 #include <libc.h>
7 #include <draw.h>
8 #include <thread.h>
9 #include <mouse.h>
10 #include <keyboard.h>
11 #include <control.h>
12
13 typedef struct Textbutton3 Textbutton3;
14
15 struct Textbutton3
16 {
17         Control;
18         CFont   *font;
19         CImage  *image;
20         CImage  *mask;
21         CImage  *light;
22         CImage  *bordercolor;
23         CImage  *textcolor;
24         CImage  *pressedtextcolor;
25         int             pressed;
26         int             lastbut;
27         int             lastshow;
28         char            **line;
29         int             nline;
30         int             align;
31         int             border;
32         int             left;
33         int             middle;
34         int             right;
35         int             toggle;
36         int             gettextflg;
37 };
38
39 enum{
40         EAlign,
41         EBorder,
42         EBordercolor,
43         EFocus,
44         EFont,
45         EFormat,
46         EHide,
47         EImage,
48         ELight,
49         EMask,
50         EPressedtextcolor,
51         ERect,
52         EReveal,
53         EShow,
54         ESize,
55         EText,
56         ETextcolor,
57         EEnable,
58         EDisable,
59         EToggle,
60         EGettext,
61         EValue,
62 };
63
64 static char *cmds[] = {
65         [EAlign] =                      "align",
66         [EBorder] =             "border",
67         [EBordercolor] =        "bordercolor",
68         [EFocus] =              "focus",
69         [EFont] =                       "font",
70         [EFormat] =             "format",
71         [EHide] =                       "hide",
72         [EImage] =              "image",
73         [ELight] =                      "light",
74         [EMask] =                       "mask",
75         [EPressedtextcolor] ="pressedtextcolor",
76         [ERect] =                       "rect",
77         [EReveal] =             "reveal",
78         [EShow] =                       "show",
79         [ESize] =                       "size",
80         [EText] =                       "text",
81         [ETextcolor] =          "textcolor",
82         [EEnable] =             "enable",
83         [EDisable] =            "disable",
84         [EToggle] =             "toggle",
85         [EGettext] =            "gettext",
86         [EValue] =                      "value",
87         nil
88 };
89
90 static void     textbutton3show(Textbutton3 *);
91
92 static void
93 textbutton3mouse(Control *c, Mouse *m)
94 {
95         Textbutton3 *t;
96
97         t = (Textbutton3 *)c;
98         if(t->left == 1) {
99                 if((m->buttons&1) == 1 && (t->lastbut&1) == 0){
100                         t->pressed ^= 1;
101                         textbutton3show(t);
102                         t->lastbut = m->buttons & 1;
103                 }else if((m->buttons&1) == 0 && (t->lastbut&1) == 1){
104                         if(t->gettextflg == 0)
105                                 chanprint(t->event, t->format, t->name, t->pressed, m->xy.x, m->xy.y);
106                         else
107                                 chanprint(t->event, "%q: value %q", t->name, t->line[0]);
108                         t->pressed ^= 1;
109                         textbutton3show(t);
110                         t->lastbut = m->buttons & 1;
111                 }
112         }
113         if(t->middle == 1) {
114                 if((m->buttons&2) == 2 && (t->lastbut&2) == 0){
115                         t->pressed ^= 2;
116                         textbutton3show(t);
117                         t->lastbut = m->buttons & 2;
118                 }else if((m->buttons&2) == 0 && (t->lastbut&2) == 2){
119                         if(t->gettextflg == 0)
120                                 chanprint(t->event, t->format, t->name, t->pressed, m->xy.x, m->xy.y);
121                         else
122                                 chanprint(t->event, "%q: value %q", t->name, t->line[0]);
123                         t->pressed ^= 2;
124                         textbutton3show(t);
125                         t->lastbut = m->buttons & 2;
126                 }
127         }
128         if(t->right == 1) {
129                 if((m->buttons&4) == 4 && (t->lastbut&4) == 0){
130                         t->pressed ^= 4;
131                         textbutton3show(t);
132                         t->lastbut = m->buttons & 4;
133                 }else if((m->buttons&4) == 0 && (t->lastbut&4) == 4){
134                         if(t->gettextflg == 0)
135                                 chanprint(t->event, t->format, t->name, t->pressed, m->xy.x, m->xy.y);
136                         else
137                                 chanprint(t->event, "%q: value %q", t->name, t->line[0]);
138                         t->pressed ^= 4;
139                         textbutton3show(t);
140                         t->lastbut = m->buttons & 4;
141                 }
142         }
143 }
144
145 static void
146 textbutton3free(Control *c)
147 {
148         int i;
149         Textbutton3 *t;
150
151         t = (Textbutton3*)c;
152         _putctlfont(t->font);
153         _putctlimage(t->image);
154         _putctlimage(t->light);
155         _putctlimage(t->mask);
156         _putctlimage(t->textcolor);
157         _putctlimage(t->bordercolor);
158         _putctlimage(t->pressedtextcolor);
159         for(i=0; i<t->nline; i++)
160                 free(t->line[i]);
161         free(t->line);
162 }
163
164 static void
165 textbutton3show(Textbutton3 *t)
166 {
167         Rectangle r, clipr;
168         int i, dx, dy, w;
169         Font *f;
170         Point p, q;
171         Image *im;
172
173         if(t->hidden || t->lastshow == t->pressed)
174                 return;
175         f = t->font->font;
176         draw(t->screen, t->rect, t->image->image, nil, t->image->image->r.min);
177         if(t->pressed || t->toggle)
178                 draw(t->screen, t->rect, t->light->image, t->mask->image, t->mask->image->r.min);
179         if(t->border > 0)
180                 border(t->screen, t->rect, t->border, t->bordercolor->image, ZP);
181         /* text goes here */
182         dx = 0;
183         for(i=0; i<t->nline; i++){
184                 w = stringwidth(f, t->line[i]);         /*****/
185                 if(dx < w)
186                         dx = w;
187         }
188         dy = t->nline*f->height;
189         clipr = insetrect(t->rect, t->border);
190         p = _ctlalignpoint(clipr, dx, dy, t->align);
191         im = t->textcolor->image;
192         if(t->pressed)
193                 im = t->pressedtextcolor->image;
194         for(i=0; i<t->nline; i++){
195                 r.min = p;
196                 r.max.x = p.x+dx;
197                 r.max.y = p.y+f->height;
198                 q = _ctlalignpoint(r, stringwidth(f, t->line[i]), f->height, t->align%3);
199                 _string(t->screen, q, im,
200                         ZP, f, t->line[i], nil, strlen(t->line[i]),
201                         clipr, nil, ZP, SoverD);
202                 p.y += f->height;
203         }
204         t->lastshow = t->pressed;
205         flushimage(display, 1);
206 }
207
208 static void
209 textbutton3ctl(Control *c, CParse *cp)
210 {
211         int cmd, i;
212         Rectangle r;
213         Textbutton3 *t;
214
215         t = (Textbutton3*)c;
216         cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
217         switch(cmd){
218         default:
219                 ctlerror("%q: unrecognized message '%s'", t->name, cp->str);
220                 break;
221         case EAlign:
222                 _ctlargcount(t, cp, 2);
223                 t->align = _ctlalignment(cp->args[1]);
224                 t->lastshow = -1;       /* force redraw */
225                 break;
226         case EBorder:
227                 _ctlargcount(t, cp, 2);
228                 t->border = cp->iargs[1];
229                 t->lastshow = -1;       /* force redraw */
230                 break;
231         case EBordercolor:
232                 _ctlargcount(t, cp, 2);
233                 _setctlimage(t, &t->bordercolor, cp->args[1]);
234                 t->lastshow = -1;       /* force redraw */
235                 break;
236         case EFocus:
237                 break;
238         case EFont:
239                 _ctlargcount(t, cp, 2);
240                 _setctlfont(t, &t->font, cp->args[1]);
241                 t->lastshow = -1;       /* force redraw */
242                 break;
243         case EFormat:
244                 _ctlargcount(t, cp, 2);
245                 t->format = ctlstrdup(cp->args[1]);
246                 break;
247         case EHide:
248                 _ctlargcount(t, cp, 1);
249                 t->hidden = 1;
250                 break;
251         case EImage:
252                 _ctlargcount(t, cp, 2);
253                 _setctlimage(t, &t->image, cp->args[1]);
254                 t->lastshow = -1;       /* force redraw */
255                 break;
256         case ELight:
257                 _ctlargcount(t, cp, 2);
258                 _setctlimage(t, &t->light, cp->args[1]);
259                 t->lastshow = -1;       /* force redraw */
260                 break;
261         case EMask:
262                 _ctlargcount(t, cp, 2);
263                 _setctlimage(t, &t->mask, cp->args[1]);
264                 t->lastshow = -1;       /* force redraw */
265                 break;
266         case EPressedtextcolor:
267                 _ctlargcount(t, cp, 2);
268                 _setctlimage(t, &t->pressedtextcolor, cp->args[1]);
269                 t->lastshow = -1;       /* force redraw */
270                 break;
271         case ERect:
272                 _ctlargcount(t, cp, 5);
273                 r.min.x = cp->iargs[1];
274                 r.min.y = cp->iargs[2];
275                 r.max.x = cp->iargs[3];
276                 r.max.y = cp->iargs[4];
277                 if(Dx(r)<=0 || Dy(r)<=0)
278                         ctlerror("%q: bad rectangle: %s", t->name, cp->str);
279                 t->rect = r;
280                 t->lastshow = -1;       /* force redraw */
281                 break;
282         case EReveal:
283                 _ctlargcount(t, cp, 1);
284                 t->hidden = 0;
285                 t->lastshow = -1;       /* force redraw */
286                 textbutton3show(t);
287                 break;
288         case EShow:
289                 _ctlargcount(t, cp, 1);
290                 t->lastshow = -1;       /* force redraw */
291                 textbutton3show(t);
292                 break;
293         case ESize:
294                 if (cp->nargs == 3)
295                         r.max = Pt(0x7fffffff, 0x7fffffff);
296                 else{
297                         _ctlargcount(t, cp, 5);
298                         r.max.x = cp->iargs[3];
299                         r.max.y = cp->iargs[4];
300                 }
301                 r.min.x = cp->iargs[1];
302                 r.min.y = cp->iargs[2];
303                 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)
304                         ctlerror("%q: bad sizes: %s", t->name, cp->str);
305                 t->size.min = r.min;
306                 t->size.max = r.max;
307                 break;
308         case EText:
309                 /* free existing text */
310                 for(i=0; i<t->nline; i++)
311                         free(t->line[i]);
312                 t->nline = cp->nargs-1;
313                 t->line = ctlrealloc(t->line, t->nline*sizeof(char*));
314                 for(i=0; i<t->nline; i++)
315                         t->line[i] = ctlstrdup(cp->args[i+1]);
316                 t->lastshow = -1;       /* force redraw */
317                 textbutton3show(t);
318                 break;
319         case ETextcolor:
320                 _ctlargcount(t, cp, 2);
321                 _setctlimage(t, &t->textcolor, cp->args[1]);
322                 t->lastshow = -1;       /* force redraw */
323                 break;
324         case EEnable:
325                 _ctlargcount(t, cp, 2);
326                 if(strcmp(cp->args[1], "left") == 0)
327                                 t->left = 1;
328                 else if(strcmp(cp->args[1], "middle") == 0)
329                                 t->middle = 1;
330                 else if(strcmp(cp->args[1], "right") == 0)
331                                 t->right = 1;
332                 break;
333         case EDisable:
334                 _ctlargcount(t, cp, 2);
335                 if(strcmp(cp->args[1], "left") == 0)
336                         t->left = 0;
337                 else if(strcmp(cp->args[1], "middle") == 0)
338                         t->middle = 0;
339                 else if(strcmp(cp->args[1], "right") == 0)
340                         t->right = 0;
341                 break;
342         case EToggle:
343                 _ctlargcount(t, cp, 2);
344                 if(strcmp(cp->args[1], "on") == 0)
345                         t->toggle = 1;
346                 else if(strcmp(cp->args[1], "off") == 0)
347                         t->toggle = 0;
348                 t->lastshow = -1;       /* force redraw */
349                 break;
350         case EGettext:
351                 _ctlargcount(t, cp, 2);
352                 if(strcmp(cp->args[1], "on") == 0)
353                         t->gettextflg = 1;
354                 else if(strcmp(cp->args[1], "off") == 0)
355                         t->gettextflg = 0;
356                 break;
357         case EValue:
358                 _ctlargcount(t, cp, 2);
359                 if((cp->iargs[1]!=0) != t->pressed){
360                         t->pressed ^= 1;
361                         textbutton3show(t);
362                 }
363                 break;
364         }
365 }
366
367 Control*
368 createtextbutton3(Controlset *cs, char *name)
369 {
370         Textbutton3 *t;
371
372         t = (Textbutton3 *)_createctl(cs, "textbutton3", sizeof(Textbutton3), name);
373         t->line = ctlmalloc(sizeof(char*));
374         t->nline = 0;
375         t->image = _getctlimage("white");
376         t->light = _getctlimage("yellow");
377         t->mask = _getctlimage("opaque");
378         t->bordercolor = _getctlimage("black");
379         t->textcolor = _getctlimage("black");
380         t->pressedtextcolor = _getctlimage("black");
381         t->font = _getctlfont("font");
382         t->format = ctlstrdup("%q: value %d %d %d");
383         t->lastshow = -1;
384         t->mouse = textbutton3mouse;
385         t->ctl = textbutton3ctl;
386         t->exit = textbutton3free;
387         t->left = 1;
388         t->middle = 1;
389         t->right = 1;
390         t->toggle = 0;
391         t->gettextflg = 0;
392         return (Control *)t;
393 }