16 colinit(Column *c, Rectangle r)
21 draw(screen, r, display->white, nil, ZP);
29 r1.max.y = r1.min.y + font->height;
30 textinit(t, screen, r1, font, tagcols);
34 draw(screen, r1, display->black, nil, ZP);
35 textinsert(t, 0, L"New Cut Paste Snarf Sort Delcol ", 32);
36 textsetselect(t, t->rs.nr, t->rs.nr);
37 draw(screen, t->scrollr, colbutton, nil, colbutton->r.min);
42 coladd(Column *c, Window *w, Window *clone, int y)
50 r.min.y = c->tag.r.max.y+Border;
51 if(y<r.min.y && c->nw>0){ /* steal half of last window by default */
53 y = v->page.all.min.y+Dy(v->page.all)/2;
55 /* look for window we'll land on */
56 for(i=0; i<c->nw; i++){
63 i++; /* new window will go after v */
65 * if v's too small, grow it first.
67 if(!c->safe || Dy(v->page.all)<=3 ){
69 y = v->page.all.min.y+Dy(v->page.all)/2;
75 t = c->w[i]->r.min.y-Border;
78 y = min(y, t-(Dy(v->r)-Dy(v->page.all)));
79 r1.max.y = min(y, v->page.all.min.y+Dy(v->page.all));
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));
91 winresize(w, r, FALSE);
100 w->status.row = c->row;
101 c->w = realloc(c->w, (c->nw+1)*sizeof(Window*));
102 memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
106 /* near but not on the button */
107 moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
113 colclose(Column *c, Window *w, int dofree)
121 for(i=0; i<c->nw; i++)
124 error("can't find window");
134 memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*));
136 c->w = realloc(c->w, c->nw*sizeof(Window*));
138 draw(screen, r, display->white, nil, ZP);
141 if(i == c->nw){ /* extend last window down */
143 r.min.y = w->r.min.y;
144 r.max.y = c->r.max.y;
145 }else{ /* extend next window up */
147 r.max.y = w->r.max.y;
150 winresize(w, r, FALSE);
154 colcloseall(Column *c)
161 if(seltext && c==seltext->col)
164 for(i=0; i<c->nw; i++){
179 colmousebut(Column *c)
181 moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
185 colresize(Column *c, Rectangle r)
193 r1.max.y = r1.min.y + c->tag.font->height;
194 textresize(&c->tag, screen, r1);
195 draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
198 draw(screen, r1, display->black, nil, ZP);
200 for(i=0; i<c->nw; i++){
205 r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r);
207 r2.max.y = r2.min.y+Border;
208 draw(screen, r2, display->black, nil, ZP);
210 r1.min.y = winresize(w, r1, FALSE);
217 colcmp(void *a, void *b)
222 r1 = (*(Window**)a)->page.title.r;
223 nr1 = (*(Window**)a)->page.title.nr;
224 r2 = (*(Window**)b)->page.title.r;
225 nr2 = (*(Window**)b)->page.title.nr;
226 for(i=0; i<nr1 && i<nr2; i++){
239 Rectangle r, r1, *rp;
245 rp = emalloc(c->nw*sizeof(Rectangle));
246 wp = emalloc(c->nw*sizeof(Window*));
247 memmove(wp, c->w, c->nw*sizeof(Window*));
248 qsort(wp, c->nw, sizeof(Window*), colcmp);
249 for(i=0; i<c->nw; i++)
253 for(i=0; i<c->nw; i++){
257 r.max.y = c->r.max.y;
259 r.max.y = r.min.y+Dy(w->r)+Border;
261 r1.max.y = r1.min.y+Border;
262 draw(screen, r1, display->black, nil, ZP);
264 y = winresize(w, r, FALSE);
272 colgrow(Column *c, Window *w, int but)
275 int i, j, k, l, y1, y2, *nl, *ny, tot, nnl, onl, dnl, h, wnl;
278 for(i=0; i<c->nw; i++)
281 error("can't find window");
285 if(but < 0){ /* make sure window fills its own space properly */
287 if(i==c->nw-1 || c->safe==FALSE)
290 r.max.y = c->w[i+1]->r.min.y;
291 winresize(w, r, FALSE);
294 cr.min.y = c->w[0]->r.min.y;
295 if(but == 3){ /* full size */
301 for(j=1; j<c->nw; j++)
302 c->w[j]->page.all = ZR;
303 winresize(w, cr, FALSE);
307 /* store old #lines for each window */
308 wnl = Dy(w->page.all);
310 nl = emalloc(c->nw * sizeof(int));
311 ny = emalloc(c->nw * sizeof(int));
313 for(j=0; j<c->nw; j++){
314 l = Dy(c->w[j]->page.all);
318 /* approximate new #lines for this window */
319 if(but == 2){ /* as big as can be */
320 memset(nl, 0, c->nw * sizeof(int));
323 nnl = min(onl + max(min(5, wnl), onl/2), tot);
329 /* compute new #lines for each window */
330 for(k=1; k<c->nw; k++){
331 /* prune from later window */
333 if(j<c->nw && nl[j]){
334 l = min(dnl, max(1, nl[j]/2));
339 /* prune from earlier window */
342 l = min(dnl, max(1, nl[j]/2));
349 /* pack everyone above */
355 r.max.y = y1+Dy(v->tag.all)+Border+Dy(v->url.all);
357 r.max.y += 1 + nl[j];
358 if(!c->safe || !eqrect(v->r, r))
359 winresize(v, r, c->safe);
361 r.min.y = v->r.max.y;
363 draw(screen, r, display->black, nil, ZP);
366 /* scan to see new size of everyone below */
368 for(j=c->nw-1; j>i; j--){
371 r.min.y = y2-Dy(v->tag.all)-Border-Dy(v->url.all);
373 r.min.y -= 1 + nl[j];
378 /* compute new size of window */
382 r.max.y = c->r.max.y;
384 r.max.y = r.min.y+Dy(w->tag.all)+Border+Dy(w->url.all);
386 if(y2-r.max.y >= 2*(1+h+Border)){
388 r.max.y += h*((y2-r.max.y)/h);
392 if(!c->safe || !eqrect(w->r, r))
393 winresize(w, r, c->safe);
398 draw(screen, r, display->black, nil, ZP);
399 for(j=i+1; j<c->nw; j++)
400 ny[j] -= (y2-r.max.y);
402 /* pack everyone below */
404 for(j=i+1; j<c->nw; j++){
409 r.max.y = c->r.max.y;
411 r.max.y = y1+Dy(v->tag.all)+Border+Dy(v->url.all);
413 r.max.y += 1 + nl[j];
415 if(!c->safe || !eqrect(v->r, r))
416 winresize(v, r, c->safe);
417 if(j < c->nw-1){ /* no border on last window */
418 r.min.y = v->r.max.y;
420 draw(screen, r, display->black, nil, ZP);
431 coldragwin(Column *c, Window *w, int but)
440 setcursor(mousectl, &boxcursor);
443 while(mouse->buttons == b)
445 setcursor(mousectl, nil);
447 while(mouse->buttons)
452 for(i=0; i<c->nw; i++)
455 error("can't find window");
459 if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){
464 /* is it a flick to the right? */
465 if(abs(p.y-op.y)<10 && p.x>op.x+30 && rowwhichcol(c->row, p)==c)
466 p.x = op.x+Dx(w->r); /* yes: toss to next column */
467 nc = rowwhichcol(c->row, p);
468 if(nc!=nil && nc!=c){
469 colclose(c, w, FALSE);
470 coladd(nc, w, nil, p.y);
475 return; /* can't do it */
476 if((i>0 && p.y<c->w[i-1]->r.min.y) || (i<c->nw-1 && p.y>w->r.max.y)
477 || (i==0 && p.y>w->r.max.y)){
479 colclose(c, w, FALSE);
480 coladd(c, w, nil, p.y);
487 if(p.y < v->url.all.max.y)
488 p.y = v->url.all.max.y;
489 if(p.y > w->r.max.y-Dy(w->tag.all)-Border-Dy(w->url.all))
490 p.y = w->r.max.y-Dy(w->tag.all)-Border-Dy(w->url.all);
493 if(r.max.y > v->page.all.min.y){
494 r.max.y -= (r.max.y-v->page.all.min.y)%font->height;
495 if(v->page.all.min.y == v->page.all.max.y)
499 winresize(v, r, c->safe);
500 r.min.y = v->r.max.y;
501 r.max.y = r.min.y+Border;
502 draw(screen, r, display->black, nil, ZP);
505 r.max.y = c->r.max.y;
507 r.max.y = c->w[i+1]->r.min.y-Border;
509 winresize(w, r, c->safe);
515 colwhich(Column *c, Point p, Rune r, int key)
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 winlock(w, key ? 'K' : 'M');
530 t = wintype(w, p, r);
532 t = winmouse(w, p, r);
546 for(i=0; i<c->nw; i++)
547 clean &= winclean(c->w[i], TRUE);