]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/abaco/rows.c
abacos tcs.h is automatically generated
[plan9front.git] / sys / src / cmd / abaco / rows.c
1 #include <u.h>
2 #include <libc.h>
3 #include <draw.h>
4 #include <memdraw.h>
5 #include <thread.h>
6 #include <cursor.h>
7 #include <mouse.h>
8 #include <keyboard.h>
9 #include <frame.h>
10 #include <plumb.h>
11 #include <html.h>
12 #include "dat.h"
13 #include "fns.h"
14
15 void
16 rowinit(Row *row, Rectangle r)
17 {
18         Rectangle r1;
19         Text *t;
20
21         draw(screen, r, display->white, nil, ZP);
22         row->r = r;
23         row->col = nil;
24         row->ncol = 0;
25         r1 = r;
26         r1.max.y = r1.min.y + font->height;
27         t = &row->tag;
28         textinit(t, screen, r1, font, tagcols);
29         t->what = Rowtag;
30         t->row = row;
31         t->w = nil;
32         t->col = nil;
33         r1.min.y = r1.max.y;
34         r1.max.y += Border;
35         draw(screen, r1, display->black, nil, ZP);
36         textinsert(t, 0, L"Newcol Google Exit ", 19);
37         textsetselect(t, t->rs.nr, t->rs.nr);
38 }
39
40 Column*
41 rowadd(Row *row, Column *c, int x)
42 {
43         Rectangle r, r1;
44         Column *d;
45         int i;
46
47         d = nil;
48         r = row->r;
49         r.min.y = row->tag.r.max.y+Border;
50         if(x<r.min.x && row->ncol>0){   /*steal 40% of last column by default */
51                 d = row->col[row->ncol-1];
52                 x = d->r.min.x + 3*Dx(d->r)/5;
53         }
54         /* look for column we'll land on */
55         for(i=0; i<row->ncol; i++){
56                 d = row->col[i];
57                 if(x < d->r.max.x)
58                         break;
59         }
60         if(row->ncol > 0){
61                 if(i < row->ncol)
62                         i++;    /* new column will go after d */
63                 r = d->r;
64                 if(Dx(r) < 100)
65                         return nil;
66                 draw(screen, r, display->white, nil, ZP);
67                 r1 = r;
68                 r1.max.x = min(x, r.max.x-50);
69                 if(Dx(r1) < 50)
70                         r1.max.x = r1.min.x+50;
71                 colresize(d, r1);
72                 r1.min.x = r1.max.x;
73                 r1.max.x = r1.min.x+Border;
74                 draw(screen, r1, display->black, nil, ZP);
75                 r.min.x = r1.max.x;
76         }
77         if(c == nil){
78                 c = emalloc(sizeof(Column));
79                 colinit(c, r);
80         }else
81                 colresize(c, r);
82         c->row = row;
83         c->tag.row = row;
84         row->col = realloc(row->col, (row->ncol+1)*sizeof(Column*));
85         memmove(row->col+i+1, row->col+i, (row->ncol-i)*sizeof(Column*));
86         row->col[i] = c;
87         row->ncol++;
88         clearmouse();
89         return c;
90 }
91
92 void
93 rowresize(Row *row, Rectangle r)
94 {
95         int i, dx, odx;
96         Rectangle r1, r2;
97         Column *c;
98
99         dx = Dx(r);
100         odx = Dx(row->r);
101         row->r = r;
102         r1 = r;
103         r1.max.y = r1.min.y + font->height;
104         textresize(&row->tag, screen, r1);
105         r1.min.y = r1.max.y;
106         r1.max.y += Border;
107         draw(screen, r1, display->black, nil, ZP);
108         r.min.y = r1.max.y;
109         r1 = r;
110         r1.max.x = r1.min.x;
111         for(i=0; i<row->ncol; i++){
112                 c = row->col[i];
113                 r1.min.x = r1.max.x;
114                 if(i == row->ncol-1)
115                         r1.max.x = r.max.x;
116                 else
117                         r1.max.x = r1.min.x+Dx(c->r)*dx/odx;
118                 if(i > 0){
119                         r2 = r1;
120                         r2.max.x = r2.min.x+Border;
121                         draw(screen, r2, display->black, nil, ZP);
122                         r1.min.x = r2.max.x;
123                 }
124                 colresize(c, r1);
125         }
126 }
127
128 void
129 rowdragcol(Row *row, Column *c, int)
130 {
131         Rectangle r;
132         int i, b, x;
133         Point p, op;
134         Column *d;
135
136         clearmouse();
137         setcursor(mousectl, &boxcursor);
138         b = mouse->buttons;
139         op = mouse->xy;
140         while(mouse->buttons == b)
141                 readmouse(mousectl);
142         setcursor(mousectl, nil);
143         if(mouse->buttons){
144                 while(mouse->buttons)
145                         readmouse(mousectl);
146                 return;
147         }
148
149         for(i=0; i<row->ncol; i++)
150                 if(row->col[i] == c)
151                         goto Found;
152         error("can't find column");
153
154   Found:
155         if(i == 0)
156                 return;
157         p = mouse->xy;
158         if((abs(p.x-op.x)<5 && abs(p.y-op.y)<5))
159                 return;
160         if((i>0 && p.x<row->col[i-1]->r.min.x) || (i<row->ncol-1 && p.x>c->r.max.x)){
161                 /* shuffle */
162                 x = c->r.min.x;
163                 rowclose(row, c, FALSE);
164                 if(rowadd(row, c, p.x) == nil)  /* whoops! */
165                 if(rowadd(row, c, x) == nil)            /* WHOOPS! */
166                 if(rowadd(row, c, -1)==nil){            /* shit! */
167                         rowclose(row, c, TRUE);
168                         return;
169                 }
170                 colmousebut(c);
171                 return;
172         }
173         d = row->col[i-1];
174         if(p.x < d->r.min.x+80+Scrollsize)
175                 p.x = d->r.min.x+80+Scrollsize;
176         if(p.x > c->r.max.x-80-Scrollsize)
177                 p.x = c->r.max.x-80-Scrollsize;
178         r = d->r;
179         r.max.x = c->r.max.x;
180         draw(screen, r, display->white, nil, ZP);
181         r.max.x = p.x;
182         colresize(d, r);
183         r = c->r;
184         r.min.x = p.x;
185         r.max.x = r.min.x;
186         r.max.x += Border;
187         draw(screen, r, display->black, nil, ZP);
188         r.min.x = r.max.x;
189         r.max.x = c->r.max.x;
190         colresize(c, r);
191         colmousebut(c);
192 }
193
194 void
195 rowclose(Row *row, Column *c, int dofree)
196 {
197         Rectangle r;
198         int i;
199
200         for(i=0; i<row->ncol; i++)
201                 if(row->col[i] == c)
202                         goto Found;
203         error("can't find column");
204   Found:
205         r = c->r;
206         if(dofree)
207                 colcloseall(c);
208         memmove(row->col+i, row->col+i+1, (row->ncol-i)*sizeof(Column*));
209         row->ncol--;
210         row->col = realloc(row->col, row->ncol*sizeof(Column*));
211         if(row->ncol == 0){
212                 draw(screen, r, display->white, nil, ZP);
213                 return;
214         }
215         if(i == row->ncol){             /* extend last column right */
216                 c = row->col[i-1];
217                 r.min.x = c->r.min.x;
218                 r.max.x = row->r.max.x;
219         }else{                  /* extend next window left */
220                 c = row->col[i];
221                 r.max.x = c->r.max.x;
222         }
223         draw(screen, r, display->white, nil, ZP);
224         colresize(c, r);
225 }
226
227 Column*
228 rowwhichcol(Row *row, Point p)
229 {
230         int i;
231         Column *c;
232
233         for(i=0; i<row->ncol; i++){
234                 c = row->col[i];
235                 if(ptinrect(p, c->r))
236                         return c;
237         }
238         return nil;
239 }
240
241 Text*
242 rowwhich(Row *row, Point p, Rune r, int key)
243 {
244         Column *c;
245
246         if(ptinrect(p, row->tag.all))
247                 return &row->tag;
248         c = rowwhichcol(row, p);
249         if(c)
250                 return colwhich(c, p, r, key);
251         return nil;
252 }