Introduction
Introduction Statistics Contact Development Disclaimer Help
flayer.c - sam - An updated version of the sam text editor.
git clone git://vernunftzentrum.de/sam.git
Log
Files
Refs
LICENSE
---
flayer.c (9842B)
---
1 /* Copyright (c) 1998 Lucent Technologies - All rights reserved. */
2 #include <u.h>
3 #include <libg.h>
4 #include <frame.h>
5 #include "flayer.h"
6 #include "samterm.h"
7
8 #define DELTA 10
9
10 static Flayer **llist; /* front to back */
11 static int nllist;
12 static int nlalloc;
13 static Rectangle lDrect;
14
15 extern Bitmap screen;
16 extern Mouse mouse;
17
18 extern uint64_t _bgpixel;
19
20 Vis visibility(Flayer *);
21 void newvisibilities(int);
22 void llinsert(Flayer*);
23 void lldelete(Flayer*);
24
25 void
26 flstart(Rectangle r)
27 {
28 lDrect = r;
29 }
30
31 void
32 flnew(Flayer *l, wchar_t *(*fn)(Flayer*, int64_t, uint64_t*), int u0, vo…
33 {
34 if(nllist == nlalloc){
35 nlalloc += DELTA;
36 llist = realloc(llist, nlalloc*sizeof(Flayer**));
37 if(llist == 0)
38 panic("flnew");
39 }
40 l->textfn = fn;
41 l->user0 = u0;
42 l->user1 = u1;
43 l->bg = _bgpixel;
44 llinsert(l);
45 }
46
47 Rectangle
48 flrect(Flayer *l, Rectangle r)
49 {
50 rectclip(&r, lDrect);
51 l->entire = r;
52 l->scroll = inset(r, FLMARGIN);
53 r.min.x =
54 l->scroll.max.x = r.min.x+FLMARGIN+FLSCROLLWID+(FLGAP-FLMARGIN);
55 return r;
56 }
57
58 void
59 flinit(Flayer *l, Rectangle r, XftFont *ft, uint64_t bg)
60 {
61 lldelete(l);
62 llinsert(l);
63 l->visible = All;
64 l->origin = l->p0 = l->p1 = 0;
65 frinit(&l->f, inset(flrect(l, r), FLMARGIN), ft, &screen, bg);
66 l->bg = bg;
67 newvisibilities(1);
68 bitblt2(&screen, l->entire.min, &screen, l->entire, 0, 0, l->bg);
69 scrdraw(l, 0L);
70 flborder(l, 0);
71 }
72
73 void
74 flclose(Flayer *l)
75 {
76 if(l->visible == All)
77 bitblt2(&screen, l->entire.min, &screen, l->entire, 0, _bgpixel,…
78 else if(l->visible == Some){
79 if(l->f.b == 0)
80 l->f.b = balloc(l->entire, screen.ldepth);
81 if(l->f.b){
82 bitblt2(l->f.b, l->entire.min, l->f.b, l->entire, 0, _bgpixe…
83 flrefresh(l, l->entire, 0);
84 }
85 }
86 frclear(&l->f);
87 lldelete(l);
88 if(l->f.b && l->visible!=All)
89 bfree(l->f.b);
90 l->textfn = 0;
91 newvisibilities(1);
92 }
93
94 void
95 flborder(Flayer *l, bool wide)
96 {
97 if(flprepare(l)){
98 border(l->f.b, l->entire, FLMARGIN, 0, l->bg);
99 border(l->f.b, l->entire, wide? FLMARGIN : 1, F&~D, l->bg);
100 if(l->visible==Some)
101 flrefresh(l, l->entire, 0);
102 }
103 }
104
105 Flayer *
106 flwhich(Point p)
107 {
108 int i;
109
110 if(p.x==0 && p.y==0)
111 return nllist? llist[0] : 0;
112 for(i=0; i<nllist; i++)
113 if(ptinrect(p, llist[i]->entire))
114 return llist[i];
115 return 0;
116 }
117
118 void
119 flupfront(Flayer *l)
120 {
121 int v = l->visible;
122
123 lldelete(l);
124 llinsert(l);
125 if(v!=All)
126 newvisibilities(0);
127 }
128
129 void
130 newvisibilities(int redraw)
131 /* if redraw false, we know it's a flupfront, and needn't
132 * redraw anyone becoming partially covered */
133 {
134 int i;
135 Vis ov;
136 Flayer *l;
137
138 for(i = 0; i<nllist; i++){
139 l = llist[i];
140 ov = l->visible;
141 l->visible = visibility(l);
142 #define V(a, b) (((a)<<2)|((b)))
143 switch(V(ov, l->visible)){
144 case V(Some, None):
145 if(l->f.b)
146 bfree(l->f.b);
147 case V(All, None):
148 case V(All, Some):
149 l->f.b = 0;
150 frclear(&l->f);
151 break;
152
153 case V(Some, Some):
154 if(l->f.b==0 && redraw)
155 case V(None, Some):
156 flprepare(l);
157 if(l->f.b && redraw){
158 flrefresh(l, l->entire, 0);
159 bfree(l->f.b);
160 l->f.b = 0;
161 frclear(&l->f);
162 }
163 case V(None, None):
164 case V(All, All):
165 break;
166
167 case V(Some, All):
168 if(l->f.b){
169 bitblt2(&screen, l->entire.min, l->f.b, l->entire, S, 0,…
170 bfree(l->f.b);
171 l->f.b = &screen;
172 break;
173 }
174 case V(None, All):
175 flprepare(l);
176 break;
177 }
178 if(ov==None && l->visible!=None)
179 flnewlyvisible(l);
180 }
181 }
182
183 void
184 llinsert(Flayer *l)
185 {
186 int i;
187 for(i=nllist; i>0; --i)
188 llist[i]=llist[i-1];
189 llist[0]=l;
190 nllist++;
191 }
192
193 void
194 lldelete(Flayer *l)
195 {
196 int i;
197
198 for(i=0; i<nllist; i++)
199 if(llist[i]==l){
200 --nllist;
201 for(; i<nllist; i++)
202 llist[i] = llist[i+1];
203 return;
204 }
205 panic("lldelete");
206 }
207
208 void
209 flinsert(Flayer *l, wchar_t *sp, wchar_t *ep, int64_t p0)
210 {
211 if(flprepare(l)){
212 frinsert(&l->f, sp, ep, p0-l->origin);
213 scrdraw(l, scrtotal(l));
214 if(l->visible==Some)
215 flrefresh(l, l->entire, 0);
216 }
217 }
218
219 void
220 fldelete(Flayer *l, int64_t p0, int64_t p1)
221 {
222 if(flprepare(l)){
223 p0 -= l->origin;
224 if(p0 < 0)
225 p0 = 0;
226 p1 -= l->origin;
227 if(p1<0)
228 p1 = 0;
229 frdelete(&l->f, p0, p1);
230 scrdraw(l, scrtotal(l));
231 if(l->visible==Some)
232 flrefresh(l, l->entire, 0);
233 }
234 }
235
236 bool
237 flselect(Flayer *l)
238 {
239 if(l->visible!=All)
240 flupfront(l);
241 if(mouse.msec-l->click<Clicktime && (l->f.p0 == l->f.p1 && l->f.p0 =…
242 l->click = 0;
243 return true;
244 }
245 frselect(&l->f, &mouse);
246 if(l->f.p0==l->f.p1)
247 l->click = mouse.msec;
248 else
249 l->click = 0;
250 l->p0 = l->f.p0+l->origin, l->p1 = l->f.p1+l->origin;
251 return false;
252 }
253
254 void
255 flsetselect(Flayer *l, int64_t p0, int64_t p1)
256 {
257 uint64_t fp0, fp1;
258
259 l->click = 0;
260 if(l->visible==None || !flprepare(l)){
261 l->p0 = p0, l->p1 = p1;
262 return;
263 }
264 l->p0 = p0, l->p1 = p1;
265 flfp0p1(l, &fp0, &fp1);
266 if(fp0==l->f.p0 && fp1==l->f.p1)
267 return;
268 frselectp(&l->f, F&~D);
269 l->f.p0 = fp0, l->f.p1 = fp1;
270 frselectp(&l->f, F&~D);
271 if(l->visible==Some)
272 flrefresh(l, l->entire, 0);
273 }
274
275 void
276 flfp0p1(Flayer *l, uint64_t *pp0, uint64_t *pp1)
277 {
278 int64_t p0 = l->p0-l->origin, p1 = l->p1-l->origin;
279
280 if(p0 < 0)
281 p0 = 0;
282 if(p1 < 0)
283 p1 = 0;
284 if(p0 > l->f.nchars)
285 p0 = l->f.nchars;
286 if(p1 > l->f.nchars)
287 p1 = l->f.nchars;
288 *pp0 = p0;
289 *pp1 = p1;
290 }
291
292 Rectangle
293 rscale(Rectangle r, Point old, Point new)
294 {
295 r.min.x = r.min.x*new.x/old.x;
296 r.min.y = r.min.y*new.y/old.y;
297 r.max.x = r.max.x*new.x/old.x;
298 r.max.y = r.max.y*new.y/old.y;
299 return r;
300 }
301
302 void
303 flreshape(Rectangle dr)
304 {
305 int i;
306 Flayer *l;
307 Frame *f;
308 Rectangle r, olDrect;
309 int move;
310
311 olDrect = lDrect;
312 lDrect = dr;
313 move = 0;
314 bitblt2(&screen, lDrect.min, &screen, lDrect, 0, 0, _bgpixel);
315
316 for(i=0; i<nllist; i++){
317 l = llist[i];
318 f = &l->f;
319 if(move)
320 r = raddp(rsubp(l->entire, olDrect.min), dr.min);
321 else{
322 r = raddp(rscale(rsubp(l->entire, olDrect.min),
323 sub(olDrect.max, olDrect.min),
324 sub(dr.max, dr.min)), dr.min);
325 if(l->visible==Some && f->b){
326 bfree(f->b);
327 frclear(f);
328 }
329 f->b = 0;
330 if(l->visible!=None)
331 frclear(f);
332 }
333 if(!rectclip(&r, dr))
334 panic("flreshape");
335 if(r.max.x-r.min.x<100)
336 r.min.x = dr.min.x;
337 if(r.max.x-r.min.x<100)
338 r.max.x = dr.max.x;
339 if(r.max.y-r.min.y<2*FLMARGIN+f->fheight)
340 r.min.y = dr.min.y;
341 if(r.max.y-r.min.y<2*FLMARGIN+f->fheight)
342 r.max.y = dr.max.y;
343 if(!move)
344 l->visible = None;
345 frsetrects(f, inset(flrect(l, r), FLMARGIN), f->b);
346 if(!move && f->b)
347 scrdraw(l, scrtotal(l));
348 }
349 newvisibilities(1);
350 }
351
352 int
353 flprepare(Flayer *l)
354 {
355 Frame *f;
356 uint64_t n;
357 wchar_t *r;
358
359 if(l->visible == None)
360 return 0;
361 f = &l->f;
362 if(f->b == 0){
363 if(l->visible == All)
364 f->b = &screen;
365 else if((f->b = balloc(l->entire, screen.ldepth))==0)
366 return 0;
367 bitblt2(f->b, l->entire.min, f->b, l->entire, 0, 0, l->bg);
368 border(f->b, l->entire, l==llist[0]? FLMARGIN : 1, F&~D, l->bg);
369 n = f->nchars;
370 frinit(f, f->entire, f->font, f->b, l->bg);
371 r = (*l->textfn)(l, n, &n);
372 frinsert(f, r, r+n, (uint64_t)0);
373 frselectp(f, F&~D);
374 flfp0p1(l, &l->f.p0, &l->f.p1);
375 frselectp(f, F&~D);
376 scrdraw(l, scrtotal(l));
377 }
378 return 1;
379 }
380
381 static bool somevis, someinvis, justvis;
382
383 Vis
384 visibility(Flayer *l)
385 {
386 somevis = someinvis = false;
387 justvis = true;
388 flrefresh(l, l->entire, 0);
389 justvis = false;
390 if(!somevis)
391 return None;
392 if(!someinvis)
393 return All;
394 return Some;
395 }
396
397 void
398 flrefresh(Flayer *l, Rectangle r, int i)
399 {
400 Flayer *t;
401 Rectangle s;
402
403 Top:
404 if((t=llist[i++]) == l){
405 if(!justvis)
406 bitblt2(&screen, r.min, l->f.b, r, S, 0, l->bg);
407 somevis = true;
408 }else{
409 if(!rectXrect(t->entire, r))
410 goto Top; /* avoid stacking unnecessarily */
411 if(t->entire.min.x>r.min.x){
412 s = r;
413 s.max.x = t->entire.min.x;
414 flrefresh(l, s, i);
415 r.min.x = t->entire.min.x;
416 }
417 if(t->entire.min.y>r.min.y){
418 s = r;
419 s.max.y = t->entire.min.y;
420 flrefresh(l, s, i);
421 r.min.y = t->entire.min.y;
422 }
423 if(t->entire.max.x<r.max.x){
424 s = r;
425 s.min.x = t->entire.max.x;
426 flrefresh(l, s, i);
427 r.max.x = t->entire.max.x;
428 }
429 if(t->entire.max.y<r.max.y){
430 s = r;
431 s.min.y = t->entire.max.y;
432 flrefresh(l, s, i);
433 r.max.y = t->entire.max.y;
434 }
435 /* remaining piece of r is blocked by t; forget about it */
436 someinvis = true;
437 }
438 }
You are viewing proxied material from vernunftzentrum.de. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.