1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 b3994ec5 2003-12-11 devnull #include "dat.h"
12 b3994ec5 2003-12-11 devnull #include "fns.h"
14 b3994ec5 2003-12-11 devnull static Rune Lheader[] = {
15 b3994ec5 2003-12-11 devnull 'N', 'e', 'w', ' ',
16 b3994ec5 2003-12-11 devnull 'C', 'u', 't', ' ',
17 b3994ec5 2003-12-11 devnull 'P', 'a', 's', 't', 'e', ' ',
18 b3994ec5 2003-12-11 devnull 'S', 'n', 'a', 'r', 'f', ' ',
19 b3994ec5 2003-12-11 devnull 'S', 'o', 'r', 't', ' ',
20 b3994ec5 2003-12-11 devnull 'Z', 'e', 'r', 'o', 'x', ' ',
21 b3994ec5 2003-12-11 devnull 'D', 'e', 'l', 'c', 'o', 'l', ' ',
26 b3994ec5 2003-12-11 devnull colinit(Column *c, Rectangle r)
28 b3994ec5 2003-12-11 devnull Rectangle r1;
31 b3994ec5 2003-12-11 devnull draw(screen, r, display->white, nil, ZP);
32 b3994ec5 2003-12-11 devnull c->r = r;
33 b3994ec5 2003-12-11 devnull c->w = nil;
34 b3994ec5 2003-12-11 devnull c->nw = 0;
35 b3994ec5 2003-12-11 devnull t = &c->tag;
36 b3994ec5 2003-12-11 devnull t->w = nil;
37 b3994ec5 2003-12-11 devnull t->col = c;
39 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y + font->height;
40 b3994ec5 2003-12-11 devnull textinit(t, fileaddtext(nil, t), r1, &reffont, tagcols);
41 b3994ec5 2003-12-11 devnull t->what = Columntag;
42 b3994ec5 2003-12-11 devnull r1.min.y = r1.max.y;
43 b3994ec5 2003-12-11 devnull r1.max.y += Border;
44 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
45 b3994ec5 2003-12-11 devnull textinsert(t, 0, Lheader, 38, TRUE);
46 b3994ec5 2003-12-11 devnull textsetselect(t, t->file->b.nc, t->file->b.nc);
47 b3994ec5 2003-12-11 devnull draw(screen, t->scrollr, colbutton, nil, colbutton->r.min);
48 b3994ec5 2003-12-11 devnull c->safe = TRUE;
52 b3994ec5 2003-12-11 devnull coladd(Column *c, Window *w, Window *clone, int y)
54 b3994ec5 2003-12-11 devnull Rectangle r, r1;
55 b3994ec5 2003-12-11 devnull Window *v;
56 41636940 2008-03-07 rsc int i, j, minht, ymax, buggered;
59 b3994ec5 2003-12-11 devnull r = c->r;
60 b3994ec5 2003-12-11 devnull r.min.y = c->tag.fr.r.max.y+Border;
61 b3994ec5 2003-12-11 devnull if(y<r.min.y && c->nw>0){ /* steal half of last window by default */
62 b3994ec5 2003-12-11 devnull v = c->w[c->nw-1];
63 b3994ec5 2003-12-11 devnull y = v->body.fr.r.min.y+Dy(v->body.fr.r)/2;
65 b3994ec5 2003-12-11 devnull /* look for window we'll land on */
66 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
67 b3994ec5 2003-12-11 devnull v = c->w[i];
68 b3994ec5 2003-12-11 devnull if(y < v->r.max.y)
71 41636940 2008-03-07 rsc buggered = 0;
72 b3994ec5 2003-12-11 devnull if(c->nw > 0){
73 b3994ec5 2003-12-11 devnull if(i < c->nw)
74 b3994ec5 2003-12-11 devnull i++; /* new window will go after v */
76 a2db69c8 2008-03-07 rsc * if landing window (v) is too small, grow it first.
78 20ae0b0f 2005-12-16 devnull minht = v->tag.fr.font->height+Border+1;
80 20ae0b0f 2005-12-16 devnull while(!c->safe || v->body.fr.maxlines<=3 || Dy(v->body.all) <= minht){
81 20ae0b0f 2005-12-16 devnull if(++j > 10){
82 41636940 2008-03-07 rsc buggered = 1; /* too many windows in column */
85 b3994ec5 2003-12-11 devnull colgrow(c, v, 1);
89 a2db69c8 2008-03-07 rsc * figure out where to split v to make room for w
92 41636940 2008-03-07 rsc /* new window stops where next window begins */
93 41636940 2008-03-07 rsc if(i < c->nw)
94 a2db69c8 2008-03-07 rsc ymax = c->w[i]->r.min.y-Border;
96 41636940 2008-03-07 rsc ymax = c->r.max.y;
98 41636940 2008-03-07 rsc /* new window must start after v's tag ends */
99 41636940 2008-03-07 rsc y = max(y, v->tagtop.max.y+Border);
101 41636940 2008-03-07 rsc /* new window must start early enough to end before ymax */
102 a2db69c8 2008-03-07 rsc y = min(y, ymax - minht);
104 41636940 2008-03-07 rsc /* if y is too small, too many windows in column */
105 41636940 2008-03-07 rsc if(y < v->tagtop.max.y+Border)
106 41636940 2008-03-07 rsc buggered = 1;
109 41636940 2008-03-07 rsc * resize & redraw v
112 41636940 2008-03-07 rsc r.max.y = ymax;
113 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
115 a2db69c8 2008-03-07 rsc y = min(y, ymax-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1));
116 b3994ec5 2003-12-11 devnull r1.max.y = min(y, v->body.fr.r.min.y+v->body.fr.nlines*v->body.fr.font->height);
117 33dc4226 2005-10-31 devnull r1.min.y = winresize(v, r1, FALSE, FALSE);
118 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+Border;
119 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
122 41636940 2008-03-07 rsc * leave r with w's coordinates
124 b3994ec5 2003-12-11 devnull r.min.y = r1.max.y;
126 b3994ec5 2003-12-11 devnull if(w == nil){
127 b3994ec5 2003-12-11 devnull w = emalloc(sizeof(Window));
128 b3994ec5 2003-12-11 devnull w->col = c;
129 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
130 b3994ec5 2003-12-11 devnull wininit(w, clone, r);
132 b3994ec5 2003-12-11 devnull w->col = c;
133 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
135 b3994ec5 2003-12-11 devnull w->tag.col = c;
136 b3994ec5 2003-12-11 devnull w->tag.row = c->row;
137 b3994ec5 2003-12-11 devnull w->body.col = c;
138 b3994ec5 2003-12-11 devnull w->body.row = c->row;
139 b3994ec5 2003-12-11 devnull c->w = realloc(c->w, (c->nw+1)*sizeof(Window*));
140 b3994ec5 2003-12-11 devnull memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
141 b3994ec5 2003-12-11 devnull c->nw++;
142 b3994ec5 2003-12-11 devnull c->w[i] = w;
143 41636940 2008-03-07 rsc c->safe = TRUE;
145 41636940 2008-03-07 rsc /* if there were too many windows, redraw the whole column */
146 41636940 2008-03-07 rsc if(buggered)
147 41636940 2008-03-07 rsc colresize(c, c->r);
149 b3994ec5 2003-12-11 devnull savemouse(w);
150 41636940 2008-03-07 rsc /* near the button, but in the body */
151 b3994ec5 2003-12-11 devnull moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
152 b3994ec5 2003-12-11 devnull barttext = &w->body;
153 b3994ec5 2003-12-11 devnull return w;
157 b3994ec5 2003-12-11 devnull colclose(Column *c, Window *w, int dofree)
159 b3994ec5 2003-12-11 devnull Rectangle r;
162 b3994ec5 2003-12-11 devnull /* w is locked */
163 b3994ec5 2003-12-11 devnull if(!c->safe)
164 b3994ec5 2003-12-11 devnull colgrow(c, w, 1);
165 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
166 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
167 b3994ec5 2003-12-11 devnull goto Found;
168 b3994ec5 2003-12-11 devnull error("can't find window");
170 b3994ec5 2003-12-11 devnull r = w->r;
171 b3994ec5 2003-12-11 devnull w->tag.col = nil;
172 b3994ec5 2003-12-11 devnull w->body.col = nil;
173 b3994ec5 2003-12-11 devnull w->col = nil;
174 b3994ec5 2003-12-11 devnull restoremouse(w);
175 b3994ec5 2003-12-11 devnull if(dofree){
176 b3994ec5 2003-12-11 devnull windelete(w);
177 b3994ec5 2003-12-11 devnull winclose(w);
179 b3994ec5 2003-12-11 devnull c->nw--;
180 a2db69c8 2008-03-07 rsc memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*));
181 b3994ec5 2003-12-11 devnull c->w = realloc(c->w, c->nw*sizeof(Window*));
182 b3994ec5 2003-12-11 devnull if(c->nw == 0){
183 b3994ec5 2003-12-11 devnull draw(screen, r, display->white, nil, ZP);
186 b3994ec5 2003-12-11 devnull if(i == c->nw){ /* extend last window down */
187 b3994ec5 2003-12-11 devnull w = c->w[i-1];
188 b3994ec5 2003-12-11 devnull r.min.y = w->r.min.y;
189 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
190 b3994ec5 2003-12-11 devnull }else{ /* extend next window up */
191 b3994ec5 2003-12-11 devnull w = c->w[i];
192 b3994ec5 2003-12-11 devnull r.max.y = w->r.max.y;
194 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
195 b3994ec5 2003-12-11 devnull if(c->safe)
196 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
200 b3994ec5 2003-12-11 devnull colcloseall(Column *c)
203 b3994ec5 2003-12-11 devnull Window *w;
205 b3994ec5 2003-12-11 devnull if(c == activecol)
206 b3994ec5 2003-12-11 devnull activecol = nil;
207 b3994ec5 2003-12-11 devnull textclose(&c->tag);
208 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
209 b3994ec5 2003-12-11 devnull w = c->w[i];
210 b3994ec5 2003-12-11 devnull winclose(w);
212 b3994ec5 2003-12-11 devnull c->nw = 0;
213 b3994ec5 2003-12-11 devnull free(c->w);
214 b3994ec5 2003-12-11 devnull free(c);
215 b3994ec5 2003-12-11 devnull clearmouse();
219 b3994ec5 2003-12-11 devnull colmousebut(Column *c)
221 b3994ec5 2003-12-11 devnull moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
225 b3994ec5 2003-12-11 devnull colresize(Column *c, Rectangle r)
228 b3994ec5 2003-12-11 devnull Rectangle r1, r2;
229 b3994ec5 2003-12-11 devnull Window *w;
231 b3994ec5 2003-12-11 devnull clearmouse();
233 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y + c->tag.fr.font->height;
234 33dc4226 2005-10-31 devnull textresize(&c->tag, r1, TRUE);
235 b3994ec5 2003-12-11 devnull draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
236 b3994ec5 2003-12-11 devnull r1.min.y = r1.max.y;
237 b3994ec5 2003-12-11 devnull r1.max.y += Border;
238 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
239 b3994ec5 2003-12-11 devnull r1.max.y = r.max.y;
240 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
241 b3994ec5 2003-12-11 devnull w = c->w[i];
242 b3994ec5 2003-12-11 devnull w->maxlines = 0;
243 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
244 b3994ec5 2003-12-11 devnull r1.max.y = r.max.y;
246 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r);
247 a2db69c8 2008-03-07 rsc r1.max.y = max(r1.max.y, r1.min.y + Border+font->height);
248 b3994ec5 2003-12-11 devnull r2 = r1;
249 b3994ec5 2003-12-11 devnull r2.max.y = r2.min.y+Border;
250 b3994ec5 2003-12-11 devnull draw(screen, r2, display->black, nil, ZP);
251 b3994ec5 2003-12-11 devnull r1.min.y = r2.max.y;
252 33dc4226 2005-10-31 devnull r1.min.y = winresize(w, r1, FALSE, i==c->nw-1);
254 b3994ec5 2003-12-11 devnull c->r = r;
259 b3994ec5 2003-12-11 devnull colcmp(const void *a, const void *b)
261 b3994ec5 2003-12-11 devnull Rune *r1, *r2;
262 b3994ec5 2003-12-11 devnull int i, nr1, nr2;
264 b3994ec5 2003-12-11 devnull r1 = (*(Window**)a)->body.file->name;
265 b3994ec5 2003-12-11 devnull nr1 = (*(Window**)a)->body.file->nname;
266 b3994ec5 2003-12-11 devnull r2 = (*(Window**)b)->body.file->name;
267 b3994ec5 2003-12-11 devnull nr2 = (*(Window**)b)->body.file->nname;
268 b3994ec5 2003-12-11 devnull for(i=0; i<nr1 && i<nr2; i++){
269 b3994ec5 2003-12-11 devnull if(*r1 != *r2)
270 b3994ec5 2003-12-11 devnull return *r1-*r2;
274 b3994ec5 2003-12-11 devnull return nr1-nr2;
278 b3994ec5 2003-12-11 devnull colsort(Column *c)
280 b3994ec5 2003-12-11 devnull int i, y;
281 b3994ec5 2003-12-11 devnull Rectangle r, r1, *rp;
282 b3994ec5 2003-12-11 devnull Window **wp, *w;
284 b3994ec5 2003-12-11 devnull if(c->nw == 0)
286 b3994ec5 2003-12-11 devnull clearmouse();
287 b3994ec5 2003-12-11 devnull rp = emalloc(c->nw*sizeof(Rectangle));
288 b3994ec5 2003-12-11 devnull wp = emalloc(c->nw*sizeof(Window*));
289 b3994ec5 2003-12-11 devnull memmove(wp, c->w, c->nw*sizeof(Window*));
290 b3994ec5 2003-12-11 devnull qsort(wp, c->nw, sizeof(Window*), colcmp);
291 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
292 b3994ec5 2003-12-11 devnull rp[i] = wp[i]->r;
293 b3994ec5 2003-12-11 devnull r = c->r;
294 b3994ec5 2003-12-11 devnull r.min.y = c->tag.fr.r.max.y;
295 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
296 b3994ec5 2003-12-11 devnull y = r.min.y;
297 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
298 b3994ec5 2003-12-11 devnull w = wp[i];
299 b3994ec5 2003-12-11 devnull r.min.y = y;
300 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
301 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
303 b3994ec5 2003-12-11 devnull r.max.y = r.min.y+Dy(w->r)+Border;
305 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+Border;
306 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
307 b3994ec5 2003-12-11 devnull r.min.y = r1.max.y;
308 d5233ccb 2005-10-31 devnull y = winresize(w, r, FALSE, i==c->nw-1);
310 b3994ec5 2003-12-11 devnull free(rp);
311 b3994ec5 2003-12-11 devnull free(c->w);
312 b3994ec5 2003-12-11 devnull c->w = wp;
316 b3994ec5 2003-12-11 devnull colgrow(Column *c, Window *w, int but)
318 b3994ec5 2003-12-11 devnull Rectangle r, cr;
319 b3994ec5 2003-12-11 devnull int i, j, k, l, y1, y2, *nl, *ny, tot, nnl, onl, dnl, h;
320 b3994ec5 2003-12-11 devnull Window *v;
322 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
323 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
324 b3994ec5 2003-12-11 devnull goto Found;
325 b3994ec5 2003-12-11 devnull error("can't find window");
328 b3994ec5 2003-12-11 devnull cr = c->r;
329 b3994ec5 2003-12-11 devnull if(but < 0){ /* make sure window fills its own space properly */
330 b3994ec5 2003-12-11 devnull r = w->r;
331 b3994ec5 2003-12-11 devnull if(i==c->nw-1 || c->safe==FALSE)
332 b3994ec5 2003-12-11 devnull r.max.y = cr.max.y;
334 a2db69c8 2008-03-07 rsc r.max.y = c->w[i+1]->r.min.y - Border;
335 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
338 b3994ec5 2003-12-11 devnull cr.min.y = c->w[0]->r.min.y;
339 b3994ec5 2003-12-11 devnull if(but == 3){ /* full size */
340 b3994ec5 2003-12-11 devnull if(i != 0){
341 b3994ec5 2003-12-11 devnull v = c->w[0];
342 b3994ec5 2003-12-11 devnull c->w[0] = w;
343 b3994ec5 2003-12-11 devnull c->w[i] = v;
345 b3994ec5 2003-12-11 devnull draw(screen, cr, textcols[BACK], nil, ZP);
346 33dc4226 2005-10-31 devnull winresize(w, cr, FALSE, TRUE);
347 b3994ec5 2003-12-11 devnull for(i=1; i<c->nw; i++)
348 b3994ec5 2003-12-11 devnull c->w[i]->body.fr.maxlines = 0;
349 b3994ec5 2003-12-11 devnull c->safe = FALSE;
352 b3994ec5 2003-12-11 devnull /* store old #lines for each window */
353 b3994ec5 2003-12-11 devnull onl = w->body.fr.maxlines;
354 b3994ec5 2003-12-11 devnull nl = emalloc(c->nw * sizeof(int));
355 b3994ec5 2003-12-11 devnull ny = emalloc(c->nw * sizeof(int));
356 b3994ec5 2003-12-11 devnull tot = 0;
357 b3994ec5 2003-12-11 devnull for(j=0; j<c->nw; j++){
358 33dc4226 2005-10-31 devnull l = c->w[j]->taglines-1 + c->w[j]->body.fr.maxlines;
359 b3994ec5 2003-12-11 devnull nl[j] = l;
360 b3994ec5 2003-12-11 devnull tot += l;
362 b3994ec5 2003-12-11 devnull /* approximate new #lines for this window */
363 b3994ec5 2003-12-11 devnull if(but == 2){ /* as big as can be */
364 b3994ec5 2003-12-11 devnull memset(nl, 0, c->nw * sizeof(int));
365 b3994ec5 2003-12-11 devnull goto Pack;
367 33dc4226 2005-10-31 devnull nnl = min(onl + max(min(5, w->taglines-1+w->maxlines), onl/2), tot);
368 33dc4226 2005-10-31 devnull if(nnl < w->taglines-1+w->maxlines)
369 a2db69c8 2008-03-07 rsc nnl = (w->taglines-1+w->maxlines + nnl)/2;
370 b3994ec5 2003-12-11 devnull if(nnl == 0)
371 b3994ec5 2003-12-11 devnull nnl = 2;
372 b3994ec5 2003-12-11 devnull dnl = nnl - onl;
373 b3994ec5 2003-12-11 devnull /* compute new #lines for each window */
374 b3994ec5 2003-12-11 devnull for(k=1; k<c->nw; k++){
375 b3994ec5 2003-12-11 devnull /* prune from later window */
376 b3994ec5 2003-12-11 devnull j = i+k;
377 b3994ec5 2003-12-11 devnull if(j<c->nw && nl[j]){
378 b3994ec5 2003-12-11 devnull l = min(dnl, max(1, nl[j]/2));
379 b3994ec5 2003-12-11 devnull nl[j] -= l;
380 b3994ec5 2003-12-11 devnull nl[i] += l;
381 b3994ec5 2003-12-11 devnull dnl -= l;
383 b3994ec5 2003-12-11 devnull /* prune from earlier window */
384 b3994ec5 2003-12-11 devnull j = i-k;
385 b3994ec5 2003-12-11 devnull if(j>=0 && nl[j]){
386 b3994ec5 2003-12-11 devnull l = min(dnl, max(1, nl[j]/2));
387 b3994ec5 2003-12-11 devnull nl[j] -= l;
388 b3994ec5 2003-12-11 devnull nl[i] += l;
389 b3994ec5 2003-12-11 devnull dnl -= l;
393 b3994ec5 2003-12-11 devnull /* pack everyone above */
394 b3994ec5 2003-12-11 devnull y1 = cr.min.y;
395 b3994ec5 2003-12-11 devnull for(j=0; j<i; j++){
396 b3994ec5 2003-12-11 devnull v = c->w[j];
397 b3994ec5 2003-12-11 devnull r = v->r;
398 b3994ec5 2003-12-11 devnull r.min.y = y1;
399 33dc4226 2005-10-31 devnull r.max.y = y1+Dy(v->tagtop);
400 b3994ec5 2003-12-11 devnull if(nl[j])
401 b3994ec5 2003-12-11 devnull r.max.y += 1 + nl[j]*v->body.fr.font->height;
402 33dc4226 2005-10-31 devnull r.min.y = winresize(v, r, c->safe, FALSE);
403 b3994ec5 2003-12-11 devnull r.max.y += Border;
404 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
405 b3994ec5 2003-12-11 devnull y1 = r.max.y;
407 b3994ec5 2003-12-11 devnull /* scan to see new size of everyone below */
408 b3994ec5 2003-12-11 devnull y2 = c->r.max.y;
409 b3994ec5 2003-12-11 devnull for(j=c->nw-1; j>i; j--){
410 b3994ec5 2003-12-11 devnull v = c->w[j];
411 b3994ec5 2003-12-11 devnull r = v->r;
412 33dc4226 2005-10-31 devnull r.min.y = y2-Dy(v->tagtop);
413 b3994ec5 2003-12-11 devnull if(nl[j])
414 b3994ec5 2003-12-11 devnull r.min.y -= 1 + nl[j]*v->body.fr.font->height;
415 b3994ec5 2003-12-11 devnull r.min.y -= Border;
416 b3994ec5 2003-12-11 devnull ny[j] = r.min.y;
417 b3994ec5 2003-12-11 devnull y2 = r.min.y;
419 b3994ec5 2003-12-11 devnull /* compute new size of window */
420 b3994ec5 2003-12-11 devnull r = w->r;
421 b3994ec5 2003-12-11 devnull r.min.y = y1;
422 33dc4226 2005-10-31 devnull r.max.y = y2;
423 b3994ec5 2003-12-11 devnull h = w->body.fr.font->height;
424 33dc4226 2005-10-31 devnull if(Dy(r) < Dy(w->tagtop)+1+h+Border)
425 d5233ccb 2005-10-31 devnull r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border;
426 b3994ec5 2003-12-11 devnull /* draw window */
427 41636940 2008-03-07 rsc r.max.y = winresize(w, r, c->safe, TRUE);
428 b3994ec5 2003-12-11 devnull if(i < c->nw-1){
429 b3994ec5 2003-12-11 devnull r.min.y = r.max.y;
430 b3994ec5 2003-12-11 devnull r.max.y += Border;
431 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
432 b3994ec5 2003-12-11 devnull for(j=i+1; j<c->nw; j++)
433 b3994ec5 2003-12-11 devnull ny[j] -= (y2-r.max.y);
435 b3994ec5 2003-12-11 devnull /* pack everyone below */
436 b3994ec5 2003-12-11 devnull y1 = r.max.y;
437 b3994ec5 2003-12-11 devnull for(j=i+1; j<c->nw; j++){
438 b3994ec5 2003-12-11 devnull v = c->w[j];
439 b3994ec5 2003-12-11 devnull r = v->r;
440 b3994ec5 2003-12-11 devnull r.min.y = y1;
441 d5233ccb 2005-10-31 devnull r.max.y = y1+Dy(v->tagtop);
442 b3994ec5 2003-12-11 devnull if(nl[j])
443 b3994ec5 2003-12-11 devnull r.max.y += 1 + nl[j]*v->body.fr.font->height;
444 a2db69c8 2008-03-07 rsc y1 = winresize(v, r, c->safe, j==c->nw-1);
445 b3994ec5 2003-12-11 devnull if(j < c->nw-1){ /* no border on last window */
446 33dc4226 2005-10-31 devnull r.min.y = y1;
447 b3994ec5 2003-12-11 devnull r.max.y += Border;
448 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
449 33dc4226 2005-10-31 devnull y1 = r.max.y;
452 b3994ec5 2003-12-11 devnull free(nl);
453 b3994ec5 2003-12-11 devnull free(ny);
454 b3994ec5 2003-12-11 devnull c->safe = TRUE;
455 b3994ec5 2003-12-11 devnull winmousebut(w);
459 b3994ec5 2003-12-11 devnull coldragwin(Column *c, Window *w, int but)
461 b3994ec5 2003-12-11 devnull Rectangle r;
462 b3994ec5 2003-12-11 devnull int i, b;
463 b3994ec5 2003-12-11 devnull Point p, op;
464 b3994ec5 2003-12-11 devnull Window *v;
465 b3994ec5 2003-12-11 devnull Column *nc;
467 b3994ec5 2003-12-11 devnull clearmouse();
468 b3994ec5 2003-12-11 devnull setcursor(mousectl, &boxcursor);
469 b3994ec5 2003-12-11 devnull b = mouse->buttons;
470 b3994ec5 2003-12-11 devnull op = mouse->xy;
471 b3994ec5 2003-12-11 devnull while(mouse->buttons == b)
472 b3994ec5 2003-12-11 devnull readmouse(mousectl);
473 b3994ec5 2003-12-11 devnull setcursor(mousectl, nil);
474 b3994ec5 2003-12-11 devnull if(mouse->buttons){
475 b3994ec5 2003-12-11 devnull while(mouse->buttons)
476 b3994ec5 2003-12-11 devnull readmouse(mousectl);
480 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
481 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
482 b3994ec5 2003-12-11 devnull goto Found;
483 b3994ec5 2003-12-11 devnull error("can't find window");
486 a2db69c8 2008-03-07 rsc if(w->tagexpand) /* force recomputation of window tag size */
487 a2db69c8 2008-03-07 rsc w->taglines = 1;
488 b3994ec5 2003-12-11 devnull p = mouse->xy;
489 b3994ec5 2003-12-11 devnull if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){
490 b3994ec5 2003-12-11 devnull colgrow(c, w, but);
491 b3994ec5 2003-12-11 devnull winmousebut(w);
494 b3994ec5 2003-12-11 devnull /* is it a flick to the right? */
495 b3994ec5 2003-12-11 devnull if(abs(p.y-op.y)<10 && p.x>op.x+30 && rowwhichcol(c->row, p)==c)
496 4da83e7c 2004-03-05 devnull p.x = op.x+Dx(w->r); /* yes: toss to next column */
497 b3994ec5 2003-12-11 devnull nc = rowwhichcol(c->row, p);
498 b3994ec5 2003-12-11 devnull if(nc!=nil && nc!=c){
499 b3994ec5 2003-12-11 devnull colclose(c, w, FALSE);
500 b3994ec5 2003-12-11 devnull coladd(nc, w, nil, p.y);
501 b3994ec5 2003-12-11 devnull winmousebut(w);
504 b3994ec5 2003-12-11 devnull if(i==0 && c->nw==1)
505 b3994ec5 2003-12-11 devnull return; /* can't do it */
506 b3994ec5 2003-12-11 devnull if((i>0 && p.y<c->w[i-1]->r.min.y) || (i<c->nw-1 && p.y>w->r.max.y)
507 b3994ec5 2003-12-11 devnull || (i==0 && p.y>w->r.max.y)){
508 b3994ec5 2003-12-11 devnull /* shuffle */
509 b3994ec5 2003-12-11 devnull colclose(c, w, FALSE);
510 b3994ec5 2003-12-11 devnull coladd(c, w, nil, p.y);
511 b3994ec5 2003-12-11 devnull winmousebut(w);
514 b3994ec5 2003-12-11 devnull if(i == 0)
516 b3994ec5 2003-12-11 devnull v = c->w[i-1];
517 33dc4226 2005-10-31 devnull if(p.y < v->tagtop.max.y)
518 33dc4226 2005-10-31 devnull p.y = v->tagtop.max.y;
519 33dc4226 2005-10-31 devnull if(p.y > w->r.max.y-Dy(w->tagtop)-Border)
520 33dc4226 2005-10-31 devnull p.y = w->r.max.y-Dy(w->tagtop)-Border;
521 b3994ec5 2003-12-11 devnull r = v->r;
522 b3994ec5 2003-12-11 devnull r.max.y = p.y;
523 b3994ec5 2003-12-11 devnull if(r.max.y > v->body.fr.r.min.y){
524 b3994ec5 2003-12-11 devnull r.max.y -= (r.max.y-v->body.fr.r.min.y)%v->body.fr.font->height;
525 b3994ec5 2003-12-11 devnull if(v->body.fr.r.min.y == v->body.fr.r.max.y)
526 b3994ec5 2003-12-11 devnull r.max.y++;
528 33dc4226 2005-10-31 devnull r.min.y = winresize(v, r, c->safe, FALSE);
529 b3994ec5 2003-12-11 devnull r.max.y = r.min.y+Border;
530 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
531 b3994ec5 2003-12-11 devnull r.min.y = r.max.y;
532 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
533 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
535 b3994ec5 2003-12-11 devnull r.max.y = c->w[i+1]->r.min.y-Border;
536 2d23eb93 2006-01-12 devnull winresize(w, r, c->safe, TRUE);
537 b3994ec5 2003-12-11 devnull c->safe = TRUE;
538 b3994ec5 2003-12-11 devnull winmousebut(w);
542 b3994ec5 2003-12-11 devnull colwhich(Column *c, Point p)
545 b3994ec5 2003-12-11 devnull Window *w;
547 b3994ec5 2003-12-11 devnull if(!ptinrect(p, c->r))
548 b3994ec5 2003-12-11 devnull return nil;
549 b3994ec5 2003-12-11 devnull if(ptinrect(p, c->tag.all))
550 b3994ec5 2003-12-11 devnull return &c->tag;
551 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
552 b3994ec5 2003-12-11 devnull w = c->w[i];
553 b3994ec5 2003-12-11 devnull if(ptinrect(p, w->r)){
554 83ab7d88 2007-11-27 rsc if(ptinrect(p, w->tagtop) || ptinrect(p, w->tag.all))
555 b3994ec5 2003-12-11 devnull return &w->tag;
556 83ab7d88 2007-11-27 rsc /* exclude partial line at bottom */
557 83ab7d88 2007-11-27 rsc if(p.x >= w->body.scrollr.max.x && p.y >= w->body.fr.r.max.y)
559 83ab7d88 2007-11-27 rsc return &w->body;
562 b3994ec5 2003-12-11 devnull return nil;
566 b3994ec5 2003-12-11 devnull colclean(Column *c)
568 b3994ec5 2003-12-11 devnull int i, clean;
570 b3994ec5 2003-12-11 devnull clean = TRUE;
571 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
572 b3994ec5 2003-12-11 devnull clean &= winclean(c->w[i], TRUE);
573 b3994ec5 2003-12-11 devnull return clean;