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 20ae0b0f 2005-12-16 devnull int i, j, minht, t;
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 b3994ec5 2003-12-11 devnull if(c->nw > 0){
72 b3994ec5 2003-12-11 devnull if(i < c->nw)
73 b3994ec5 2003-12-11 devnull i++; /* new window will go after v */
74 b3994ec5 2003-12-11 devnull /*
75 b3994ec5 2003-12-11 devnull * if v's too small, grow it first.
76 b3994ec5 2003-12-11 devnull */
77 20ae0b0f 2005-12-16 devnull minht = v->tag.fr.font->height+Border+1;
78 20ae0b0f 2005-12-16 devnull j = 0;
79 20ae0b0f 2005-12-16 devnull while(!c->safe || v->body.fr.maxlines<=3 || Dy(v->body.all) <= minht){
80 20ae0b0f 2005-12-16 devnull if(++j > 10){
81 20ae0b0f 2005-12-16 devnull fprint(2, "oops: dy=%d\n", Dy(v->body.all));
82 20ae0b0f 2005-12-16 devnull break;
83 20ae0b0f 2005-12-16 devnull }
84 b3994ec5 2003-12-11 devnull colgrow(c, v, 1);
85 b3994ec5 2003-12-11 devnull }
86 b3994ec5 2003-12-11 devnull if(i == c->nw)
87 b3994ec5 2003-12-11 devnull t = c->r.max.y;
88 b3994ec5 2003-12-11 devnull else
89 b3994ec5 2003-12-11 devnull t = c->w[i]->r.min.y-Border;
90 20ae0b0f 2005-12-16 devnull y = v->body.all.min.y+Dy(v->body.all)/2;
91 20ae0b0f 2005-12-16 devnull if(t - y < minht)
92 20ae0b0f 2005-12-16 devnull y = t - minht;
93 20ae0b0f 2005-12-16 devnull if(y < v->body.all.min.y)
94 20ae0b0f 2005-12-16 devnull y = v->body.all.min.y;
95 20ae0b0f 2005-12-16 devnull r = v->r;
96 b3994ec5 2003-12-11 devnull r.max.y = t;
97 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
98 b3994ec5 2003-12-11 devnull r1 = r;
99 33dc4226 2005-10-31 devnull y = min(y, t-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1));
100 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);
101 33dc4226 2005-10-31 devnull r1.min.y = winresize(v, r1, FALSE, FALSE);
102 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+Border;
103 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
104 b3994ec5 2003-12-11 devnull r.min.y = r1.max.y;
105 b3994ec5 2003-12-11 devnull }
106 b3994ec5 2003-12-11 devnull if(w == nil){
107 b3994ec5 2003-12-11 devnull w = emalloc(sizeof(Window));
108 b3994ec5 2003-12-11 devnull w->col = c;
109 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
110 b3994ec5 2003-12-11 devnull wininit(w, clone, r);
111 b3994ec5 2003-12-11 devnull }else{
112 b3994ec5 2003-12-11 devnull w->col = c;
113 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
114 b3994ec5 2003-12-11 devnull }
115 b3994ec5 2003-12-11 devnull w->tag.col = c;
116 b3994ec5 2003-12-11 devnull w->tag.row = c->row;
117 b3994ec5 2003-12-11 devnull w->body.col = c;
118 b3994ec5 2003-12-11 devnull w->body.row = c->row;
119 b3994ec5 2003-12-11 devnull c->w = realloc(c->w, (c->nw+1)*sizeof(Window*));
120 b3994ec5 2003-12-11 devnull memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
121 b3994ec5 2003-12-11 devnull c->nw++;
122 b3994ec5 2003-12-11 devnull c->w[i] = w;
123 b3994ec5 2003-12-11 devnull savemouse(w);
124 b3994ec5 2003-12-11 devnull /* near but not on the button */
125 b3994ec5 2003-12-11 devnull moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
126 b3994ec5 2003-12-11 devnull barttext = &w->body;
127 b3994ec5 2003-12-11 devnull c->safe = TRUE;
128 b3994ec5 2003-12-11 devnull return w;
129 b3994ec5 2003-12-11 devnull }
130 b3994ec5 2003-12-11 devnull
131 b3994ec5 2003-12-11 devnull void
132 b3994ec5 2003-12-11 devnull colclose(Column *c, Window *w, int dofree)
133 b3994ec5 2003-12-11 devnull {
134 b3994ec5 2003-12-11 devnull Rectangle r;
135 b3994ec5 2003-12-11 devnull int i;
136 b3994ec5 2003-12-11 devnull
137 b3994ec5 2003-12-11 devnull /* w is locked */
138 b3994ec5 2003-12-11 devnull if(!c->safe)
139 b3994ec5 2003-12-11 devnull colgrow(c, w, 1);
140 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
141 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
142 b3994ec5 2003-12-11 devnull goto Found;
143 b3994ec5 2003-12-11 devnull error("can't find window");
144 b3994ec5 2003-12-11 devnull Found:
145 b3994ec5 2003-12-11 devnull r = w->r;
146 b3994ec5 2003-12-11 devnull w->tag.col = nil;
147 b3994ec5 2003-12-11 devnull w->body.col = nil;
148 b3994ec5 2003-12-11 devnull w->col = nil;
149 b3994ec5 2003-12-11 devnull restoremouse(w);
150 b3994ec5 2003-12-11 devnull if(dofree){
151 b3994ec5 2003-12-11 devnull windelete(w);
152 b3994ec5 2003-12-11 devnull winclose(w);
153 b3994ec5 2003-12-11 devnull }
154 b3994ec5 2003-12-11 devnull memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*));
155 b3994ec5 2003-12-11 devnull c->nw--;
156 b3994ec5 2003-12-11 devnull c->w = realloc(c->w, c->nw*sizeof(Window*));
157 b3994ec5 2003-12-11 devnull if(c->nw == 0){
158 b3994ec5 2003-12-11 devnull draw(screen, r, display->white, nil, ZP);
159 b3994ec5 2003-12-11 devnull return;
160 b3994ec5 2003-12-11 devnull }
161 b3994ec5 2003-12-11 devnull if(i == c->nw){ /* extend last window down */
162 b3994ec5 2003-12-11 devnull w = c->w[i-1];
163 b3994ec5 2003-12-11 devnull r.min.y = w->r.min.y;
164 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
165 b3994ec5 2003-12-11 devnull }else{ /* extend next window up */
166 b3994ec5 2003-12-11 devnull w = c->w[i];
167 b3994ec5 2003-12-11 devnull r.max.y = w->r.max.y;
168 b3994ec5 2003-12-11 devnull }
169 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
170 b3994ec5 2003-12-11 devnull if(c->safe)
171 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
172 b3994ec5 2003-12-11 devnull }
173 b3994ec5 2003-12-11 devnull
174 b3994ec5 2003-12-11 devnull void
175 b3994ec5 2003-12-11 devnull colcloseall(Column *c)
176 b3994ec5 2003-12-11 devnull {
177 b3994ec5 2003-12-11 devnull int i;
178 b3994ec5 2003-12-11 devnull Window *w;
179 b3994ec5 2003-12-11 devnull
180 b3994ec5 2003-12-11 devnull if(c == activecol)
181 b3994ec5 2003-12-11 devnull activecol = nil;
182 b3994ec5 2003-12-11 devnull textclose(&c->tag);
183 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
184 b3994ec5 2003-12-11 devnull w = c->w[i];
185 b3994ec5 2003-12-11 devnull winclose(w);
186 b3994ec5 2003-12-11 devnull }
187 b3994ec5 2003-12-11 devnull c->nw = 0;
188 b3994ec5 2003-12-11 devnull free(c->w);
189 b3994ec5 2003-12-11 devnull free(c);
190 b3994ec5 2003-12-11 devnull clearmouse();
191 b3994ec5 2003-12-11 devnull }
192 b3994ec5 2003-12-11 devnull
193 b3994ec5 2003-12-11 devnull void
194 b3994ec5 2003-12-11 devnull colmousebut(Column *c)
195 b3994ec5 2003-12-11 devnull {
196 b3994ec5 2003-12-11 devnull moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
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 colresize(Column *c, Rectangle r)
201 b3994ec5 2003-12-11 devnull {
202 b3994ec5 2003-12-11 devnull int i;
203 b3994ec5 2003-12-11 devnull Rectangle r1, r2;
204 b3994ec5 2003-12-11 devnull Window *w;
205 b3994ec5 2003-12-11 devnull
206 b3994ec5 2003-12-11 devnull clearmouse();
207 b3994ec5 2003-12-11 devnull r1 = r;
208 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y + c->tag.fr.font->height;
209 33dc4226 2005-10-31 devnull textresize(&c->tag, r1, TRUE);
210 b3994ec5 2003-12-11 devnull draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
211 b3994ec5 2003-12-11 devnull r1.min.y = r1.max.y;
212 b3994ec5 2003-12-11 devnull r1.max.y += Border;
213 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
214 b3994ec5 2003-12-11 devnull r1.max.y = r.max.y;
215 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
216 b3994ec5 2003-12-11 devnull w = c->w[i];
217 b3994ec5 2003-12-11 devnull w->maxlines = 0;
218 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
219 b3994ec5 2003-12-11 devnull r1.max.y = r.max.y;
220 b3994ec5 2003-12-11 devnull else
221 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+(Dy(w->r)+Border)*Dy(r)/Dy(c->r);
222 20ae0b0f 2005-12-16 devnull if(Dy(r1) < Border+font->height)
223 20ae0b0f 2005-12-16 devnull r1.max.y = r1.min.y + Border+font->height;
224 b3994ec5 2003-12-11 devnull r2 = r1;
225 b3994ec5 2003-12-11 devnull r2.max.y = r2.min.y+Border;
226 b3994ec5 2003-12-11 devnull draw(screen, r2, display->black, nil, ZP);
227 b3994ec5 2003-12-11 devnull r1.min.y = r2.max.y;
228 33dc4226 2005-10-31 devnull r1.min.y = winresize(w, r1, FALSE, i==c->nw-1);
229 b3994ec5 2003-12-11 devnull }
230 b3994ec5 2003-12-11 devnull c->r = r;
231 b3994ec5 2003-12-11 devnull }
232 b3994ec5 2003-12-11 devnull
233 b3994ec5 2003-12-11 devnull static
234 b3994ec5 2003-12-11 devnull int
235 b3994ec5 2003-12-11 devnull colcmp(const void *a, const void *b)
236 b3994ec5 2003-12-11 devnull {
237 b3994ec5 2003-12-11 devnull Rune *r1, *r2;
238 b3994ec5 2003-12-11 devnull int i, nr1, nr2;
239 b3994ec5 2003-12-11 devnull
240 b3994ec5 2003-12-11 devnull r1 = (*(Window**)a)->body.file->name;
241 b3994ec5 2003-12-11 devnull nr1 = (*(Window**)a)->body.file->nname;
242 b3994ec5 2003-12-11 devnull r2 = (*(Window**)b)->body.file->name;
243 b3994ec5 2003-12-11 devnull nr2 = (*(Window**)b)->body.file->nname;
244 b3994ec5 2003-12-11 devnull for(i=0; i<nr1 && i<nr2; i++){
245 b3994ec5 2003-12-11 devnull if(*r1 != *r2)
246 b3994ec5 2003-12-11 devnull return *r1-*r2;
247 b3994ec5 2003-12-11 devnull r1++;
248 b3994ec5 2003-12-11 devnull r2++;
249 b3994ec5 2003-12-11 devnull }
250 b3994ec5 2003-12-11 devnull return nr1-nr2;
251 b3994ec5 2003-12-11 devnull }
252 b3994ec5 2003-12-11 devnull
253 b3994ec5 2003-12-11 devnull void
254 b3994ec5 2003-12-11 devnull colsort(Column *c)
255 b3994ec5 2003-12-11 devnull {
256 b3994ec5 2003-12-11 devnull int i, y;
257 b3994ec5 2003-12-11 devnull Rectangle r, r1, *rp;
258 b3994ec5 2003-12-11 devnull Window **wp, *w;
259 b3994ec5 2003-12-11 devnull
260 b3994ec5 2003-12-11 devnull if(c->nw == 0)
261 b3994ec5 2003-12-11 devnull return;
262 b3994ec5 2003-12-11 devnull clearmouse();
263 b3994ec5 2003-12-11 devnull rp = emalloc(c->nw*sizeof(Rectangle));
264 b3994ec5 2003-12-11 devnull wp = emalloc(c->nw*sizeof(Window*));
265 b3994ec5 2003-12-11 devnull memmove(wp, c->w, c->nw*sizeof(Window*));
266 b3994ec5 2003-12-11 devnull qsort(wp, c->nw, sizeof(Window*), colcmp);
267 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
268 b3994ec5 2003-12-11 devnull rp[i] = wp[i]->r;
269 b3994ec5 2003-12-11 devnull r = c->r;
270 b3994ec5 2003-12-11 devnull r.min.y = c->tag.fr.r.max.y;
271 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
272 b3994ec5 2003-12-11 devnull y = r.min.y;
273 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
274 b3994ec5 2003-12-11 devnull w = wp[i];
275 b3994ec5 2003-12-11 devnull r.min.y = y;
276 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
277 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
278 b3994ec5 2003-12-11 devnull else
279 b3994ec5 2003-12-11 devnull r.max.y = r.min.y+Dy(w->r)+Border;
280 b3994ec5 2003-12-11 devnull r1 = r;
281 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+Border;
282 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
283 b3994ec5 2003-12-11 devnull r.min.y = r1.max.y;
284 d5233ccb 2005-10-31 devnull y = winresize(w, r, FALSE, i==c->nw-1);
285 b3994ec5 2003-12-11 devnull }
286 b3994ec5 2003-12-11 devnull free(rp);
287 b3994ec5 2003-12-11 devnull free(c->w);
288 b3994ec5 2003-12-11 devnull c->w = wp;
289 b3994ec5 2003-12-11 devnull }
290 b3994ec5 2003-12-11 devnull
291 b3994ec5 2003-12-11 devnull void
292 b3994ec5 2003-12-11 devnull colgrow(Column *c, Window *w, int but)
293 b3994ec5 2003-12-11 devnull {
294 b3994ec5 2003-12-11 devnull Rectangle r, cr;
295 b3994ec5 2003-12-11 devnull int i, j, k, l, y1, y2, *nl, *ny, tot, nnl, onl, dnl, h;
296 b3994ec5 2003-12-11 devnull Window *v;
297 b3994ec5 2003-12-11 devnull
298 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
299 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
300 b3994ec5 2003-12-11 devnull goto Found;
301 b3994ec5 2003-12-11 devnull error("can't find window");
302 b3994ec5 2003-12-11 devnull
303 b3994ec5 2003-12-11 devnull Found:
304 b3994ec5 2003-12-11 devnull cr = c->r;
305 b3994ec5 2003-12-11 devnull if(but < 0){ /* make sure window fills its own space properly */
306 b3994ec5 2003-12-11 devnull r = w->r;
307 b3994ec5 2003-12-11 devnull if(i==c->nw-1 || c->safe==FALSE)
308 b3994ec5 2003-12-11 devnull r.max.y = cr.max.y;
309 b3994ec5 2003-12-11 devnull else
310 2d23eb93 2006-01-12 devnull r.max.y = c->w[i+1]->r.min.y-Border;
311 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
312 b3994ec5 2003-12-11 devnull return;
313 b3994ec5 2003-12-11 devnull }
314 b3994ec5 2003-12-11 devnull cr.min.y = c->w[0]->r.min.y;
315 b3994ec5 2003-12-11 devnull if(but == 3){ /* full size */
316 b3994ec5 2003-12-11 devnull if(i != 0){
317 b3994ec5 2003-12-11 devnull v = c->w[0];
318 b3994ec5 2003-12-11 devnull c->w[0] = w;
319 b3994ec5 2003-12-11 devnull c->w[i] = v;
320 b3994ec5 2003-12-11 devnull }
321 b3994ec5 2003-12-11 devnull draw(screen, cr, textcols[BACK], nil, ZP);
322 33dc4226 2005-10-31 devnull winresize(w, cr, FALSE, TRUE);
323 b3994ec5 2003-12-11 devnull for(i=1; i<c->nw; i++)
324 b3994ec5 2003-12-11 devnull c->w[i]->body.fr.maxlines = 0;
325 b3994ec5 2003-12-11 devnull c->safe = FALSE;
326 b3994ec5 2003-12-11 devnull return;
327 b3994ec5 2003-12-11 devnull }
328 b3994ec5 2003-12-11 devnull /* store old #lines for each window */
329 b3994ec5 2003-12-11 devnull onl = w->body.fr.maxlines;
330 b3994ec5 2003-12-11 devnull nl = emalloc(c->nw * sizeof(int));
331 b3994ec5 2003-12-11 devnull ny = emalloc(c->nw * sizeof(int));
332 b3994ec5 2003-12-11 devnull tot = 0;
333 b3994ec5 2003-12-11 devnull for(j=0; j<c->nw; j++){
334 33dc4226 2005-10-31 devnull l = c->w[j]->taglines-1 + c->w[j]->body.fr.maxlines;
335 b3994ec5 2003-12-11 devnull nl[j] = l;
336 b3994ec5 2003-12-11 devnull tot += l;
337 b3994ec5 2003-12-11 devnull }
338 b3994ec5 2003-12-11 devnull /* approximate new #lines for this window */
339 b3994ec5 2003-12-11 devnull if(but == 2){ /* as big as can be */
340 b3994ec5 2003-12-11 devnull memset(nl, 0, c->nw * sizeof(int));
341 b3994ec5 2003-12-11 devnull goto Pack;
342 b3994ec5 2003-12-11 devnull }
343 33dc4226 2005-10-31 devnull nnl = min(onl + max(min(5, w->taglines-1+w->maxlines), onl/2), tot);
344 33dc4226 2005-10-31 devnull if(nnl < w->taglines-1+w->maxlines)
345 33dc4226 2005-10-31 devnull nnl = (w->taglines-1+w->maxlines+nnl)/2;
346 b3994ec5 2003-12-11 devnull if(nnl == 0)
347 b3994ec5 2003-12-11 devnull nnl = 2;
348 b3994ec5 2003-12-11 devnull dnl = nnl - onl;
349 b3994ec5 2003-12-11 devnull /* compute new #lines for each window */
350 b3994ec5 2003-12-11 devnull for(k=1; k<c->nw; k++){
351 b3994ec5 2003-12-11 devnull /* prune from later window */
352 b3994ec5 2003-12-11 devnull j = i+k;
353 b3994ec5 2003-12-11 devnull if(j<c->nw && nl[j]){
354 b3994ec5 2003-12-11 devnull l = min(dnl, max(1, nl[j]/2));
355 b3994ec5 2003-12-11 devnull nl[j] -= l;
356 b3994ec5 2003-12-11 devnull nl[i] += l;
357 b3994ec5 2003-12-11 devnull dnl -= l;
358 b3994ec5 2003-12-11 devnull }
359 b3994ec5 2003-12-11 devnull /* prune from earlier window */
360 b3994ec5 2003-12-11 devnull j = i-k;
361 b3994ec5 2003-12-11 devnull if(j>=0 && nl[j]){
362 b3994ec5 2003-12-11 devnull l = min(dnl, max(1, nl[j]/2));
363 b3994ec5 2003-12-11 devnull nl[j] -= l;
364 b3994ec5 2003-12-11 devnull nl[i] += l;
365 b3994ec5 2003-12-11 devnull dnl -= l;
366 b3994ec5 2003-12-11 devnull }
367 b3994ec5 2003-12-11 devnull }
368 b3994ec5 2003-12-11 devnull Pack:
369 b3994ec5 2003-12-11 devnull /* pack everyone above */
370 b3994ec5 2003-12-11 devnull y1 = cr.min.y;
371 b3994ec5 2003-12-11 devnull for(j=0; j<i; j++){
372 b3994ec5 2003-12-11 devnull v = c->w[j];
373 b3994ec5 2003-12-11 devnull r = v->r;
374 b3994ec5 2003-12-11 devnull r.min.y = y1;
375 33dc4226 2005-10-31 devnull r.max.y = y1+Dy(v->tagtop);
376 b3994ec5 2003-12-11 devnull if(nl[j])
377 b3994ec5 2003-12-11 devnull r.max.y += 1 + nl[j]*v->body.fr.font->height;
378 33dc4226 2005-10-31 devnull r.min.y = winresize(v, r, c->safe, FALSE);
379 b3994ec5 2003-12-11 devnull r.max.y += Border;
380 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
381 b3994ec5 2003-12-11 devnull y1 = r.max.y;
382 b3994ec5 2003-12-11 devnull }
383 b3994ec5 2003-12-11 devnull /* scan to see new size of everyone below */
384 b3994ec5 2003-12-11 devnull y2 = c->r.max.y;
385 b3994ec5 2003-12-11 devnull for(j=c->nw-1; j>i; j--){
386 b3994ec5 2003-12-11 devnull v = c->w[j];
387 b3994ec5 2003-12-11 devnull r = v->r;
388 33dc4226 2005-10-31 devnull r.min.y = y2-Dy(v->tagtop);
389 b3994ec5 2003-12-11 devnull if(nl[j])
390 b3994ec5 2003-12-11 devnull r.min.y -= 1 + nl[j]*v->body.fr.font->height;
391 b3994ec5 2003-12-11 devnull r.min.y -= Border;
392 b3994ec5 2003-12-11 devnull ny[j] = r.min.y;
393 b3994ec5 2003-12-11 devnull y2 = r.min.y;
394 b3994ec5 2003-12-11 devnull }
395 b3994ec5 2003-12-11 devnull /* compute new size of window */
396 b3994ec5 2003-12-11 devnull r = w->r;
397 b3994ec5 2003-12-11 devnull r.min.y = y1;
398 33dc4226 2005-10-31 devnull r.max.y = y2;
399 b3994ec5 2003-12-11 devnull h = w->body.fr.font->height;
400 33dc4226 2005-10-31 devnull if(Dy(r) < Dy(w->tagtop)+1+h+Border)
401 d5233ccb 2005-10-31 devnull r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border;
402 b3994ec5 2003-12-11 devnull /* draw window */
403 33dc4226 2005-10-31 devnull winresize(w, r, c->safe, TRUE);
404 b3994ec5 2003-12-11 devnull if(i < c->nw-1){
405 b3994ec5 2003-12-11 devnull r.min.y = r.max.y;
406 b3994ec5 2003-12-11 devnull r.max.y += Border;
407 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
408 b3994ec5 2003-12-11 devnull for(j=i+1; j<c->nw; j++)
409 b3994ec5 2003-12-11 devnull ny[j] -= (y2-r.max.y);
410 b3994ec5 2003-12-11 devnull }
411 b3994ec5 2003-12-11 devnull /* pack everyone below */
412 b3994ec5 2003-12-11 devnull y1 = r.max.y;
413 b3994ec5 2003-12-11 devnull for(j=i+1; j<c->nw; j++){
414 b3994ec5 2003-12-11 devnull v = c->w[j];
415 b3994ec5 2003-12-11 devnull r = v->r;
416 b3994ec5 2003-12-11 devnull r.min.y = y1;
417 d5233ccb 2005-10-31 devnull r.max.y = y1+Dy(v->tagtop);
418 b3994ec5 2003-12-11 devnull if(nl[j])
419 b3994ec5 2003-12-11 devnull r.max.y += 1 + nl[j]*v->body.fr.font->height;
420 33dc4226 2005-10-31 devnull y1 = winresize(v, r, c->safe, j+1==c->nw);
421 b3994ec5 2003-12-11 devnull if(j < c->nw-1){ /* no border on last window */
422 33dc4226 2005-10-31 devnull r.min.y = y1;
423 b3994ec5 2003-12-11 devnull r.max.y += Border;
424 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
425 33dc4226 2005-10-31 devnull y1 = r.max.y;
426 b3994ec5 2003-12-11 devnull }
427 b3994ec5 2003-12-11 devnull }
428 33dc4226 2005-10-31 devnull /*
429 b3994ec5 2003-12-11 devnull r = w->r;
430 b3994ec5 2003-12-11 devnull r.min.y = y1;
431 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
432 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
433 33dc4226 2005-10-31 devnull */
434 b3994ec5 2003-12-11 devnull free(nl);
435 b3994ec5 2003-12-11 devnull free(ny);
436 b3994ec5 2003-12-11 devnull c->safe = TRUE;
437 b3994ec5 2003-12-11 devnull winmousebut(w);
438 b3994ec5 2003-12-11 devnull }
439 b3994ec5 2003-12-11 devnull
440 b3994ec5 2003-12-11 devnull void
441 b3994ec5 2003-12-11 devnull coldragwin(Column *c, Window *w, int but)
442 b3994ec5 2003-12-11 devnull {
443 b3994ec5 2003-12-11 devnull Rectangle r;
444 b3994ec5 2003-12-11 devnull int i, b;
445 b3994ec5 2003-12-11 devnull Point p, op;
446 b3994ec5 2003-12-11 devnull Window *v;
447 b3994ec5 2003-12-11 devnull Column *nc;
448 b3994ec5 2003-12-11 devnull
449 b3994ec5 2003-12-11 devnull clearmouse();
450 b3994ec5 2003-12-11 devnull setcursor(mousectl, &boxcursor);
451 b3994ec5 2003-12-11 devnull b = mouse->buttons;
452 b3994ec5 2003-12-11 devnull op = mouse->xy;
453 b3994ec5 2003-12-11 devnull while(mouse->buttons == b)
454 b3994ec5 2003-12-11 devnull readmouse(mousectl);
455 b3994ec5 2003-12-11 devnull setcursor(mousectl, nil);
456 b3994ec5 2003-12-11 devnull if(mouse->buttons){
457 b3994ec5 2003-12-11 devnull while(mouse->buttons)
458 b3994ec5 2003-12-11 devnull readmouse(mousectl);
459 b3994ec5 2003-12-11 devnull return;
460 b3994ec5 2003-12-11 devnull }
461 b3994ec5 2003-12-11 devnull
462 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
463 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
464 b3994ec5 2003-12-11 devnull goto Found;
465 b3994ec5 2003-12-11 devnull error("can't find window");
466 b3994ec5 2003-12-11 devnull
467 b3994ec5 2003-12-11 devnull Found:
468 f8dea3c1 2005-12-16 devnull /* TAG - force recompute tag size (if in auto-expand mode) on mouse op. */
469 f8dea3c1 2005-12-16 devnull w->taglines = 1;
470 f8dea3c1 2005-12-16 devnull /* END TAG */
471 b3994ec5 2003-12-11 devnull p = mouse->xy;
472 b3994ec5 2003-12-11 devnull if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){
473 b3994ec5 2003-12-11 devnull colgrow(c, w, but);
474 b3994ec5 2003-12-11 devnull winmousebut(w);
475 b3994ec5 2003-12-11 devnull return;
476 b3994ec5 2003-12-11 devnull }
477 b3994ec5 2003-12-11 devnull /* is it a flick to the right? */
478 b3994ec5 2003-12-11 devnull if(abs(p.y-op.y)<10 && p.x>op.x+30 && rowwhichcol(c->row, p)==c)
479 4da83e7c 2004-03-05 devnull p.x = op.x+Dx(w->r); /* yes: toss to next column */
480 b3994ec5 2003-12-11 devnull nc = rowwhichcol(c->row, p);
481 b3994ec5 2003-12-11 devnull if(nc!=nil && nc!=c){
482 b3994ec5 2003-12-11 devnull colclose(c, w, FALSE);
483 b3994ec5 2003-12-11 devnull coladd(nc, w, nil, p.y);
484 b3994ec5 2003-12-11 devnull winmousebut(w);
485 b3994ec5 2003-12-11 devnull return;
486 b3994ec5 2003-12-11 devnull }
487 b3994ec5 2003-12-11 devnull if(i==0 && c->nw==1)
488 b3994ec5 2003-12-11 devnull return; /* can't do it */
489 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)
490 b3994ec5 2003-12-11 devnull || (i==0 && p.y>w->r.max.y)){
491 b3994ec5 2003-12-11 devnull /* shuffle */
492 b3994ec5 2003-12-11 devnull colclose(c, w, FALSE);
493 b3994ec5 2003-12-11 devnull coladd(c, w, nil, p.y);
494 b3994ec5 2003-12-11 devnull winmousebut(w);
495 b3994ec5 2003-12-11 devnull return;
496 b3994ec5 2003-12-11 devnull }
497 b3994ec5 2003-12-11 devnull if(i == 0)
498 b3994ec5 2003-12-11 devnull return;
499 b3994ec5 2003-12-11 devnull v = c->w[i-1];
500 33dc4226 2005-10-31 devnull if(p.y < v->tagtop.max.y)
501 33dc4226 2005-10-31 devnull p.y = v->tagtop.max.y;
502 33dc4226 2005-10-31 devnull if(p.y > w->r.max.y-Dy(w->tagtop)-Border)
503 33dc4226 2005-10-31 devnull p.y = w->r.max.y-Dy(w->tagtop)-Border;
504 b3994ec5 2003-12-11 devnull r = v->r;
505 b3994ec5 2003-12-11 devnull r.max.y = p.y;
506 b3994ec5 2003-12-11 devnull if(r.max.y > v->body.fr.r.min.y){
507 b3994ec5 2003-12-11 devnull r.max.y -= (r.max.y-v->body.fr.r.min.y)%v->body.fr.font->height;
508 b3994ec5 2003-12-11 devnull if(v->body.fr.r.min.y == v->body.fr.r.max.y)
509 b3994ec5 2003-12-11 devnull r.max.y++;
510 b3994ec5 2003-12-11 devnull }
511 33dc4226 2005-10-31 devnull r.min.y = winresize(v, r, c->safe, FALSE);
512 b3994ec5 2003-12-11 devnull r.max.y = r.min.y+Border;
513 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
514 b3994ec5 2003-12-11 devnull r.min.y = r.max.y;
515 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
516 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
517 b3994ec5 2003-12-11 devnull else
518 b3994ec5 2003-12-11 devnull r.max.y = c->w[i+1]->r.min.y-Border;
519 2d23eb93 2006-01-12 devnull winresize(w, r, c->safe, TRUE);
520 b3994ec5 2003-12-11 devnull c->safe = TRUE;
521 b3994ec5 2003-12-11 devnull winmousebut(w);
522 b3994ec5 2003-12-11 devnull }
523 b3994ec5 2003-12-11 devnull
524 b3994ec5 2003-12-11 devnull Text*
525 b3994ec5 2003-12-11 devnull colwhich(Column *c, Point p)
526 b3994ec5 2003-12-11 devnull {
527 b3994ec5 2003-12-11 devnull int i;
528 b3994ec5 2003-12-11 devnull Window *w;
529 b3994ec5 2003-12-11 devnull
530 b3994ec5 2003-12-11 devnull if(!ptinrect(p, c->r))
531 b3994ec5 2003-12-11 devnull return nil;
532 b3994ec5 2003-12-11 devnull if(ptinrect(p, c->tag.all))
533 b3994ec5 2003-12-11 devnull return &c->tag;
534 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
535 b3994ec5 2003-12-11 devnull w = c->w[i];
536 b3994ec5 2003-12-11 devnull if(ptinrect(p, w->r)){
537 33dc4226 2005-10-31 devnull if(ptinrect(p, w->tagtop) || ptinrect(p, w->tag.fr.r))
538 b3994ec5 2003-12-11 devnull return &w->tag;
539 33dc4226 2005-10-31 devnull if(ptinrect(p, w->body.scrollr) || ptinrect(p, w->body.fr.r))
540 33dc4226 2005-10-31 devnull return &w->body;
541 33dc4226 2005-10-31 devnull return nil;
542 b3994ec5 2003-12-11 devnull }
543 b3994ec5 2003-12-11 devnull }
544 b3994ec5 2003-12-11 devnull return nil;
545 b3994ec5 2003-12-11 devnull }
546 b3994ec5 2003-12-11 devnull
547 b3994ec5 2003-12-11 devnull int
548 b3994ec5 2003-12-11 devnull colclean(Column *c)
549 b3994ec5 2003-12-11 devnull {
550 b3994ec5 2003-12-11 devnull int i, clean;
551 b3994ec5 2003-12-11 devnull
552 b3994ec5 2003-12-11 devnull clean = TRUE;
553 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
554 b3994ec5 2003-12-11 devnull clean &= winclean(c->w[i], TRUE);
555 b3994ec5 2003-12-11 devnull return clean;
556 b3994ec5 2003-12-11 devnull }