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