Exemplo n.º 1
0
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;
}
Exemplo n.º 2
0
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;
}