#include #include #include #include #include #include #include "univ.h" void RequestLines(Pad*); static Image *scrtemp; static Image *scrback; void scrltemp( void ){ int h; if( scrtemp ) return; #define BIG 3 h = BIG*Dy( screen->r ); scrtemp = allocimage( display, Rect(0, 0, 32, h), screen->chan, 0, 0 ); scrback = allocimage( display, Rect(0, 0, 32, h), screen->chan, 0, 0 ); if( scrtemp==0 || scrback==0 ) panic( "scrltemp" ); } long ScrollTotal( Pad *p ){ /* should be in ClipPaint ?? */ long lines; Line *l, *lsent=&p->sentinel; if( lsent->key ) lines = lsent->key; else for( lines=0, l=lsent->down; l!=lsent ; l=l->down ) lines++; return (p->nlines=lines); } void Mark( Pad *p, Rectangle r ){ if(rectclip(&r, p->scroll)) draw(screen, r, padcols[BORD], nil, ZPoint); } void Unmark( Pad *p, Rectangle r ){ if(rectclip(&r, p->scroll)) draw(screen, r, padcols[BACK], nil, Pt(0, r.min.y-p->scroll.min.y)); } Rectangle scrollbar( Rectangle r, int from, int to, int lo, int hi ){ int rh = Dy(r), h = hi-lo; scrltemp(); r.max.y -= muldiv(hi-to,rh,h); r.min.y += muldiv(from-lo,rh,h); return r; } void PaintScroll( Pad *p ){ long tot = ScrollTotal( p ); Rectangle r1, r2; scrltemp(); if( !tot ) return; r1 = p->scroll; r2 = scrollbar( r1, p->lo, p->hi, 0, tot ); if( !eqrect( r2, p->lastsr ) ){ p->lastsr = r2; draw( screen, r1, padcols[BACK], nil, ZP ); draw( screen, r2, padcols[BORD], nil, r2.min ); } } void Doscroll( Pad *p, int but ){ int lines, delta; int x, dy, y, y0, y1, y2, yscale; Rectangle r, s; if( but!=2 ) return; y0 = p->scroll.min.y; yscale = p->scroll.max.y - y0; s = insetrect(p->scroll, 1); x = (s.min.x+s.max.x)/2; lines = ScrollTotal(p); delta = p->hi - p->lo + 1; r = scrollbar( p->scroll, p->lo, p->hi, 0, lines ); y = mousep->xy.y; draw(scrback, Rect(0,0,Dx(p->scroll),Dy(p->scroll)), screen, nil, p->scroll.min); while(button(but)){ y1 = y; y2 = mousep->xy.y; if(y2 < p->scroll.min.y) y2 = p->scroll.min.y; if(y2 >= p->scroll.max.y) y2 = p->scroll.max.y; y = y2; if(y > p->scroll.max.y-2) y = p->scroll.max.y-2; if(!eqpt(mousep->xy, Pt(x, y))){ /* from acme */ moveto(mousectl, Pt(x, y)); readmouse(mousectl); } if(y != y1){ dy = y - y1; Unmark(p, r); r = rectaddpt(r, Pt(0,dy)); Mark(p, r); } waitMOUSE(); } if( ptinrect(mousep->xy, p->scroll) ){ Scrolly = mousep->xy.y; Paint(p); Scrolly = 0; RequestLines(p); return; } draw(screen, p->scroll, scrback, nil, ZPoint); }