Window* coladd(Column *c, Window *w, Window *clone, int y) { Rectangle r, r1; Window *v; int i, t; v = nil; r = c->r; r.min.y = c->tag.r.max.y+Border; if(y<r.min.y && c->nw>0){ /* steal half of last window by default */ v = c->w[c->nw-1]; y = v->body.r.min.y+Dy(v->body.r)/2; } /* look for window we'll land on */ for(i=0; i<c->nw; i++){ v = c->w[i]; if(y < v->r.max.y) break; } if(c->nw > 0){ if(i < c->nw) i++; /* new window will go after v */ /* * if v's too small, grow it first. */ if(!c->safe || v->body.maxlines<=3){ colgrow(c, v, 1); y = v->body.r.min.y+Dy(v->body.r)/2; } r = v->r; if(i == c->nw) t = c->r.max.y; else t = c->w[i]->r.min.y-Border; r.max.y = t; draw(screen, r, textcols[BACK], nil, ZP); r1 = r; y = min(y, t-(v->tag.font->height+v->body.font->height+Border+1)); r1.max.y = min(y, v->body.r.min.y+v->body.nlines*v->body.font->height); r1.min.y = winresize(v, r1, FALSE); r1.max.y = r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); r.min.y = r1.max.y; } if(w == nil){ w = emalloc(sizeof(Window)); w->col = c; draw(screen, r, textcols[BACK], nil, ZP); wininit(w, clone, r); }else{ w->col = c; winresize(w, r, FALSE); } w->tag.col = c; w->tag.row = c->row; w->body.col = c; w->body.row = c->row; c->w = realloc(c->w, (c->nw+1)*sizeof(Window*)); memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*)); c->nw++; c->w[i] = w; savemouse(w); /* near but not on the button */ moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3))); barttext = &w->body; c->safe = TRUE; return w; }
Window* coladd(Column *c, Window *w, Window *clone, int y) { Rectangle r, r1; Window *v; int i, j, minht, ymax, buggered; v = nil; r = c->r; r.min.y = c->tag.fr.r.max.y+Border; if(y<r.min.y && c->nw>0){ /* steal half of last window by default */ v = c->w[c->nw-1]; y = v->body.fr.r.min.y+Dy(v->body.fr.r)/2; } /* look for window we'll land on */ for(i=0; i<c->nw; i++){ v = c->w[i]; if(y < v->r.max.y) break; } buggered = 0; if(c->nw > 0){ if(i < c->nw) i++; /* new window will go after v */ /* * if landing window (v) is too small, grow it first. */ minht = v->tag.fr.font->height+Border+1; j = 0; while(!c->safe || v->body.fr.maxlines<=3 || Dy(v->body.all) <= minht){ if(++j > 10){ buggered = 1; /* too many windows in column */ break; } colgrow(c, v, 1); } /* * figure out where to split v to make room for w */ /* new window stops where next window begins */ if(i < c->nw) ymax = c->w[i]->r.min.y-Border; else ymax = c->r.max.y; /* new window must start after v's tag ends */ y = max(y, v->tagtop.max.y+Border); /* new window must start early enough to end before ymax */ y = min(y, ymax - minht); /* if y is too small, too many windows in column */ if(y < v->tagtop.max.y+Border) buggered = 1; /* * resize & redraw v */ r = v->r; r.max.y = ymax; draw(screen, r, textcols[BACK], nil, ZP); r1 = r; y = min(y, ymax-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1)); r1.max.y = min(y, v->body.fr.r.min.y+v->body.fr.nlines*v->body.fr.font->height); r1.min.y = winresize(v, r1, FALSE, FALSE); r1.max.y = r1.min.y+Border; draw(screen, r1, display->black, nil, ZP); /* * leave r with w's coordinates */ r.min.y = r1.max.y; } if(w == nil){ w = emalloc(sizeof(Window)); w->col = c; draw(screen, r, textcols[BACK], nil, ZP); wininit(w, clone, r); }else{ w->col = c; winresize(w, r, FALSE, TRUE); } w->tag.col = c; w->tag.row = c->row; w->body.col = c; w->body.row = c->row; c->w = realloc(c->w, (c->nw+1)*sizeof(Window*)); memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*)); c->nw++; c->w[i] = w; c->safe = TRUE; /* if there were too many windows, redraw the whole column */ if(buggered) colresize(c, c->r); savemouse(w); /* near the button, but in the body */ moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3))); barttext = &w->body; return w; }