scroll.c - sam - An updated version of the sam text editor.
(HTM) git clone git://vernunftzentrum.de/sam.git
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) LICENSE
---
scroll.c (3657B)
---
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 extern Bitmap *darkgrey;
9 extern Mouse mouse;
10
11 Rectangle
12 scrpos(Rectangle r, int64_t p0, int64_t p1, int64_t tot)
13 {
14 int64_t h;
15 Rectangle q;
16
17 q = inset(r, 1);
18 h = q.max.y-q.min.y;
19 if(tot == 0)
20 return q;
21 if(tot > 1024L*1024L)
22 tot>>=10, p0>>=10, p1>>=10;
23 if(p0 > 0)
24 q.min.y += h*p0/tot;
25 if(p1 < tot)
26 q.max.y -= h*(tot-p1)/tot;
27 if(q.max.y < q.min.y+2){
28 if(q.min.y+2 <= r.max.y)
29 q.max.y = q.min.y+2;
30 else
31 q.min.y = q.max.y-2;
32 }
33 return q;
34 }
35
36 void
37 scrflip(Flayer *l, Rectangle r)
38 {
39 if(rectclip(&r, l->scroll))
40 bitblt2(l->f.b, r.min, l->f.b, r, F&~D, 0, l->bg);
41 }
42
43 void
44 scrdraw(Flayer *l, int64_t tot)
45 {
46 Rectangle r, r1, r2;
47 Bitmap *b;
48 static Bitmap *x;
49 int h;
50
51 if(l->f.b == 0)
52 panic("scrdraw");
53 r = l->scroll;
54 r.min.x += 1; /* border between margin and bar */
55 r1 = r;
56 if(l->visible == All){
57 if(x == 0){
58 if (screensize(0, &h) == 0)
59 h = 2048;
60 x = balloc(Rect(0, 0, 32, h), l->f.b->ldepth);
61 if(x == 0)
62 panic("scrdraw balloc");
63 }
64 b = x;
65 r1.min.x = 0;
66 r1.max.x = Dx(r);
67 }else
68 b = l->f.b;
69 bitblt2(b, r1.min, b, r1, F, 0, l->bg);
70 texture(b, inset(r1, 1), darkgrey, S);
71 r2 = scrpos(r1, l->origin, l->origin+l->f.nchars, tot);
72 bitblt2(b, r2.min, b, r2, 0, 0, l->bg);
73 if(b!=l->f.b)
74 bitblt2(l->f.b, r.min, b, r1, S, 0, l->bg);
75 }
76
77 void
78 scroll(Flayer *l, int pbut, int but)
79 {
80 int in = 0, oin;
81 int64_t tot = scrtotal(l);
82 Rectangle scr, r, s, rt;
83 int x, y, my, oy, h;
84 int64_t p0;
85
86 s = inset(l->scroll, 1);
87 x = s.min.x+FLSCROLLWID/2;
88 scr = scrpos(l->scroll, l->origin, l->origin+l->f.nchars, tot);
89 r = scr;
90 y = scr.min.y;
91 my = mouse.xy.y;
92 do{
93 oin = in;
94 in = abs(x-mouse.xy.x)<=FLSCROLLWID/2;
95 if(oin != in)
96 scrflip(l, r);
97 if(in){
98 oy = y;
99 my = mouse.xy.y;
100 if(my < s.min.y)
101 my = s.min.y;
102 if(my >= s.max.y)
103 my = s.max.y;
104 if(!eqpt(mouse.xy, Pt(x, my)))
105 cursorset(Pt(x, my));
106 if(but == 1){
107 p0 = l->origin-frcharofpt(&l->f, Pt(s.max.x, my));
108 rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
109 y = rt.min.y;
110 }else if(but == 2){
111 y = my;
112 if(y > s.max.y-2)
113 y = s.max.y-2;
114 }else if(but == 3){
115 p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
116 rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
117 y = rt.min.y;
118 }
119 if(y != oy){
120 scrflip(l, r);
121 r = raddp(scr, Pt(0, y-scr.min.y));
122 scrflip(l, r);
123 }
124 }
125 }while(button(pbut));
126 if(in){
127 h = s.max.y-s.min.y;
128 scrflip(l, r);
129 p0 = 0;
130 if(but == 1)
131 p0 = (int64_t)(my-s.min.y)/l->f.fheight+1;
132 else if(but == 2){
133 if(tot > 1024L*1024L)
134 p0 = ((tot>>10)*(y-s.min.y)/h)<<10;
135 else
136 p0 = tot*(y-s.min.y)/h;
137 }else if(but == 3){
138 p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
139 if(p0 > tot)
140 p0 = tot;
141 }
142 scrorigin(l, but, p0);
143 }
144 }