Blame


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"
13 b3994ec5 2003-12-11 devnull
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', ' ',
22 b3994ec5 2003-12-11 devnull 0
23 b3994ec5 2003-12-11 devnull };
24 b3994ec5 2003-12-11 devnull
25 b3994ec5 2003-12-11 devnull void
26 b3994ec5 2003-12-11 devnull colinit(Column *c, Rectangle r)
27 b3994ec5 2003-12-11 devnull {
28 b3994ec5 2003-12-11 devnull Rectangle r1;
29 b3994ec5 2003-12-11 devnull Text *t;
30 b3994ec5 2003-12-11 devnull
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;
38 b3994ec5 2003-12-11 devnull r1 = r;
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;
49 b3994ec5 2003-12-11 devnull }
50 b3994ec5 2003-12-11 devnull
51 b3994ec5 2003-12-11 devnull Window*
52 b3994ec5 2003-12-11 devnull coladd(Column *c, Window *w, Window *clone, int y)
53 b3994ec5 2003-12-11 devnull {
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;
57 b3994ec5 2003-12-11 devnull
58 b3994ec5 2003-12-11 devnull v = nil;
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;
64 b3994ec5 2003-12-11 devnull }
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)
69 b3994ec5 2003-12-11 devnull break;
70 b3994ec5 2003-12-11 devnull }
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 */
75 b3994ec5 2003-12-11 devnull /*
76 a2db69c8 2008-03-07 rsc * if landing window (v) is too small, grow it first.
77 b3994ec5 2003-12-11 devnull */
78 20ae0b0f 2005-12-16 devnull minht = v->tag.fr.font->height+Border+1;
79 20ae0b0f 2005-12-16 devnull j = 0;
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 */
83 20ae0b0f 2005-12-16 devnull break;
84 20ae0b0f 2005-12-16 devnull }
85 b3994ec5 2003-12-11 devnull colgrow(c, v, 1);
86 b3994ec5 2003-12-11 devnull }
87 a2db69c8 2008-03-07 rsc
88 a2db69c8 2008-03-07 rsc /*
89 a2db69c8 2008-03-07 rsc * figure out where to split v to make room for w
90 a2db69c8 2008-03-07 rsc */
91 41636940 2008-03-07 rsc
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;
95 41636940 2008-03-07 rsc else
96 41636940 2008-03-07 rsc ymax = c->r.max.y;
97 41636940 2008-03-07 rsc
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);
100 41636940 2008-03-07 rsc
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);
103 41636940 2008-03-07 rsc
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;
107 a2db69c8 2008-03-07 rsc
108 a2db69c8 2008-03-07 rsc /*
109 41636940 2008-03-07 rsc * resize & redraw v
110 a2db69c8 2008-03-07 rsc */
111 41636940 2008-03-07 rsc r = v->r;
112 41636940 2008-03-07 rsc r.max.y = ymax;
113 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
114 b3994ec5 2003-12-11 devnull r1 = r;
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);
120 41636940 2008-03-07 rsc
121 41636940 2008-03-07 rsc /*
122 41636940 2008-03-07 rsc * leave r with w's coordinates
123 41636940 2008-03-07 rsc */
124 b3994ec5 2003-12-11 devnull r.min.y = r1.max.y;
125 b3994ec5 2003-12-11 devnull }
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);
131 b3994ec5 2003-12-11 devnull }else{
132 b3994ec5 2003-12-11 devnull w->col = c;
133 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
134 b3994ec5 2003-12-11 devnull }
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;
144 41636940 2008-03-07 rsc
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);
148 41636940 2008-03-07 rsc
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;
154 b3994ec5 2003-12-11 devnull }
155 b3994ec5 2003-12-11 devnull
156 b3994ec5 2003-12-11 devnull void
157 b3994ec5 2003-12-11 devnull colclose(Column *c, Window *w, int dofree)
158 b3994ec5 2003-12-11 devnull {
159 b3994ec5 2003-12-11 devnull Rectangle r;
160 b3994ec5 2003-12-11 devnull int i;
161 b3994ec5 2003-12-11 devnull
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");
169 b3994ec5 2003-12-11 devnull Found:
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);
178 b3994ec5 2003-12-11 devnull }
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);
184 b3994ec5 2003-12-11 devnull return;
185 b3994ec5 2003-12-11 devnull }
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;
193 b3994ec5 2003-12-11 devnull }
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);
197 b3994ec5 2003-12-11 devnull }
198 b3994ec5 2003-12-11 devnull
199 b3994ec5 2003-12-11 devnull void
200 b3994ec5 2003-12-11 devnull colcloseall(Column *c)
201 b3994ec5 2003-12-11 devnull {
202 b3994ec5 2003-12-11 devnull int i;
203 b3994ec5 2003-12-11 devnull Window *w;
204 b3994ec5 2003-12-11 devnull
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);
211 b3994ec5 2003-12-11 devnull }
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();
216 b3994ec5 2003-12-11 devnull }
217 b3994ec5 2003-12-11 devnull
218 b3994ec5 2003-12-11 devnull void
219 b3994ec5 2003-12-11 devnull colmousebut(Column *c)
220 b3994ec5 2003-12-11 devnull {
221 b3994ec5 2003-12-11 devnull moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
222 b3994ec5 2003-12-11 devnull }
223 b3994ec5 2003-12-11 devnull
224 b3994ec5 2003-12-11 devnull void
225 b3994ec5 2003-12-11 devnull colresize(Column *c, Rectangle r)
226 b3994ec5 2003-12-11 devnull {
227 b3994ec5 2003-12-11 devnull int i;
228 b3994ec5 2003-12-11 devnull Rectangle r1, r2;
229 b3994ec5 2003-12-11 devnull Window *w;
230 b3994ec5 2003-12-11 devnull
231 b3994ec5 2003-12-11 devnull clearmouse();
232 b3994ec5 2003-12-11 devnull r1 = r;
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;
245 b3994ec5 2003-12-11 devnull else
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);
253 b3994ec5 2003-12-11 devnull }
254 b3994ec5 2003-12-11 devnull c->r = r;
255 b3994ec5 2003-12-11 devnull }
256 b3994ec5 2003-12-11 devnull
257 b3994ec5 2003-12-11 devnull static
258 b3994ec5 2003-12-11 devnull int
259 b3994ec5 2003-12-11 devnull colcmp(const void *a, const void *b)
260 b3994ec5 2003-12-11 devnull {
261 b3994ec5 2003-12-11 devnull Rune *r1, *r2;
262 b3994ec5 2003-12-11 devnull int i, nr1, nr2;
263 b3994ec5 2003-12-11 devnull
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;
271 b3994ec5 2003-12-11 devnull r1++;
272 b3994ec5 2003-12-11 devnull r2++;
273 b3994ec5 2003-12-11 devnull }
274 b3994ec5 2003-12-11 devnull return nr1-nr2;
275 b3994ec5 2003-12-11 devnull }
276 b3994ec5 2003-12-11 devnull
277 b3994ec5 2003-12-11 devnull void
278 b3994ec5 2003-12-11 devnull colsort(Column *c)
279 b3994ec5 2003-12-11 devnull {
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;
283 b3994ec5 2003-12-11 devnull
284 b3994ec5 2003-12-11 devnull if(c->nw == 0)
285 b3994ec5 2003-12-11 devnull return;
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;
302 b3994ec5 2003-12-11 devnull else
303 b3994ec5 2003-12-11 devnull r.max.y = r.min.y+Dy(w->r)+Border;
304 b3994ec5 2003-12-11 devnull r1 = r;
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);
309 b3994ec5 2003-12-11 devnull }
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;
313 b3994ec5 2003-12-11 devnull }
314 b3994ec5 2003-12-11 devnull
315 b3994ec5 2003-12-11 devnull void
316 b3994ec5 2003-12-11 devnull colgrow(Column *c, Window *w, int but)
317 b3994ec5 2003-12-11 devnull {
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;
321 b3994ec5 2003-12-11 devnull
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");
326 b3994ec5 2003-12-11 devnull
327 b3994ec5 2003-12-11 devnull Found:
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;
333 b3994ec5 2003-12-11 devnull else
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);
336 b3994ec5 2003-12-11 devnull return;
337 b3994ec5 2003-12-11 devnull }
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;
344 b3994ec5 2003-12-11 devnull }
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;
350 b3994ec5 2003-12-11 devnull return;
351 b3994ec5 2003-12-11 devnull }
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;
361 b3994ec5 2003-12-11 devnull }
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;
366 b3994ec5 2003-12-11 devnull }
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;
382 b3994ec5 2003-12-11 devnull }
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;
390 b3994ec5 2003-12-11 devnull }
391 b3994ec5 2003-12-11 devnull }
392 b3994ec5 2003-12-11 devnull Pack:
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;
406 b3994ec5 2003-12-11 devnull }
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;
418 b3994ec5 2003-12-11 devnull }
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);
434 b3994ec5 2003-12-11 devnull }
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;
450 b3994ec5 2003-12-11 devnull }
451 b3994ec5 2003-12-11 devnull }
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);
456 b3994ec5 2003-12-11 devnull }
457 b3994ec5 2003-12-11 devnull
458 b3994ec5 2003-12-11 devnull void
459 b3994ec5 2003-12-11 devnull coldragwin(Column *c, Window *w, int but)
460 b3994ec5 2003-12-11 devnull {
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;
466 b3994ec5 2003-12-11 devnull
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);
477 b3994ec5 2003-12-11 devnull return;
478 b3994ec5 2003-12-11 devnull }
479 b3994ec5 2003-12-11 devnull
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");
484 b3994ec5 2003-12-11 devnull
485 b3994ec5 2003-12-11 devnull Found:
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);
492 b3994ec5 2003-12-11 devnull return;
493 b3994ec5 2003-12-11 devnull }
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);
502 b3994ec5 2003-12-11 devnull return;
503 b3994ec5 2003-12-11 devnull }
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);
512 b3994ec5 2003-12-11 devnull return;
513 b3994ec5 2003-12-11 devnull }
514 b3994ec5 2003-12-11 devnull if(i == 0)
515 b3994ec5 2003-12-11 devnull return;
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++;
527 b3994ec5 2003-12-11 devnull }
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;
534 b3994ec5 2003-12-11 devnull else
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);
539 b3994ec5 2003-12-11 devnull }
540 b3994ec5 2003-12-11 devnull
541 b3994ec5 2003-12-11 devnull Text*
542 b3994ec5 2003-12-11 devnull colwhich(Column *c, Point p)
543 b3994ec5 2003-12-11 devnull {
544 b3994ec5 2003-12-11 devnull int i;
545 b3994ec5 2003-12-11 devnull Window *w;
546 b3994ec5 2003-12-11 devnull
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)
558 83ab7d88 2007-11-27 rsc return nil;
559 83ab7d88 2007-11-27 rsc return &w->body;
560 b3994ec5 2003-12-11 devnull }
561 b3994ec5 2003-12-11 devnull }
562 b3994ec5 2003-12-11 devnull return nil;
563 b3994ec5 2003-12-11 devnull }
564 b3994ec5 2003-12-11 devnull
565 b3994ec5 2003-12-11 devnull int
566 b3994ec5 2003-12-11 devnull colclean(Column *c)
567 b3994ec5 2003-12-11 devnull {
568 b3994ec5 2003-12-11 devnull int i, clean;
569 b3994ec5 2003-12-11 devnull
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;
574 b3994ec5 2003-12-11 devnull }