URI:
       tscroll.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tscroll.c (3328B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <draw.h>
            4 #include <thread.h>
            5 #include <mouse.h>
            6 #include <cursor.h>
            7 #include <keyboard.h>
            8 #include <frame.h>
            9 #include "flayer.h"
           10 #include "samterm.h"
           11 
           12 static Image *scrtmp;
           13 static Image *scrback;
           14 
           15 void
           16 scrtemps(void)
           17 {
           18         int h;
           19 
           20         if(scrtmp)
           21                 return;
           22         if(screensize(0, &h) == 0)
           23                 h = 2048;
           24         scrtmp = allocimage(display, Rect(0, 0, 32, h), screen->chan, 0, 0);
           25         scrback = allocimage(display, Rect(0, 0, 32, h), screen->chan, 0, 0);
           26         if(scrtmp==0 || scrback==0)
           27                 panic("scrtemps");
           28 }
           29 
           30 Rectangle
           31 scrpos(Rectangle r, long p0, long p1, long tot)
           32 {
           33         Rectangle q;
           34         int h;
           35 
           36         q = r;
           37         h = q.max.y-q.min.y;
           38         if(tot == 0)
           39                 return q;
           40         if(tot > 1024L*1024L)
           41                 tot>>=10, p0>>=10, p1>>=10;
           42         if(p0 > 0)
           43                 q.min.y += h*p0/tot;
           44         if(p1 < tot)
           45                 q.max.y -= h*(tot-p1)/tot;
           46         if(q.max.y < q.min.y+2){
           47                 if(q.min.y+2 <= r.max.y)
           48                         q.max.y = q.min.y+2;
           49                 else
           50                         q.min.y = q.max.y-2;
           51         }
           52         return q;
           53 }
           54 
           55 void
           56 scrmark(Flayer *l, Rectangle r)
           57 {
           58         r.max.x--;
           59         if(rectclip(&r, l->scroll))
           60                 draw(l->f.b, r, l->f.cols[HIGH], nil, ZP);
           61 }
           62 
           63 void
           64 scrunmark(Flayer *l, Rectangle r)
           65 {
           66         if(rectclip(&r, l->scroll))
           67                 draw(l->f.b, r, scrback, nil, Pt(0, r.min.y-l->scroll.min.y));
           68 }
           69 
           70 void
           71 scrdraw(Flayer *l, long tot)
           72 {
           73         Rectangle r, r1, r2;
           74         Image *b;
           75 
           76         scrtemps();
           77         if(l->f.b == 0)
           78                 panic("scrdraw");
           79         r = l->scroll;
           80         r1 = r;
           81         if(l->visible == All){
           82                 b = scrtmp;
           83                 r1.min.x = 0;
           84                 r1.max.x = Dx(r);
           85         }else
           86                 b = l->f.b;
           87         r2 = scrpos(r1, l->origin, l->origin+l->f.nchars, tot);
           88         if(!eqrect(r2, l->lastsr)){
           89                 l->lastsr = r2;
           90                 draw(b, r1, l->f.cols[BORD], nil, ZP);
           91                 draw(b, r2, l->f.cols[BACK], nil, r2.min);
           92                 r2 = r1;
           93                 r2.min.x = r2.max.x-1;
           94                 draw(b, r2, l->f.cols[BORD], nil, ZP);
           95                 if(b!=l->f.b)
           96                         draw(l->f.b, r, b, nil, r1.min);
           97         }
           98 }
           99 
          100 void
          101 scroll(Flayer *l, int but)
          102 {
          103         int in = 0, oin;
          104         long tot = scrtotal(l);
          105         Rectangle scr, r, s, rt;
          106         int x, y, my, oy, h;
          107         long p0;
          108 
          109         s = l->scroll;
          110         x = s.min.x+FLSCROLLWID(l)/2;
          111         scr = scrpos(l->scroll, l->origin, l->origin+l->f.nchars, tot);
          112         r = scr;
          113         y = scr.min.y;
          114         my = mousep->xy.y;
          115         draw(scrback, Rect(0,0,Dx(l->scroll), Dy(l->scroll)), l->f.b, nil, l->scroll.min);
          116         do{
          117                 oin = in;
          118                 in = abs(x-mousep->xy.x)<=FLSCROLLWID(l)/2;
          119                 if(oin && !in)
          120                         scrunmark(l, r);
          121                 if(in){
          122                         scrmark(l, r);
          123                         oy = y;
          124                         my = mousep->xy.y;
          125                         if(my < s.min.y)
          126                                 my = s.min.y;
          127                         if(my >= s.max.y)
          128                                 my = s.max.y;
          129                         if(!eqpt(mousep->xy, Pt(x, my)))
          130                                 moveto(mousectl, Pt(x, my));
          131                         if(but == 1){
          132                                 p0 = l->origin-frcharofpt(&l->f, Pt(s.max.x, my));
          133                                 rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
          134                                 y = rt.min.y;
          135                         }else if(but == 2){
          136                                 y = my;
          137                                 if(y > s.max.y-2)
          138                                         y = s.max.y-2;
          139                         }else if(but == 3){
          140                                 p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
          141                                 rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
          142                                 y = rt.min.y;
          143                         }
          144                         if(y != oy){
          145                                 scrunmark(l, r);
          146                                 r = rectaddpt(scr, Pt(0, y-scr.min.y));
          147                                 scrmark(l, r);
          148                         }
          149                 }
          150         }while(button(but));
          151         if(in){
          152                 h = s.max.y-s.min.y;
          153                 scrunmark(l, r);
          154                 p0 = 0;
          155                 if(but == 1)
          156                         p0 = (long)(my-s.min.y)/l->f.font->height+1;
          157                 else if(but == 2){
          158                         if(tot > 1024L*1024L)
          159                                 p0 = ((tot>>10)*(y-s.min.y)/h)<<10;
          160                         else
          161                                 p0 = tot*(y-s.min.y)/h;
          162                 }else if(but == 3){
          163                         p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
          164                         if(p0 > tot)
          165                                 p0 = tot;
          166                 }
          167                 scrorigin(l, but, p0);
          168         }
          169 }