]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libcontrol/box.c
fix fuckup
[plan9front.git] / sys / src / libcontrol / box.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 Box Box;
10
11 struct Box
12 {
13         Control;
14         int             border;
15         CImage  *bordercolor;
16         CImage  *image;
17         int             align;
18 };
19
20 enum{
21         EAlign,
22         EBorder,
23         EBordercolor,
24         EFocus,
25         EHide,
26         EImage,
27         ERect,
28         EReveal,
29         EShow,
30         ESize,
31 };
32
33 static char *cmds[] = {
34         [EAlign] =              "align",
35         [EBorder] =     "border",
36         [EBordercolor] ="bordercolor",
37         [EFocus] =      "focus",
38         [EHide] =               "hide",
39         [EImage] =      "image",
40         [ERect] =               "rect",
41         [EReveal] =     "reveal",
42         [EShow] =               "show",
43         [ESize] =               "size",
44         nil
45 };
46
47 static void
48 boxkey(Control *c, Rune *rp)
49 {
50         Box *b;
51
52         b = (Box*)c;
53         chanprint(b->event, "%q: key 0x%x", b->name, rp[0]);
54 }
55
56 static void
57 boxmouse(Control *c, Mouse *m)
58 {
59         Box *b;
60
61         b = (Box*)c;
62         if (ptinrect(m->xy,b->rect))
63                 chanprint(b->event, "%q: mouse %P %d %ld", b->name,
64                         m->xy, m->buttons, m->msec);
65 }
66
67 static void
68 boxfree(Control *c)
69 {
70         _putctlimage(((Box*)c)->image);
71 }
72
73 static void
74 boxshow(Box *b)
75 {
76         Image *i;
77         Rectangle r;
78
79         if(b->hidden)
80                 return;
81         if(b->border > 0){
82                 border(b->screen, b->rect, b->border, b->bordercolor->image, ZP);
83                 r = insetrect(b->rect, b->border);
84         }else
85                 r = b->rect;
86         i = b->image->image;
87         /* BUG: ALIGNMENT AND CLIPPING */
88         draw(b->screen, r, i, nil, ZP);
89 }
90
91 static void
92 boxctl(Control *c, CParse *cp)
93 {
94         int cmd;
95         Rectangle r;
96         Box *b;
97
98         b = (Box*)c;
99         cmd = _ctllookup(cp->args[0], cmds, nelem(cmds));
100         switch(cmd){
101         default:
102                 ctlerror("%q: unrecognized message '%s'", b->name, cp->str);
103                 break;
104         case EAlign:
105                 _ctlargcount(b, cp, 2);
106                 b->align = _ctlalignment(cp->args[1]);
107                 break;
108         case EBorder:
109                 _ctlargcount(b, cp, 2);
110                 if(cp->iargs[1] < 0)
111                         ctlerror("%q: bad border: %c", b->name, cp->str);
112                 b->border = cp->iargs[1];
113                 break;
114         case EBordercolor:
115                 _ctlargcount(b, cp, 2);
116                 _setctlimage(b, &b->bordercolor, cp->args[1]);
117                 break;
118         case EFocus:
119                 _ctlargcount(b, cp, 2);
120                 chanprint(b->event, "%q: focus %s", b->name, cp->args[1]);
121                 break;
122         case EHide:
123                 _ctlargcount(b, cp, 1);
124                 b->hidden = 1;
125                 break;
126         case EImage:
127                 _ctlargcount(b, cp, 2);
128                 _setctlimage(b, &b->image, cp->args[1]);
129                 break;
130         case ERect:
131                 _ctlargcount(b, cp, 5);
132                 r.min.x = cp->iargs[1];
133                 r.min.y = cp->iargs[2];
134                 r.max.x = cp->iargs[3];
135                 r.max.y = cp->iargs[4];
136                 if(Dx(r)<0 || Dy(r)<0)
137                         ctlerror("%q: bad rectangle: %s", b->name, cp->str);
138                 b->rect = r;
139                 break;
140         case EReveal:
141                 _ctlargcount(b, cp, 1);
142                 b->hidden = 0;
143                 boxshow(b);
144                 break;
145         case EShow:
146                 _ctlargcount(b, cp, 1);
147                 boxshow(b);
148                 break;
149         case ESize:
150                 if (cp->nargs == 3)
151                         r.max = Pt(0x7fffffff, 0x7fffffff);
152                 else{
153                         _ctlargcount(b, cp, 5);
154                         r.max.x = cp->iargs[3];
155                         r.max.y = cp->iargs[4];
156                 }
157                 r.min.x = cp->iargs[1];
158                 r.min.y = cp->iargs[2];
159                 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)
160                         ctlerror("%q: bad sizes: %s", b->name, cp->str);
161                 b->size.min = r.min;
162                 b->size.max = r.max;
163                 break;
164         }
165 }
166
167 Control*
168 createbox(Controlset *cs, char *name)
169 {
170         Box *b;
171
172         b = (Box *)_createctl(cs, "box", sizeof(Box), name);
173         b->image = _getctlimage("white");
174         b->bordercolor = _getctlimage("black");
175         b->align = Aupperleft;
176         b->key = boxkey;
177         b->mouse = boxmouse;
178         b->ctl = boxctl;
179         b->exit = boxfree;
180         return (Control *)b;
181 }