123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187 |
- implement Scroll;
- include "common.m";
- sys : Sys;
- drawm : Draw;
- acme : Acme;
- graph : Graph;
- utils : Utils;
- gui : Gui;
- dat : Dat;
- framem : Framem;
- textm : Textm;
- timerm : Timerm;
- BORD, BACK : import Framem;
- FALSE, TRUE, XXX, Maxblock : import Dat;
- error, warning : import utils;
- Point, Rect, Image, Display : import drawm;
- draw : import graph;
- black, white, display : import gui;
- mouse, cmouse : import dat;
- Frame : import framem;
- Timer : import Dat;
- Text : import textm;
- frgetmouse : import acme;
- mainwin : import gui;
- init(mods : ref Dat->Mods)
- {
- sys = mods.sys;
- drawm = mods.draw;
- acme = mods.acme;
- graph = mods.graph;
- utils = mods.utils;
- gui = mods.gui;
- dat = mods.dat;
- framem = mods.framem;
- textm = mods.textm;
- timerm = mods.timerm;
- }
- scrpos(r : Rect, p0 : int, p1 : int, tot : int) : Rect
- {
- h : int;
- q : Rect;
- q = r;
- # q = r.inset(1);
- h = q.max.y-q.min.y;
- if(tot == 0)
- return q;
- if(tot > 1024*1024){
- tot >>= 10;
- p0 >>= 10;
- p1 >>= 10;
- }
- if(p0 > 0)
- q.min.y += h*p0/tot;
- if(p1 < tot)
- q.max.y -= h*(tot-p1)/tot;
- if(q.max.y < q.min.y+2){
- if(q.min.y+2 <= r.max.y)
- q.max.y = q.min.y+2;
- else
- q.min.y = q.max.y-2;
- }
- return q;
- }
- scrx : ref Image;
- scrresize()
- {
- scrx = nil;
- h := 1024;
- if (display != nil)
- h = display.image.r.dy();
- rr := Rect((0, 0), (32, h));
- scrx = graph->balloc(rr, mainwin.chans, Draw->White);
- if(scrx == nil)
- error("scroll balloc");
- }
- scrdraw(t : ref Text)
- {
- r, r1, r2 : Rect;
- if(t.w==nil || t.what!=Textm->Body || t != t.w.body)
- return;
- if(scrx == nil)
- scrresize();
- r = t.scrollr;
- b := scrx;
- r1 = r;
- # r.min.x += 1; # border between margin and bar
- r1.min.x = 0;
- r1.max.x = r.dx();
- r2 = scrpos(r1, t.org, t.org+t.frame.nchars, t.file.buf.nc);
- if(!r2.eq(t.lastsr)){
- t.lastsr = r2;
- draw(b, r1, t.frame.cols[BORD], nil, (0, 0));
- draw(b, r2, t.frame.cols[BACK], nil, (0, 0));
- r2.min.x = r2.max.x-1;
- draw(b, r2, t.frame.cols[BORD], nil, (0, 0));
- draw(t.frame.b, r, b, nil, (0, r1.min.y));
- # bflush();
- }
- }
- scrsleep(dt : int)
- {
- timer : ref Timer;
- timer = timerm->timerstart(dt);
- graph->bflush();
- # only run from mouse task, so safe to use cmouse
- alt{
- <-(timer.c) =>
- timerm->timerstop(timer);
- *mouse = *<-cmouse =>
- spawn timerm->timerwaittask(timer);
- }
- }
- scroll(t : ref Text, but : int)
- {
- p0, oldp0 : int;
- s : Rect;
- x, y, my, h, first : int;
- s = t.scrollr.inset(1);
- h = s.max.y-s.min.y;
- x = (s.min.x+s.max.x)/2;
- oldp0 = ~0;
- first = TRUE;
- do{
- graph->bflush();
- my = mouse.xy.y;
- if(my < s.min.y)
- my = s.min.y;
- if(my >= s.max.y)
- my = s.max.y;
- if(but == 2){
- y = my;
- if(y > s.max.y-2)
- y = s.max.y-2;
- if(t.file.buf.nc > 1024*1024)
- p0 = ((t.file.buf.nc>>10)*(y-s.min.y)/h)<<10;
- else
- p0 = t.file.buf.nc*(y-s.min.y)/h;
- if(oldp0 != p0)
- t.setorigin(p0, FALSE);
- oldp0 = p0;
- frgetmouse();
- continue;
- }
- if(but == 1) {
- p0 = t.backnl(t.org, (my-s.min.y)/t.frame.font.height);
- if(p0 == t.org)
- p0 = t.backnl(t.org, 1);
- }
- else {
- p0 = t.org+framem->frcharofpt(t.frame, (s.max.x, my));
- if(p0 == t.org)
- p0 = t.forwnl(t.org, 1);
- }
- if(oldp0 != p0)
- t.setorigin(p0, TRUE);
- oldp0 = p0;
- # debounce
- if(first){
- graph->bflush();
- sys->sleep(200);
- alt {
- *mouse = *<-cmouse =>
- ;
- * =>
- ;
- }
- first = FALSE;
- }
- scrsleep(80);
- }while(mouse.buttons & (1<<(but-1)));
- while(mouse.buttons)
- frgetmouse();
- }
|