From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/cmd/abaco/scrl.c | 317 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 317 insertions(+) create mode 100755 sys/src/cmd/abaco/scrl.c (limited to 'sys/src/cmd/abaco/scrl.c') diff --git a/sys/src/cmd/abaco/scrl.c b/sys/src/cmd/abaco/scrl.c new file mode 100755 index 000000000..3b7072f97 --- /dev/null +++ b/sys/src/cmd/abaco/scrl.c @@ -0,0 +1,317 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dat.h" +#include "fns.h" + +static Image *vscrtmp; +static Image *hscrtmp; + +void +scrlresize(void) +{ + freeimage(vscrtmp); + freeimage(hscrtmp); + vscrtmp = eallocimage(display, Rect(0, 0, 32, screen->r.max.y), screen->chan, 0, DNofill); + hscrtmp = eallocimage(display, Rect(0, 0, screen->r.max.x, 32), screen->chan, 0, DNofill); +} + +static +Rectangle +scrpos(Rectangle r, uint p0, uint p1, uint tot) +{ + Rectangle q; + int h; + + q = r; + 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; +} + +void +textscrdraw(Text *t) +{ + Rectangle r, r1, r2; + Image *b; + + if(vscrtmp == nil) + scrlresize(); + r = t->scrollr; + b = vscrtmp; + r1 = r; + r1.min.x = 0; + r1.max.x = Dx(r); + r2 = scrpos(r1, t->org, t->org+t->nchars, t->rs.nr); + if(!eqrect(r2, t->lastsr)){ + t->lastsr = r2; + draw(b, r1, t->cols[BORD], nil, ZP); + draw(b, r2, t->cols[BACK], nil, ZP); + r2.min.x = r2.max.x-1; + draw(b, r2, t->cols[BORD], nil, ZP); + draw(t->b, r, b, nil, Pt(0, r1.min.y)); +/*flushimage(display, 1);/*BUG?*/ + } +} + +void +scrsleep(uint dt) +{ + Timer *timer; + static Alt alts[3]; + + timer = timerstart(dt); + alts[0].c = timer->c; + alts[0].v = nil; + alts[0].op = CHANRCV; + alts[1].c = mousectl->c; + alts[1].v = &mousectl->Mouse; + alts[1].op = CHANRCV; + alts[2].op = CHANEND; + for(;;) + switch(alt(alts)){ + case 0: + timerstop(timer); + return; + case 1: + timercancel(timer); + return; + } +} + +void +textscroll(Text *t, int but) +{ + uint p0, oldp0; + Rectangle s; + int x, y, my, h, first; + + s = insetrect(t->scrollr, 1); + h = s.max.y-s.min.y; + x = (s.min.x+s.max.x)/2; + oldp0 = ~0; + first = TRUE; + do{ + flushimage(display, 1); + my = mouse->xy.y; + if(my < s.min.y) + my = s.min.y; + if(my >= s.max.y) + my = s.max.y; + if(!eqpt(mouse->xy, Pt(x, my))){ + moveto(mousectl, Pt(x, my)); + readmouse(mousectl); /* absorb event generated by moveto() */ + } + if(but == 2){ + y = my; + p0 = (vlong)t->rs.nr*(y-s.min.y)/h; + if(p0 >= t->q1) + p0 = textbacknl(t, p0, 2); + if(oldp0 != p0) + textsetorigin(t, p0, FALSE); + oldp0 = p0; + readmouse(mousectl); + continue; + } + if(but == 1) + p0 = textbacknl(t, t->org, (my-s.min.y)/t->font->height); + else + p0 = t->org+frcharofpt(t, Pt(s.max.x, my)); + if(oldp0 != p0) + textsetorigin(t, p0, TRUE); + oldp0 = p0; + /* debounce */ + if(first){ + flushimage(display, 1); + sleep(200); + nbrecv(mousectl->c, &mousectl->Mouse); + first = FALSE; + } + scrsleep(80); + }while(mouse->buttons & (1<<(but-1))); + while(mouse->buttons) + readmouse(mousectl); +} + +enum +{ + Scrbord = 1, +}; + +void +pagescrldraw(Page *p) +{ + Rectangle r1; + int t, d, l, h; + + if(vscrtmp == nil) + scrlresize(); + + r1 = Rect(0,0,Dx(p->hscrollr), Dy(p->hscrollr)); + d = Dx(r1); + t = Dx(p->lay->r); + l = muldiv(p->pos.x, d, t); + h = muldiv(p->pos.x+d, d, t); + draw(hscrtmp, r1, tagcols[HIGH], nil, ZP); + r1.max.x = r1.min.x+h; + r1.min.x += l; + r1.min.y += Scrbord; + r1.max.y -= Scrbord; + draw(hscrtmp, r1, tagcols[BACK], nil, ZP); + + r1 = Rect(0,0,Dx(p->vscrollr), Dy(p->vscrollr)); + d = Dy(r1); + t = Dy(p->lay->r); + l = muldiv(p->pos.y, d, t); + h = muldiv(p->pos.y+d, d, t); + draw(vscrtmp, r1, tagcols[HIGH], nil, ZP); + r1.max.y = r1.min.y+h; + r1.min.y += l; + r1.max.x -= Scrbord; + r1.min.x += Scrbord; + draw(vscrtmp, r1, tagcols[BACK], nil, ZP); + + draw(screen, p->vscrollr, vscrtmp, nil, vscrtmp->r.min); + draw(screen, p->hscrollr, hscrtmp, nil, hscrtmp->r.min); +} + +void +pagescroll(Page *p, int but, int horizontal) +{ + uint oldp0, p0; + Rectangle s; + Point mxy; + int i, m, om, first, d, size; + int smin, smax, ss, *pos; + + if(horizontal){ + s = insetrect(p->hscrollr, 1); + ss = s.max.x - s.min.x; + i = (s.min.y+s.max.y)/2; + d = Dx(p->r); + size = Dx(p->lay->r); + p0 = p->pos.x; + pos = &p->pos.x; + smin = s.min.x; + smax = s.max.x; + om = mouse->xy.x; + }else{ + s = insetrect(p->vscrollr, 1); + ss = s.max.y-s.min.y; + i = (s.min.x+s.max.x)/2; + d = Dy(p->r); + size = Dy(p->lay->r); + p0 = p->pos.y; + pos = &p->pos.y; + smin = s.min.y; + smax = s.max.y; + om = mouse->xy.y; + } + oldp0 = ~0; + first = TRUE; + do{ + flushimage(display, 1); + if(horizontal) + m = mouse->xy.x; + else + m = mouse->xy.y; + + if(m > om) + m += (m-om)*Panspeed; + else if(m < om) + m -= (om-m)*Panspeed; + + if(m < smin) + m = smin; + if(m > smax) + m = smax; + + om = m; + if(horizontal) + mxy = Pt(m, i); + else + mxy = Pt(i, m); + if(!eqpt(mouse->xy, mxy)){ + moveto(mousectl, mxy); + readmouse(mousectl); /* absorb event generated by moveto() */ + } + if(but == 2){ + p0 = muldiv(m-smin, size, ss); + p0 = max(p0, 0); + p0 = min(p0,size-d); + if(oldp0 != p0){ + *pos = p0; + pageredraw(p); + } + oldp0 = p0; + readmouse(mousectl); + continue; + } + if(but == 1) + p0 -= (d/2); + else + p0 += d/2; + p0 = min(p0, size-d); + p0 = max(p0, 0); + if(oldp0 != p0){ + *pos = p0; + pageredraw(p); + } + oldp0 = p0; + /* debounce */ + if(first){ + flushimage(display, 1); + sleep(200); + nbrecv(mousectl->c, &mousectl->Mouse); + first = FALSE; + } + scrsleep(80); + }while(mouse->buttons & (1<<(but-1))); + while(mouse->buttons) + readmouse(mousectl); +} + +int +pagescrollxy(Page *p, int x, int y) +{ + int scrled; + + scrled = FALSE; + if(x != 0){ + p->pos.x += x; + p->pos.x = max(p->pos.x, 0); + p->pos.x = min(p->pos.x, Dx(p->lay->r)-Dx(p->r)); + scrled =TRUE; + } + if(y != 0){ + p->pos.y += y; + p->pos.y = max(p->pos.y, 0); + p->pos.y = min(p->pos.y, Dy(p->lay->r)-Dy(p->r)); + scrled =TRUE; + } + return scrled; +} -- cgit v1.2.3