1 #include <u.h> 2 #include <libc.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, long p0, long p1, long tot) 13 { 14 long 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 bitblt(l->f.b, r.min, l->f.b, r, F&~D); 41 } 42 43 void 44 scrdraw(Flayer *l, long 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 bitblt(b, r1.min, b, r1, F); 70 texture(b, inset(r1, 1), darkgrey, S); 71 r2 = scrpos(r1, l->origin, l->origin+l->f.nchars, tot); 72 bitblt(b, r2.min, b, r2, 0); 73 if(b!=l->f.b) 74 bitblt(l->f.b, r.min, b, r1, S); 75 } 76 77 void 78 scroll(Flayer *l, int but) 79 { 80 int in = 0, oin; 81 long tot = scrtotal(l); 82 Rectangle scr, r, s, rt; 83 int x, y, my, oy, h; 84 long 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(but)); 126 if(in){ 127 h = s.max.y-s.min.y; 128 scrflip(l, r); 129 p0 = 0; 130 if(but == 1) 131 p0 = (long)(my-s.min.y)/l->f.font->height+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 } 145