tscroll.c - plan9port - [fork] Plan 9 from user space
git clone git://src.adamsgaard.dk/plan9port
Log
Files
Refs
README
LICENSE
---
tscroll.c (3328B)
---
     1 #include 
     2 #include 
     3 #include 
     4 #include 
     5 #include 
     6 #include 
     7 #include 
     8 #include 
     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 }