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 67dbeee5 2017-10-10 rsc #include <libsec.h>
12 b3994ec5 2003-12-11 devnull #include "dat.h"
13 b3994ec5 2003-12-11 devnull #include "fns.h"
14 b3994ec5 2003-12-11 devnull
15 b3994ec5 2003-12-11 devnull static Rune Lheader[] = {
16 b3994ec5 2003-12-11 devnull 'N', 'e', 'w', ' ',
17 b3994ec5 2003-12-11 devnull 'C', 'u', 't', ' ',
18 b3994ec5 2003-12-11 devnull 'P', 'a', 's', 't', 'e', ' ',
19 b3994ec5 2003-12-11 devnull 'S', 'n', 'a', 'r', 'f', ' ',
20 b3994ec5 2003-12-11 devnull 'S', 'o', 'r', 't', ' ',
21 b3994ec5 2003-12-11 devnull 'Z', 'e', 'r', 'o', 'x', ' ',
22 b3994ec5 2003-12-11 devnull 'D', 'e', 'l', 'c', 'o', 'l', ' ',
23 b3994ec5 2003-12-11 devnull 0
24 b3994ec5 2003-12-11 devnull };
25 b3994ec5 2003-12-11 devnull
26 b3994ec5 2003-12-11 devnull void
27 b3994ec5 2003-12-11 devnull colinit(Column *c, Rectangle r)
28 b3994ec5 2003-12-11 devnull {
29 b3994ec5 2003-12-11 devnull Rectangle r1;
30 b3994ec5 2003-12-11 devnull Text *t;
31 b3994ec5 2003-12-11 devnull
32 b3994ec5 2003-12-11 devnull draw(screen, r, display->white, nil, ZP);
33 b3994ec5 2003-12-11 devnull c->r = r;
34 b3994ec5 2003-12-11 devnull c->w = nil;
35 b3994ec5 2003-12-11 devnull c->nw = 0;
36 b3994ec5 2003-12-11 devnull t = &c->tag;
37 b3994ec5 2003-12-11 devnull t->w = nil;
38 b3994ec5 2003-12-11 devnull t->col = c;
39 b3994ec5 2003-12-11 devnull r1 = r;
40 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y + font->height;
41 b3994ec5 2003-12-11 devnull textinit(t, fileaddtext(nil, t), r1, &reffont, tagcols);
42 b3994ec5 2003-12-11 devnull t->what = Columntag;
43 b3994ec5 2003-12-11 devnull r1.min.y = r1.max.y;
44 b3994ec5 2003-12-11 devnull r1.max.y += Border;
45 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
46 b3994ec5 2003-12-11 devnull textinsert(t, 0, Lheader, 38, TRUE);
47 b3994ec5 2003-12-11 devnull textsetselect(t, t->file->b.nc, t->file->b.nc);
48 b3994ec5 2003-12-11 devnull draw(screen, t->scrollr, colbutton, nil, colbutton->r.min);
49 b3994ec5 2003-12-11 devnull c->safe = TRUE;
50 b3994ec5 2003-12-11 devnull }
51 b3994ec5 2003-12-11 devnull
52 b3994ec5 2003-12-11 devnull Window*
53 b3994ec5 2003-12-11 devnull coladd(Column *c, Window *w, Window *clone, int y)
54 b3994ec5 2003-12-11 devnull {
55 b3994ec5 2003-12-11 devnull Rectangle r, r1;
56 b3994ec5 2003-12-11 devnull Window *v;
57 41636940 2008-03-07 rsc int i, j, minht, ymax, buggered;
58 b3994ec5 2003-12-11 devnull
59 b3994ec5 2003-12-11 devnull v = nil;
60 b3994ec5 2003-12-11 devnull r = c->r;
61 b3994ec5 2003-12-11 devnull r.min.y = c->tag.fr.r.max.y+Border;
62 b3994ec5 2003-12-11 devnull if(y<r.min.y && c->nw>0){ /* steal half of last window by default */
63 b3994ec5 2003-12-11 devnull v = c->w[c->nw-1];
64 b3994ec5 2003-12-11 devnull y = v->body.fr.r.min.y+Dy(v->body.fr.r)/2;
65 b3994ec5 2003-12-11 devnull }
66 b3994ec5 2003-12-11 devnull /* look for window we'll land on */
67 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
68 b3994ec5 2003-12-11 devnull v = c->w[i];
69 b3994ec5 2003-12-11 devnull if(y < v->r.max.y)
70 b3994ec5 2003-12-11 devnull break;
71 b3994ec5 2003-12-11 devnull }
72 41636940 2008-03-07 rsc buggered = 0;
73 b3994ec5 2003-12-11 devnull if(c->nw > 0){
74 b3994ec5 2003-12-11 devnull if(i < c->nw)
75 b3994ec5 2003-12-11 devnull i++; /* new window will go after v */
76 b3994ec5 2003-12-11 devnull /*
77 a2db69c8 2008-03-07 rsc * if landing window (v) is too small, grow it first.
78 b3994ec5 2003-12-11 devnull */
79 20ae0b0f 2005-12-16 devnull minht = v->tag.fr.font->height+Border+1;
80 20ae0b0f 2005-12-16 devnull j = 0;
81 20ae0b0f 2005-12-16 devnull while(!c->safe || v->body.fr.maxlines<=3 || Dy(v->body.all) <= minht){
82 20ae0b0f 2005-12-16 devnull if(++j > 10){
83 41636940 2008-03-07 rsc buggered = 1; /* too many windows in column */
84 20ae0b0f 2005-12-16 devnull break;
85 20ae0b0f 2005-12-16 devnull }
86 b3994ec5 2003-12-11 devnull colgrow(c, v, 1);
87 b3994ec5 2003-12-11 devnull }
88 a2db69c8 2008-03-07 rsc
89 a2db69c8 2008-03-07 rsc /*
90 a2db69c8 2008-03-07 rsc * figure out where to split v to make room for w
91 a2db69c8 2008-03-07 rsc */
92 fa325e9b 2020-01-10 cross
93 41636940 2008-03-07 rsc /* new window stops where next window begins */
94 41636940 2008-03-07 rsc if(i < c->nw)
95 a2db69c8 2008-03-07 rsc ymax = c->w[i]->r.min.y-Border;
96 41636940 2008-03-07 rsc else
97 41636940 2008-03-07 rsc ymax = c->r.max.y;
98 fa325e9b 2020-01-10 cross
99 41636940 2008-03-07 rsc /* new window must start after v's tag ends */
100 41636940 2008-03-07 rsc y = max(y, v->tagtop.max.y+Border);
101 fa325e9b 2020-01-10 cross
102 41636940 2008-03-07 rsc /* new window must start early enough to end before ymax */
103 a2db69c8 2008-03-07 rsc y = min(y, ymax - minht);
104 fa325e9b 2020-01-10 cross
105 41636940 2008-03-07 rsc /* if y is too small, too many windows in column */
106 41636940 2008-03-07 rsc if(y < v->tagtop.max.y+Border)
107 41636940 2008-03-07 rsc buggered = 1;
108 a2db69c8 2008-03-07 rsc
109 a2db69c8 2008-03-07 rsc /*
110 41636940 2008-03-07 rsc * resize & redraw v
111 a2db69c8 2008-03-07 rsc */
112 41636940 2008-03-07 rsc r = v->r;
113 41636940 2008-03-07 rsc r.max.y = ymax;
114 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
115 b3994ec5 2003-12-11 devnull r1 = r;
116 a2db69c8 2008-03-07 rsc y = min(y, ymax-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1));
117 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);
118 33dc4226 2005-10-31 devnull r1.min.y = winresize(v, r1, FALSE, FALSE);
119 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+Border;
120 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
121 fa325e9b 2020-01-10 cross
122 41636940 2008-03-07 rsc /*
123 41636940 2008-03-07 rsc * leave r with w's coordinates
124 41636940 2008-03-07 rsc */
125 b3994ec5 2003-12-11 devnull r.min.y = r1.max.y;
126 b3994ec5 2003-12-11 devnull }
127 b3994ec5 2003-12-11 devnull if(w == nil){
128 b3994ec5 2003-12-11 devnull w = emalloc(sizeof(Window));
129 b3994ec5 2003-12-11 devnull w->col = c;
130 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
131 b3994ec5 2003-12-11 devnull wininit(w, clone, r);
132 b3994ec5 2003-12-11 devnull }else{
133 b3994ec5 2003-12-11 devnull w->col = c;
134 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
135 b3994ec5 2003-12-11 devnull }
136 b3994ec5 2003-12-11 devnull w->tag.col = c;
137 b3994ec5 2003-12-11 devnull w->tag.row = c->row;
138 b3994ec5 2003-12-11 devnull w->body.col = c;
139 b3994ec5 2003-12-11 devnull w->body.row = c->row;
140 b3994ec5 2003-12-11 devnull c->w = realloc(c->w, (c->nw+1)*sizeof(Window*));
141 b3994ec5 2003-12-11 devnull memmove(c->w+i+1, c->w+i, (c->nw-i)*sizeof(Window*));
142 b3994ec5 2003-12-11 devnull c->nw++;
143 b3994ec5 2003-12-11 devnull c->w[i] = w;
144 41636940 2008-03-07 rsc c->safe = TRUE;
145 fa325e9b 2020-01-10 cross
146 41636940 2008-03-07 rsc /* if there were too many windows, redraw the whole column */
147 41636940 2008-03-07 rsc if(buggered)
148 41636940 2008-03-07 rsc colresize(c, c->r);
149 41636940 2008-03-07 rsc
150 b3994ec5 2003-12-11 devnull savemouse(w);
151 41636940 2008-03-07 rsc /* near the button, but in the body */
152 b3994ec5 2003-12-11 devnull moveto(mousectl, addpt(w->tag.scrollr.max, Pt(3, 3)));
153 b3994ec5 2003-12-11 devnull barttext = &w->body;
154 b3994ec5 2003-12-11 devnull return w;
155 b3994ec5 2003-12-11 devnull }
156 b3994ec5 2003-12-11 devnull
157 b3994ec5 2003-12-11 devnull void
158 b3994ec5 2003-12-11 devnull colclose(Column *c, Window *w, int dofree)
159 b3994ec5 2003-12-11 devnull {
160 b3994ec5 2003-12-11 devnull Rectangle r;
161 37f8ed24 2012-09-24 rsc int i, didmouse, up;
162 b3994ec5 2003-12-11 devnull
163 b3994ec5 2003-12-11 devnull /* w is locked */
164 b3994ec5 2003-12-11 devnull if(!c->safe)
165 b3994ec5 2003-12-11 devnull colgrow(c, w, 1);
166 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
167 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
168 b3994ec5 2003-12-11 devnull goto Found;
169 b3994ec5 2003-12-11 devnull error("can't find window");
170 b3994ec5 2003-12-11 devnull Found:
171 b3994ec5 2003-12-11 devnull r = w->r;
172 b3994ec5 2003-12-11 devnull w->tag.col = nil;
173 b3994ec5 2003-12-11 devnull w->body.col = nil;
174 b3994ec5 2003-12-11 devnull w->col = nil;
175 37f8ed24 2012-09-24 rsc didmouse = restoremouse(w);
176 b3994ec5 2003-12-11 devnull if(dofree){
177 b3994ec5 2003-12-11 devnull windelete(w);
178 b3994ec5 2003-12-11 devnull winclose(w);
179 b3994ec5 2003-12-11 devnull }
180 b3994ec5 2003-12-11 devnull c->nw--;
181 a2db69c8 2008-03-07 rsc memmove(c->w+i, c->w+i+1, (c->nw-i)*sizeof(Window*));
182 b3994ec5 2003-12-11 devnull c->w = realloc(c->w, c->nw*sizeof(Window*));
183 b3994ec5 2003-12-11 devnull if(c->nw == 0){
184 b3994ec5 2003-12-11 devnull draw(screen, r, display->white, nil, ZP);
185 b3994ec5 2003-12-11 devnull return;
186 b3994ec5 2003-12-11 devnull }
187 37f8ed24 2012-09-24 rsc up = 0;
188 b3994ec5 2003-12-11 devnull if(i == c->nw){ /* extend last window down */
189 b3994ec5 2003-12-11 devnull w = c->w[i-1];
190 b3994ec5 2003-12-11 devnull r.min.y = w->r.min.y;
191 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
192 b3994ec5 2003-12-11 devnull }else{ /* extend next window up */
193 37f8ed24 2012-09-24 rsc up = 1;
194 b3994ec5 2003-12-11 devnull w = c->w[i];
195 b3994ec5 2003-12-11 devnull r.max.y = w->r.max.y;
196 b3994ec5 2003-12-11 devnull }
197 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
198 37f8ed24 2012-09-24 rsc if(c->safe) {
199 37f8ed24 2012-09-24 rsc if(!didmouse && up)
200 37f8ed24 2012-09-24 rsc w->showdel = TRUE;
201 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
202 37f8ed24 2012-09-24 rsc if(!didmouse && up)
203 37f8ed24 2012-09-24 rsc movetodel(w);
204 37f8ed24 2012-09-24 rsc }
205 b3994ec5 2003-12-11 devnull }
206 b3994ec5 2003-12-11 devnull
207 b3994ec5 2003-12-11 devnull void
208 b3994ec5 2003-12-11 devnull colcloseall(Column *c)
209 b3994ec5 2003-12-11 devnull {
210 b3994ec5 2003-12-11 devnull int i;
211 b3994ec5 2003-12-11 devnull Window *w;
212 b3994ec5 2003-12-11 devnull
213 b3994ec5 2003-12-11 devnull if(c == activecol)
214 b3994ec5 2003-12-11 devnull activecol = nil;
215 b3994ec5 2003-12-11 devnull textclose(&c->tag);
216 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
217 b3994ec5 2003-12-11 devnull w = c->w[i];
218 b3994ec5 2003-12-11 devnull winclose(w);
219 b3994ec5 2003-12-11 devnull }
220 b3994ec5 2003-12-11 devnull c->nw = 0;
221 b3994ec5 2003-12-11 devnull free(c->w);
222 b3994ec5 2003-12-11 devnull free(c);
223 b3994ec5 2003-12-11 devnull clearmouse();
224 b3994ec5 2003-12-11 devnull }
225 b3994ec5 2003-12-11 devnull
226 b3994ec5 2003-12-11 devnull void
227 b3994ec5 2003-12-11 devnull colmousebut(Column *c)
228 b3994ec5 2003-12-11 devnull {
229 b3994ec5 2003-12-11 devnull moveto(mousectl, divpt(addpt(c->tag.scrollr.min, c->tag.scrollr.max), 2));
230 b3994ec5 2003-12-11 devnull }
231 b3994ec5 2003-12-11 devnull
232 b3994ec5 2003-12-11 devnull void
233 b3994ec5 2003-12-11 devnull colresize(Column *c, Rectangle r)
234 b3994ec5 2003-12-11 devnull {
235 4650064a 2020-03-30 rsc int i, old, new;
236 b3994ec5 2003-12-11 devnull Rectangle r1, r2;
237 b3994ec5 2003-12-11 devnull Window *w;
238 b3994ec5 2003-12-11 devnull
239 b3994ec5 2003-12-11 devnull clearmouse();
240 b3994ec5 2003-12-11 devnull r1 = r;
241 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y + c->tag.fr.font->height;
242 33dc4226 2005-10-31 devnull textresize(&c->tag, r1, TRUE);
243 b3994ec5 2003-12-11 devnull draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
244 b3994ec5 2003-12-11 devnull r1.min.y = r1.max.y;
245 b3994ec5 2003-12-11 devnull r1.max.y += Border;
246 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
247 b3994ec5 2003-12-11 devnull r1.max.y = r.max.y;
248 4650064a 2020-03-30 rsc new = Dy(r) - c->nw*(Border + font->height);
249 4650064a 2020-03-30 rsc old = Dy(c->r) - c->nw*(Border + font->height);
250 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
251 b3994ec5 2003-12-11 devnull w = c->w[i];
252 b3994ec5 2003-12-11 devnull w->maxlines = 0;
253 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
254 b3994ec5 2003-12-11 devnull r1.max.y = r.max.y;
255 76b9347a 2018-11-14 rsc else{
256 76b9347a 2018-11-14 rsc r1.max.y = r1.min.y;
257 4650064a 2020-03-30 rsc if(new > 0 && old > 0 && Dy(w->r) > Border+font->height){
258 4650064a 2020-03-30 rsc r1.max.y += (Dy(w->r)-Border-font->height)*new/old + Border + font->height;
259 76b9347a 2018-11-14 rsc }
260 76b9347a 2018-11-14 rsc }
261 a2db69c8 2008-03-07 rsc r1.max.y = max(r1.max.y, r1.min.y + Border+font->height);
262 b3994ec5 2003-12-11 devnull r2 = r1;
263 b3994ec5 2003-12-11 devnull r2.max.y = r2.min.y+Border;
264 b3994ec5 2003-12-11 devnull draw(screen, r2, display->black, nil, ZP);
265 b3994ec5 2003-12-11 devnull r1.min.y = r2.max.y;
266 33dc4226 2005-10-31 devnull r1.min.y = winresize(w, r1, FALSE, i==c->nw-1);
267 b3994ec5 2003-12-11 devnull }
268 b3994ec5 2003-12-11 devnull c->r = r;
269 b3994ec5 2003-12-11 devnull }
270 b3994ec5 2003-12-11 devnull
271 b3994ec5 2003-12-11 devnull static
272 b3994ec5 2003-12-11 devnull int
273 b3994ec5 2003-12-11 devnull colcmp(const void *a, const void *b)
274 b3994ec5 2003-12-11 devnull {
275 b3994ec5 2003-12-11 devnull Rune *r1, *r2;
276 b3994ec5 2003-12-11 devnull int i, nr1, nr2;
277 b3994ec5 2003-12-11 devnull
278 b3994ec5 2003-12-11 devnull r1 = (*(Window**)a)->body.file->name;
279 b3994ec5 2003-12-11 devnull nr1 = (*(Window**)a)->body.file->nname;
280 b3994ec5 2003-12-11 devnull r2 = (*(Window**)b)->body.file->name;
281 b3994ec5 2003-12-11 devnull nr2 = (*(Window**)b)->body.file->nname;
282 b3994ec5 2003-12-11 devnull for(i=0; i<nr1 && i<nr2; i++){
283 b3994ec5 2003-12-11 devnull if(*r1 != *r2)
284 b3994ec5 2003-12-11 devnull return *r1-*r2;
285 b3994ec5 2003-12-11 devnull r1++;
286 b3994ec5 2003-12-11 devnull r2++;
287 b3994ec5 2003-12-11 devnull }
288 b3994ec5 2003-12-11 devnull return nr1-nr2;
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 colsort(Column *c)
293 b3994ec5 2003-12-11 devnull {
294 b3994ec5 2003-12-11 devnull int i, y;
295 b3994ec5 2003-12-11 devnull Rectangle r, r1, *rp;
296 b3994ec5 2003-12-11 devnull Window **wp, *w;
297 b3994ec5 2003-12-11 devnull
298 b3994ec5 2003-12-11 devnull if(c->nw == 0)
299 b3994ec5 2003-12-11 devnull return;
300 b3994ec5 2003-12-11 devnull clearmouse();
301 b3994ec5 2003-12-11 devnull rp = emalloc(c->nw*sizeof(Rectangle));
302 b3994ec5 2003-12-11 devnull wp = emalloc(c->nw*sizeof(Window*));
303 b3994ec5 2003-12-11 devnull memmove(wp, c->w, c->nw*sizeof(Window*));
304 b3994ec5 2003-12-11 devnull qsort(wp, c->nw, sizeof(Window*), colcmp);
305 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
306 b3994ec5 2003-12-11 devnull rp[i] = wp[i]->r;
307 b3994ec5 2003-12-11 devnull r = c->r;
308 b3994ec5 2003-12-11 devnull r.min.y = c->tag.fr.r.max.y;
309 b3994ec5 2003-12-11 devnull draw(screen, r, textcols[BACK], nil, ZP);
310 b3994ec5 2003-12-11 devnull y = r.min.y;
311 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
312 b3994ec5 2003-12-11 devnull w = wp[i];
313 b3994ec5 2003-12-11 devnull r.min.y = y;
314 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
315 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
316 b3994ec5 2003-12-11 devnull else
317 b3994ec5 2003-12-11 devnull r.max.y = r.min.y+Dy(w->r)+Border;
318 b3994ec5 2003-12-11 devnull r1 = r;
319 b3994ec5 2003-12-11 devnull r1.max.y = r1.min.y+Border;
320 b3994ec5 2003-12-11 devnull draw(screen, r1, display->black, nil, ZP);
321 b3994ec5 2003-12-11 devnull r.min.y = r1.max.y;
322 d5233ccb 2005-10-31 devnull y = winresize(w, r, FALSE, i==c->nw-1);
323 b3994ec5 2003-12-11 devnull }
324 b3994ec5 2003-12-11 devnull free(rp);
325 b3994ec5 2003-12-11 devnull free(c->w);
326 b3994ec5 2003-12-11 devnull c->w = wp;
327 b3994ec5 2003-12-11 devnull }
328 b3994ec5 2003-12-11 devnull
329 b3994ec5 2003-12-11 devnull void
330 b3994ec5 2003-12-11 devnull colgrow(Column *c, Window *w, int but)
331 b3994ec5 2003-12-11 devnull {
332 b3994ec5 2003-12-11 devnull Rectangle r, cr;
333 b3994ec5 2003-12-11 devnull int i, j, k, l, y1, y2, *nl, *ny, tot, nnl, onl, dnl, h;
334 b3994ec5 2003-12-11 devnull Window *v;
335 b3994ec5 2003-12-11 devnull
336 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
337 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
338 b3994ec5 2003-12-11 devnull goto Found;
339 b3994ec5 2003-12-11 devnull error("can't find window");
340 b3994ec5 2003-12-11 devnull
341 b3994ec5 2003-12-11 devnull Found:
342 b3994ec5 2003-12-11 devnull cr = c->r;
343 b3994ec5 2003-12-11 devnull if(but < 0){ /* make sure window fills its own space properly */
344 b3994ec5 2003-12-11 devnull r = w->r;
345 b3994ec5 2003-12-11 devnull if(i==c->nw-1 || c->safe==FALSE)
346 b3994ec5 2003-12-11 devnull r.max.y = cr.max.y;
347 b3994ec5 2003-12-11 devnull else
348 a2db69c8 2008-03-07 rsc r.max.y = c->w[i+1]->r.min.y - Border;
349 33dc4226 2005-10-31 devnull winresize(w, r, FALSE, TRUE);
350 b3994ec5 2003-12-11 devnull return;
351 b3994ec5 2003-12-11 devnull }
352 b3994ec5 2003-12-11 devnull cr.min.y = c->w[0]->r.min.y;
353 b3994ec5 2003-12-11 devnull if(but == 3){ /* full size */
354 b3994ec5 2003-12-11 devnull if(i != 0){
355 b3994ec5 2003-12-11 devnull v = c->w[0];
356 b3994ec5 2003-12-11 devnull c->w[0] = w;
357 b3994ec5 2003-12-11 devnull c->w[i] = v;
358 b3994ec5 2003-12-11 devnull }
359 b3994ec5 2003-12-11 devnull draw(screen, cr, textcols[BACK], nil, ZP);
360 33dc4226 2005-10-31 devnull winresize(w, cr, FALSE, TRUE);
361 b3994ec5 2003-12-11 devnull for(i=1; i<c->nw; i++)
362 b3994ec5 2003-12-11 devnull c->w[i]->body.fr.maxlines = 0;
363 b3994ec5 2003-12-11 devnull c->safe = FALSE;
364 b3994ec5 2003-12-11 devnull return;
365 b3994ec5 2003-12-11 devnull }
366 b3994ec5 2003-12-11 devnull /* store old #lines for each window */
367 b3994ec5 2003-12-11 devnull onl = w->body.fr.maxlines;
368 b3994ec5 2003-12-11 devnull nl = emalloc(c->nw * sizeof(int));
369 b3994ec5 2003-12-11 devnull ny = emalloc(c->nw * sizeof(int));
370 b3994ec5 2003-12-11 devnull tot = 0;
371 b3994ec5 2003-12-11 devnull for(j=0; j<c->nw; j++){
372 33dc4226 2005-10-31 devnull l = c->w[j]->taglines-1 + c->w[j]->body.fr.maxlines;
373 b3994ec5 2003-12-11 devnull nl[j] = l;
374 b3994ec5 2003-12-11 devnull tot += l;
375 b3994ec5 2003-12-11 devnull }
376 b3994ec5 2003-12-11 devnull /* approximate new #lines for this window */
377 b3994ec5 2003-12-11 devnull if(but == 2){ /* as big as can be */
378 b3994ec5 2003-12-11 devnull memset(nl, 0, c->nw * sizeof(int));
379 b3994ec5 2003-12-11 devnull goto Pack;
380 b3994ec5 2003-12-11 devnull }
381 33dc4226 2005-10-31 devnull nnl = min(onl + max(min(5, w->taglines-1+w->maxlines), onl/2), tot);
382 33dc4226 2005-10-31 devnull if(nnl < w->taglines-1+w->maxlines)
383 a2db69c8 2008-03-07 rsc nnl = (w->taglines-1+w->maxlines + nnl)/2;
384 b3994ec5 2003-12-11 devnull if(nnl == 0)
385 b3994ec5 2003-12-11 devnull nnl = 2;
386 b3994ec5 2003-12-11 devnull dnl = nnl - onl;
387 b3994ec5 2003-12-11 devnull /* compute new #lines for each window */
388 b3994ec5 2003-12-11 devnull for(k=1; k<c->nw; k++){
389 b3994ec5 2003-12-11 devnull /* prune from later window */
390 b3994ec5 2003-12-11 devnull j = i+k;
391 b3994ec5 2003-12-11 devnull if(j<c->nw && nl[j]){
392 b3994ec5 2003-12-11 devnull l = min(dnl, max(1, nl[j]/2));
393 b3994ec5 2003-12-11 devnull nl[j] -= l;
394 b3994ec5 2003-12-11 devnull nl[i] += l;
395 b3994ec5 2003-12-11 devnull dnl -= l;
396 b3994ec5 2003-12-11 devnull }
397 b3994ec5 2003-12-11 devnull /* prune from earlier window */
398 b3994ec5 2003-12-11 devnull j = i-k;
399 b3994ec5 2003-12-11 devnull if(j>=0 && nl[j]){
400 b3994ec5 2003-12-11 devnull l = min(dnl, max(1, nl[j]/2));
401 b3994ec5 2003-12-11 devnull nl[j] -= l;
402 b3994ec5 2003-12-11 devnull nl[i] += l;
403 b3994ec5 2003-12-11 devnull dnl -= l;
404 b3994ec5 2003-12-11 devnull }
405 b3994ec5 2003-12-11 devnull }
406 b3994ec5 2003-12-11 devnull Pack:
407 b3994ec5 2003-12-11 devnull /* pack everyone above */
408 b3994ec5 2003-12-11 devnull y1 = cr.min.y;
409 b3994ec5 2003-12-11 devnull for(j=0; j<i; j++){
410 b3994ec5 2003-12-11 devnull v = c->w[j];
411 b3994ec5 2003-12-11 devnull r = v->r;
412 b3994ec5 2003-12-11 devnull r.min.y = y1;
413 33dc4226 2005-10-31 devnull r.max.y = y1+Dy(v->tagtop);
414 b3994ec5 2003-12-11 devnull if(nl[j])
415 b3994ec5 2003-12-11 devnull r.max.y += 1 + nl[j]*v->body.fr.font->height;
416 33dc4226 2005-10-31 devnull r.min.y = winresize(v, r, c->safe, FALSE);
417 b3994ec5 2003-12-11 devnull r.max.y += Border;
418 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
419 b3994ec5 2003-12-11 devnull y1 = r.max.y;
420 b3994ec5 2003-12-11 devnull }
421 b3994ec5 2003-12-11 devnull /* scan to see new size of everyone below */
422 b3994ec5 2003-12-11 devnull y2 = c->r.max.y;
423 b3994ec5 2003-12-11 devnull for(j=c->nw-1; j>i; j--){
424 b3994ec5 2003-12-11 devnull v = c->w[j];
425 b3994ec5 2003-12-11 devnull r = v->r;
426 33dc4226 2005-10-31 devnull r.min.y = y2-Dy(v->tagtop);
427 b3994ec5 2003-12-11 devnull if(nl[j])
428 b3994ec5 2003-12-11 devnull r.min.y -= 1 + nl[j]*v->body.fr.font->height;
429 b3994ec5 2003-12-11 devnull r.min.y -= Border;
430 b3994ec5 2003-12-11 devnull ny[j] = r.min.y;
431 b3994ec5 2003-12-11 devnull y2 = r.min.y;
432 b3994ec5 2003-12-11 devnull }
433 b3994ec5 2003-12-11 devnull /* compute new size of window */
434 b3994ec5 2003-12-11 devnull r = w->r;
435 b3994ec5 2003-12-11 devnull r.min.y = y1;
436 33dc4226 2005-10-31 devnull r.max.y = y2;
437 b3994ec5 2003-12-11 devnull h = w->body.fr.font->height;
438 33dc4226 2005-10-31 devnull if(Dy(r) < Dy(w->tagtop)+1+h+Border)
439 d5233ccb 2005-10-31 devnull r.max.y = r.min.y + Dy(w->tagtop)+1+h+Border;
440 b3994ec5 2003-12-11 devnull /* draw window */
441 41636940 2008-03-07 rsc r.max.y = winresize(w, r, c->safe, TRUE);
442 b3994ec5 2003-12-11 devnull if(i < c->nw-1){
443 b3994ec5 2003-12-11 devnull r.min.y = r.max.y;
444 b3994ec5 2003-12-11 devnull r.max.y += Border;
445 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
446 b3994ec5 2003-12-11 devnull for(j=i+1; j<c->nw; j++)
447 b3994ec5 2003-12-11 devnull ny[j] -= (y2-r.max.y);
448 b3994ec5 2003-12-11 devnull }
449 b3994ec5 2003-12-11 devnull /* pack everyone below */
450 b3994ec5 2003-12-11 devnull y1 = r.max.y;
451 b3994ec5 2003-12-11 devnull for(j=i+1; j<c->nw; j++){
452 b3994ec5 2003-12-11 devnull v = c->w[j];
453 b3994ec5 2003-12-11 devnull r = v->r;
454 b3994ec5 2003-12-11 devnull r.min.y = y1;
455 d5233ccb 2005-10-31 devnull r.max.y = y1+Dy(v->tagtop);
456 b3994ec5 2003-12-11 devnull if(nl[j])
457 b3994ec5 2003-12-11 devnull r.max.y += 1 + nl[j]*v->body.fr.font->height;
458 a2db69c8 2008-03-07 rsc y1 = winresize(v, r, c->safe, j==c->nw-1);
459 b3994ec5 2003-12-11 devnull if(j < c->nw-1){ /* no border on last window */
460 33dc4226 2005-10-31 devnull r.min.y = y1;
461 b3994ec5 2003-12-11 devnull r.max.y += Border;
462 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
463 33dc4226 2005-10-31 devnull y1 = r.max.y;
464 b3994ec5 2003-12-11 devnull }
465 b3994ec5 2003-12-11 devnull }
466 b3994ec5 2003-12-11 devnull free(nl);
467 b3994ec5 2003-12-11 devnull free(ny);
468 b3994ec5 2003-12-11 devnull c->safe = TRUE;
469 b3994ec5 2003-12-11 devnull winmousebut(w);
470 b3994ec5 2003-12-11 devnull }
471 b3994ec5 2003-12-11 devnull
472 b3994ec5 2003-12-11 devnull void
473 b3994ec5 2003-12-11 devnull coldragwin(Column *c, Window *w, int but)
474 b3994ec5 2003-12-11 devnull {
475 b3994ec5 2003-12-11 devnull Rectangle r;
476 b3994ec5 2003-12-11 devnull int i, b;
477 b3994ec5 2003-12-11 devnull Point p, op;
478 b3994ec5 2003-12-11 devnull Window *v;
479 b3994ec5 2003-12-11 devnull Column *nc;
480 b3994ec5 2003-12-11 devnull
481 b3994ec5 2003-12-11 devnull clearmouse();
482 43b0d532 2018-11-16 rsc setcursor2(mousectl, &boxcursor, &boxcursor2);
483 b3994ec5 2003-12-11 devnull b = mouse->buttons;
484 b3994ec5 2003-12-11 devnull op = mouse->xy;
485 b3994ec5 2003-12-11 devnull while(mouse->buttons == b)
486 b3994ec5 2003-12-11 devnull readmouse(mousectl);
487 b3994ec5 2003-12-11 devnull setcursor(mousectl, nil);
488 b3994ec5 2003-12-11 devnull if(mouse->buttons){
489 b3994ec5 2003-12-11 devnull while(mouse->buttons)
490 b3994ec5 2003-12-11 devnull readmouse(mousectl);
491 b3994ec5 2003-12-11 devnull return;
492 b3994ec5 2003-12-11 devnull }
493 b3994ec5 2003-12-11 devnull
494 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
495 b3994ec5 2003-12-11 devnull if(c->w[i] == w)
496 b3994ec5 2003-12-11 devnull goto Found;
497 b3994ec5 2003-12-11 devnull error("can't find window");
498 b3994ec5 2003-12-11 devnull
499 b3994ec5 2003-12-11 devnull Found:
500 a2db69c8 2008-03-07 rsc if(w->tagexpand) /* force recomputation of window tag size */
501 a2db69c8 2008-03-07 rsc w->taglines = 1;
502 b3994ec5 2003-12-11 devnull p = mouse->xy;
503 b3994ec5 2003-12-11 devnull if(abs(p.x-op.x)<5 && abs(p.y-op.y)<5){
504 b3994ec5 2003-12-11 devnull colgrow(c, w, but);
505 b3994ec5 2003-12-11 devnull winmousebut(w);
506 b3994ec5 2003-12-11 devnull return;
507 b3994ec5 2003-12-11 devnull }
508 b3994ec5 2003-12-11 devnull /* is it a flick to the right? */
509 b3994ec5 2003-12-11 devnull if(abs(p.y-op.y)<10 && p.x>op.x+30 && rowwhichcol(c->row, p)==c)
510 4da83e7c 2004-03-05 devnull p.x = op.x+Dx(w->r); /* yes: toss to next column */
511 b3994ec5 2003-12-11 devnull nc = rowwhichcol(c->row, p);
512 b3994ec5 2003-12-11 devnull if(nc!=nil && nc!=c){
513 b3994ec5 2003-12-11 devnull colclose(c, w, FALSE);
514 b3994ec5 2003-12-11 devnull coladd(nc, w, nil, p.y);
515 b3994ec5 2003-12-11 devnull winmousebut(w);
516 b3994ec5 2003-12-11 devnull return;
517 b3994ec5 2003-12-11 devnull }
518 b3994ec5 2003-12-11 devnull if(i==0 && c->nw==1)
519 b3994ec5 2003-12-11 devnull return; /* can't do it */
520 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)
521 b3994ec5 2003-12-11 devnull || (i==0 && p.y>w->r.max.y)){
522 b3994ec5 2003-12-11 devnull /* shuffle */
523 b3994ec5 2003-12-11 devnull colclose(c, w, FALSE);
524 b3994ec5 2003-12-11 devnull coladd(c, w, nil, p.y);
525 b3994ec5 2003-12-11 devnull winmousebut(w);
526 b3994ec5 2003-12-11 devnull return;
527 b3994ec5 2003-12-11 devnull }
528 b3994ec5 2003-12-11 devnull if(i == 0)
529 b3994ec5 2003-12-11 devnull return;
530 b3994ec5 2003-12-11 devnull v = c->w[i-1];
531 33dc4226 2005-10-31 devnull if(p.y < v->tagtop.max.y)
532 33dc4226 2005-10-31 devnull p.y = v->tagtop.max.y;
533 33dc4226 2005-10-31 devnull if(p.y > w->r.max.y-Dy(w->tagtop)-Border)
534 33dc4226 2005-10-31 devnull p.y = w->r.max.y-Dy(w->tagtop)-Border;
535 b3994ec5 2003-12-11 devnull r = v->r;
536 b3994ec5 2003-12-11 devnull r.max.y = p.y;
537 b3994ec5 2003-12-11 devnull if(r.max.y > v->body.fr.r.min.y){
538 b3994ec5 2003-12-11 devnull r.max.y -= (r.max.y-v->body.fr.r.min.y)%v->body.fr.font->height;
539 b3994ec5 2003-12-11 devnull if(v->body.fr.r.min.y == v->body.fr.r.max.y)
540 b3994ec5 2003-12-11 devnull r.max.y++;
541 b3994ec5 2003-12-11 devnull }
542 33dc4226 2005-10-31 devnull r.min.y = winresize(v, r, c->safe, FALSE);
543 b3994ec5 2003-12-11 devnull r.max.y = r.min.y+Border;
544 b3994ec5 2003-12-11 devnull draw(screen, r, display->black, nil, ZP);
545 b3994ec5 2003-12-11 devnull r.min.y = r.max.y;
546 b3994ec5 2003-12-11 devnull if(i == c->nw-1)
547 b3994ec5 2003-12-11 devnull r.max.y = c->r.max.y;
548 b3994ec5 2003-12-11 devnull else
549 b3994ec5 2003-12-11 devnull r.max.y = c->w[i+1]->r.min.y-Border;
550 2d23eb93 2006-01-12 devnull winresize(w, r, c->safe, TRUE);
551 b3994ec5 2003-12-11 devnull c->safe = TRUE;
552 37f8ed24 2012-09-24 rsc winmousebut(w);
553 b3994ec5 2003-12-11 devnull }
554 b3994ec5 2003-12-11 devnull
555 b3994ec5 2003-12-11 devnull Text*
556 b3994ec5 2003-12-11 devnull colwhich(Column *c, Point p)
557 b3994ec5 2003-12-11 devnull {
558 b3994ec5 2003-12-11 devnull int i;
559 b3994ec5 2003-12-11 devnull Window *w;
560 b3994ec5 2003-12-11 devnull
561 b3994ec5 2003-12-11 devnull if(!ptinrect(p, c->r))
562 b3994ec5 2003-12-11 devnull return nil;
563 b3994ec5 2003-12-11 devnull if(ptinrect(p, c->tag.all))
564 b3994ec5 2003-12-11 devnull return &c->tag;
565 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++){
566 b3994ec5 2003-12-11 devnull w = c->w[i];
567 b3994ec5 2003-12-11 devnull if(ptinrect(p, w->r)){
568 83ab7d88 2007-11-27 rsc if(ptinrect(p, w->tagtop) || ptinrect(p, w->tag.all))
569 b3994ec5 2003-12-11 devnull return &w->tag;
570 83ab7d88 2007-11-27 rsc /* exclude partial line at bottom */
571 83ab7d88 2007-11-27 rsc if(p.x >= w->body.scrollr.max.x && p.y >= w->body.fr.r.max.y)
572 83ab7d88 2007-11-27 rsc return nil;
573 83ab7d88 2007-11-27 rsc return &w->body;
574 b3994ec5 2003-12-11 devnull }
575 b3994ec5 2003-12-11 devnull }
576 b3994ec5 2003-12-11 devnull return nil;
577 b3994ec5 2003-12-11 devnull }
578 b3994ec5 2003-12-11 devnull
579 b3994ec5 2003-12-11 devnull int
580 b3994ec5 2003-12-11 devnull colclean(Column *c)
581 b3994ec5 2003-12-11 devnull {
582 b3994ec5 2003-12-11 devnull int i, clean;
583 b3994ec5 2003-12-11 devnull
584 b3994ec5 2003-12-11 devnull clean = TRUE;
585 b3994ec5 2003-12-11 devnull for(i=0; i<c->nw; i++)
586 b3994ec5 2003-12-11 devnull clean &= winclean(c->w[i], TRUE);
587 b3994ec5 2003-12-11 devnull return clean;
588 b3994ec5 2003-12-11 devnull }