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