15 colinit(Column *c, Rectangle r)
20 draw(screen, r, display->white, nil, ZP);
28 r1.max.y = r1.min.y + font->height;
29 textinit(t, fileaddtext(nil, t), r1, &reffont, tagcols);
33 draw(screen, r1, display->black, nil, ZP);
34 textinsert(t, 0, L"New Cut Paste Snarf Sort Zerox Delcol ", 38, TRUE);
35 textsetselect(t, t->file->nc, t->file->nc);
36 draw(screen, t->scrollr, colbutton, nil, colbutton->r.min);
41 coladd(Column *c, Window *w, Window *clone, int y)
49 r.min.y = c->tag.r.max.y+Border;
50 if(y<r.min.y && c->nw>0){ /* steal half of last window by default */
52 y = v->body.r.min.y+Dy(v->body.r)/2;
54 /* look for window we'll land on */
55 for(i=0; i<c->nw; i++){
62 i++; /* new window will go after v */
64 * if v's too small, grow it first.
66 if(!c->safe || v->body.maxlines<=3){
68 y = v->body.r.min.y+Dy(v->body.r)/2;
74 t = c->w[i]->r.min.y-Border;
76 draw(screen, r, textcols[BACK], nil, ZP);
78 y = min(y, t-(v->tag.font->height+v->body.font->height+Border+1));
79 r1.max.y = min(y, v->body.r.min.y+v->body.nlines*v->body.font->height);
80 r1.min.y = winresize(v, r1, FALSE);
81 r1.max.y = r1.min.y+Border;
82 draw(screen, r1, display->black, nil, ZP);
86 w = emalloc(sizeof(Window));
88 draw(screen, r, textcols[BACK], nil, ZP);
92 winresize(w, r, FALSE);
98 c->w = realloc(c->w, (c->nw+1)*sizeof(Window*));
99 memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
103 /* near but not on the button */
104 moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
111 colclose(Column *c, Window *w, int dofree)
119 for(i=0; i<c->nw; i++)
122 error("can't find window");
133 memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*));
135 c->w = realloc(c->w, c->nw*sizeof(Window*));
137 draw(screen, r, display->white, nil, ZP);
140 if(i == c->nw){ /* extend last window down */
142 r.min.y = w->r.min.y;
143 r.max.y = c->r.max.y;
144 }else{ /* extend next window up */
146 r.max.y = w->r.max.y;
148 draw(screen, r, textcols[BACK], nil, ZP);
150 winresize(w, r, FALSE);
154 colcloseall(Column *c)
162 for(i=0; i<c->nw; i++){
173 colmousebut(Column *c)
175 moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
179 colresize(Column *c, Rectangle r)
187 r1.max.y = r1.min.y + c->tag.font->height;
188 textresize(&c->tag, r1);
189 draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
192 draw(screen, r1, display->black, nil, ZP);
194 for(i=0; i<c->nw; i++){
200 r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r);
202 r2.max.y = r2.min.y+Border;
203 draw(screen, r2, display->black, nil, ZP);
205 r1.min.y = winresize(w, r1, FALSE);
212 colcmp(void *a, void *b)
217 r1 = (*(Window**)a)->body.file->name;
218 nr1 = (*(Window**)a)->body.file->nname;
219 r2 = (*(Window**)b)->body.file->name;
220 nr2 = (*(Window**)b)->body.file->nname;
221 for(i=0; i<nr1 && i<nr2; i++){
234 Rectangle r, r1, *rp;
240 rp = emalloc(c->nw*sizeof(Rectangle));
241 wp = emalloc(c->nw*sizeof(Window*));
242 memmove(wp, c->w, c->nw*sizeof(Window*));
243 qsort(wp, c->nw, sizeof(Window*), colcmp);
244 for(i=0; i<c->nw; i++)
247 r.min.y = c->tag.r.max.y;
248 draw(screen, r, textcols[BACK], nil, ZP);
250 for(i=0; i<c->nw; i++){
254 r.max.y = c->r.max.y;
256 r.max.y = r.min.y+Dy(w->r)+Border;
258 r1.max.y = r1.min.y+Border;
259 draw(screen, r1, display->black, nil, ZP);
261 y = winresize(w, r, FALSE);
269 colgrow(Column *c, Window *w, int but)
272 int i, j, k, l, y1, y2, *nl, *ny, tot, nnl, onl, dnl, h;
275 for(i=0; i<c->nw; i++)
278 error("can't find window");
282 if(but < 0){ /* make sure window fills its own space properly */
284 if(i==c->nw-1 || c->safe==FALSE)
287 r.max.y = c->w[i+1]->r.min.y;
288 winresize(w, r, FALSE);
291 cr.min.y = c->w[0]->r.min.y;
292 if(but == 3){ /* full size */
298 draw(screen, cr, textcols[BACK], nil, ZP);
299 winresize(w, cr, FALSE);
300 for(i=1; i<c->nw; i++)
301 c->w[i]->body.maxlines = 0;
305 /* store old #lines for each window */
306 onl = w->body.maxlines;
307 nl = emalloc(c->nw * sizeof(int));
308 ny = emalloc(c->nw * sizeof(int));
310 for(j=0; j<c->nw; j++){
311 l = c->w[j]->body.maxlines;
315 /* approximate new #lines for this window */
316 if(but == 2){ /* as big as can be */
317 memset(nl, 0, c->nw * sizeof(int));
320 nnl = min(onl + max(min(5, w->maxlines), onl/2), tot);
321 if(nnl < w->maxlines)
322 nnl = (w->maxlines+nnl)/2;
326 /* compute new #lines for each window */
327 for(k=1; k<c->nw; k++){
328 /* prune from later window */
330 if(j<c->nw && nl[j]){
331 l = min(dnl, max(1, nl[j]/2));
336 /* prune from earlier window */
339 l = min(dnl, max(1, nl[j]/2));
346 /* pack everyone above */
352 r.max.y = y1+Dy(v->tag.all);
354 r.max.y += 1 + nl[j]*v->body.font->height;
355 if(!c->safe || !eqrect(v->r, r)){
356 draw(screen, r, textcols[BACK], nil, ZP);
357 winresize(v, r, c->safe);
359 r.min.y = v->r.max.y;
361 draw(screen, r, display->black, nil, ZP);
364 /* scan to see new size of everyone below */
366 for(j=c->nw-1; j>i; j--){
369 r.min.y = y2-Dy(v->tag.all);
371 r.min.y -= 1 + nl[j]*v->body.font->height;
376 /* compute new size of window */
379 r.max.y = r.min.y+Dy(w->tag.all);
380 h = w->body.font->height;
381 if(y2-r.max.y >= 1+h+Border){
383 r.max.y += h*((y2-r.max.y)/h);
386 if(!c->safe || !eqrect(w->r, r)){
387 draw(screen, r, textcols[BACK], nil, ZP);
388 winresize(w, r, c->safe);
393 draw(screen, r, display->black, nil, ZP);
394 for(j=i+1; j<c->nw; j++)
395 ny[j] -= (y2-r.max.y);
397 /* pack everyone below */
399 for(j=i+1; j<c->nw; j++){
403 r.max.y = y1+Dy(v->tag.all);
405 r.max.y += 1 + nl[j]*v->body.font->height;
406 if(!c->safe || !eqrect(v->r, r)){
407 draw(screen, r, textcols[BACK], nil, ZP);
408 winresize(v, r, c->safe);
410 if(j < c->nw-1){ /* no border on last window */
411 r.min.y = v->r.max.y;
413 draw(screen, r, display->black, nil, ZP);
419 r.max.y = c->r.max.y;
420 draw(screen, r, textcols[BACK], nil, ZP);
428 coldragwin(Column *c, Window *w, int but)
437 setcursor(mousectl, &boxcursor);
440 while(mouse->buttons == b)
442 setcursor(mousectl, nil);
444 while(mouse->buttons)
449 for(i=0; i<c->nw; i++)
452 error("can't find window");
456 if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){
461 /* is it a flick to the right? */
462 if(abs(p.y-op.y)<10 && p.x>op.x+30 && rowwhichcol(c->row, p)==c)
463 p.x = op.x+Dx(w->r); /* yes: toss to next column */
464 nc = rowwhichcol(c->row, p);
465 if(nc!=nil && nc!=c){
466 colclose(c, w, FALSE);
467 coladd(nc, w, nil, p.y);
472 return; /* can't do it */
473 if((i>0 && p.y<c->w[i-1]->r.min.y) || (i<c->nw-1 && p.y>w->r.max.y)
474 || (i==0 && p.y>w->r.max.y)){
476 colclose(c, w, FALSE);
477 coladd(c, w, nil, p.y);
484 if(p.y < v->tag.all.max.y)
485 p.y = v->tag.all.max.y;
486 if(p.y > w->r.max.y-Dy(w->tag.all)-Border)
487 p.y = w->r.max.y-Dy(w->tag.all)-Border;
490 if(r.max.y > v->body.r.min.y){
491 r.max.y -= (r.max.y-v->body.r.min.y)%v->body.font->height;
492 if(v->body.r.min.y == v->body.r.max.y)
495 if(!eqrect(v->r, r)){
496 draw(screen, r, textcols[BACK], nil, ZP);
497 winresize(v, r, c->safe);
499 r.min.y = v->r.max.y;
500 r.max.y = r.min.y+Border;
501 draw(screen, r, display->black, nil, ZP);
504 r.max.y = c->r.max.y;
506 r.max.y = c->w[i+1]->r.min.y-Border;
507 if(!eqrect(w->r, r)){
508 draw(screen, r, textcols[BACK], nil, ZP);
509 winresize(w, r, c->safe);
516 colwhich(Column *c, Point p)
521 if(!ptinrect(p, c->r))
523 if(ptinrect(p, c->tag.all))
525 for(i=0; i<c->nw; i++){
527 if(ptinrect(p, w->r)){
528 if(ptinrect(p, w->tag.all))
532 /* scrollr drops below w->r on low windows */
533 if(ptinrect(p, w->body.scrollr))
545 for(i=0; i<c->nw; i++)
546 clean &= winclean(c->w[i], TRUE);