13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
37dd7cddfSDavid du Colombier #include <draw.h>
47dd7cddfSDavid du Colombier #include <thread.h>
57dd7cddfSDavid du Colombier #include <mouse.h>
67dd7cddfSDavid du Colombier #include <keyboard.h>
73e12c5d1SDavid du Colombier #include <frame.h>
83e12c5d1SDavid du Colombier #include "flayer.h"
93e12c5d1SDavid du Colombier #include "samterm.h"
103e12c5d1SDavid du Colombier
117dd7cddfSDavid du Colombier static Image *scrtmp;
127dd7cddfSDavid du Colombier static Image *scrback;
137dd7cddfSDavid du Colombier
147dd7cddfSDavid du Colombier void
scrtemps(void)157dd7cddfSDavid du Colombier scrtemps(void)
167dd7cddfSDavid du Colombier {
177dd7cddfSDavid du Colombier int h;
187dd7cddfSDavid du Colombier
197dd7cddfSDavid du Colombier if(scrtmp)
207dd7cddfSDavid du Colombier return;
217dd7cddfSDavid du Colombier if(screensize(0, &h) == 0)
227dd7cddfSDavid du Colombier h = 2048;
239a747e4fSDavid du Colombier scrtmp = allocimage(display, Rect(0, 0, 32, h), screen->chan, 0, 0);
249a747e4fSDavid du Colombier scrback = allocimage(display, Rect(0, 0, 32, h), screen->chan, 0, 0);
257dd7cddfSDavid du Colombier if(scrtmp==0 || scrback==0)
267dd7cddfSDavid du Colombier panic("scrtemps");
277dd7cddfSDavid du Colombier }
283e12c5d1SDavid du Colombier
293e12c5d1SDavid du Colombier Rectangle
scrpos(Rectangle r,long p0,long p1,long tot)303e12c5d1SDavid du Colombier scrpos(Rectangle r, long p0, long p1, long tot)
313e12c5d1SDavid du Colombier {
323e12c5d1SDavid du Colombier Rectangle q;
337dd7cddfSDavid du Colombier int h;
343e12c5d1SDavid du Colombier
357dd7cddfSDavid du Colombier q = r;
363e12c5d1SDavid du Colombier h = q.max.y-q.min.y;
373e12c5d1SDavid du Colombier if(tot == 0)
383e12c5d1SDavid du Colombier return q;
393e12c5d1SDavid du Colombier if(tot > 1024L*1024L)
403e12c5d1SDavid du Colombier tot>>=10, p0>>=10, p1>>=10;
413e12c5d1SDavid du Colombier if(p0 > 0)
423e12c5d1SDavid du Colombier q.min.y += h*p0/tot;
433e12c5d1SDavid du Colombier if(p1 < tot)
443e12c5d1SDavid du Colombier q.max.y -= h*(tot-p1)/tot;
453e12c5d1SDavid du Colombier if(q.max.y < q.min.y+2){
463e12c5d1SDavid du Colombier if(q.min.y+2 <= r.max.y)
473e12c5d1SDavid du Colombier q.max.y = q.min.y+2;
483e12c5d1SDavid du Colombier else
493e12c5d1SDavid du Colombier q.min.y = q.max.y-2;
503e12c5d1SDavid du Colombier }
513e12c5d1SDavid du Colombier return q;
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier
543e12c5d1SDavid du Colombier void
scrmark(Flayer * l,Rectangle r)557dd7cddfSDavid du Colombier scrmark(Flayer *l, Rectangle r)
567dd7cddfSDavid du Colombier {
577dd7cddfSDavid du Colombier r.max.x--;
58*671dfc47SDavid du Colombier if(rectclip(&r, l->scroll)) {
59*671dfc47SDavid du Colombier if (l->f.b == nil)
60*671dfc47SDavid du Colombier panic("scrmark: nil l->f.b");
617dd7cddfSDavid du Colombier draw(l->f.b, r, l->f.cols[HIGH], nil, ZP);
627dd7cddfSDavid du Colombier }
63*671dfc47SDavid du Colombier }
647dd7cddfSDavid du Colombier
657dd7cddfSDavid du Colombier void
scrunmark(Flayer * l,Rectangle r)667dd7cddfSDavid du Colombier scrunmark(Flayer *l, Rectangle r)
673e12c5d1SDavid du Colombier {
68*671dfc47SDavid du Colombier if(rectclip(&r, l->scroll)) {
69*671dfc47SDavid du Colombier if (l->f.b == nil)
70*671dfc47SDavid du Colombier panic("scrunmark: nil l->f.b");
717dd7cddfSDavid du Colombier draw(l->f.b, r, scrback, nil, Pt(0, r.min.y-l->scroll.min.y));
723e12c5d1SDavid du Colombier }
73*671dfc47SDavid du Colombier }
743e12c5d1SDavid du Colombier
753e12c5d1SDavid du Colombier void
scrdraw(Flayer * l,long tot)763e12c5d1SDavid du Colombier scrdraw(Flayer *l, long tot)
773e12c5d1SDavid du Colombier {
783e12c5d1SDavid du Colombier Rectangle r, r1, r2;
797dd7cddfSDavid du Colombier Image *b;
803e12c5d1SDavid du Colombier
817dd7cddfSDavid du Colombier scrtemps();
823e12c5d1SDavid du Colombier if(l->f.b == 0)
833e12c5d1SDavid du Colombier panic("scrdraw");
843e12c5d1SDavid du Colombier r = l->scroll;
853e12c5d1SDavid du Colombier r1 = r;
863e12c5d1SDavid du Colombier if(l->visible == All){
877dd7cddfSDavid du Colombier b = scrtmp;
883e12c5d1SDavid du Colombier r1.min.x = 0;
893e12c5d1SDavid du Colombier r1.max.x = Dx(r);
903e12c5d1SDavid du Colombier }else
913e12c5d1SDavid du Colombier b = l->f.b;
923e12c5d1SDavid du Colombier r2 = scrpos(r1, l->origin, l->origin+l->f.nchars, tot);
937dd7cddfSDavid du Colombier if(!eqrect(r2, l->lastsr)){
947dd7cddfSDavid du Colombier l->lastsr = r2;
957dd7cddfSDavid du Colombier draw(b, r1, l->f.cols[BORD], nil, ZP);
967dd7cddfSDavid du Colombier draw(b, r2, l->f.cols[BACK], nil, r2.min);
977dd7cddfSDavid du Colombier r2 = r1;
987dd7cddfSDavid du Colombier r2.min.x = r2.max.x-1;
997dd7cddfSDavid du Colombier draw(b, r2, l->f.cols[BORD], nil, ZP);
1003e12c5d1SDavid du Colombier if(b!=l->f.b)
1017dd7cddfSDavid du Colombier draw(l->f.b, r, b, nil, r1.min);
1027dd7cddfSDavid du Colombier }
1033e12c5d1SDavid du Colombier }
1043e12c5d1SDavid du Colombier
1053e12c5d1SDavid du Colombier void
scroll(Flayer * l,int but)1063e12c5d1SDavid du Colombier scroll(Flayer *l, int but)
1073e12c5d1SDavid du Colombier {
1083e12c5d1SDavid du Colombier int in = 0, oin;
1093e12c5d1SDavid du Colombier long tot = scrtotal(l);
1103e12c5d1SDavid du Colombier Rectangle scr, r, s, rt;
1113e12c5d1SDavid du Colombier int x, y, my, oy, h;
1123e12c5d1SDavid du Colombier long p0;
1133e12c5d1SDavid du Colombier
1147dd7cddfSDavid du Colombier s = l->scroll;
1153e12c5d1SDavid du Colombier x = s.min.x+FLSCROLLWID/2;
1163e12c5d1SDavid du Colombier scr = scrpos(l->scroll, l->origin, l->origin+l->f.nchars, tot);
1173e12c5d1SDavid du Colombier r = scr;
1183e12c5d1SDavid du Colombier y = scr.min.y;
1197dd7cddfSDavid du Colombier my = mousep->xy.y;
1207dd7cddfSDavid du Colombier draw(scrback, Rect(0,0,Dx(l->scroll), Dy(l->scroll)), l->f.b, nil, l->scroll.min);
1213e12c5d1SDavid du Colombier do{
1223e12c5d1SDavid du Colombier oin = in;
1237dd7cddfSDavid du Colombier in = abs(x-mousep->xy.x)<=FLSCROLLWID/2;
1247dd7cddfSDavid du Colombier if(oin && !in)
1257dd7cddfSDavid du Colombier scrunmark(l, r);
1263e12c5d1SDavid du Colombier if(in){
1277dd7cddfSDavid du Colombier scrmark(l, r);
1283e12c5d1SDavid du Colombier oy = y;
1297dd7cddfSDavid du Colombier my = mousep->xy.y;
1303e12c5d1SDavid du Colombier if(my < s.min.y)
1313e12c5d1SDavid du Colombier my = s.min.y;
1323e12c5d1SDavid du Colombier if(my >= s.max.y)
1333e12c5d1SDavid du Colombier my = s.max.y;
1347dd7cddfSDavid du Colombier if(!eqpt(mousep->xy, Pt(x, my)))
1357dd7cddfSDavid du Colombier moveto(mousectl, Pt(x, my));
1363e12c5d1SDavid du Colombier if(but == 1){
1373e12c5d1SDavid du Colombier p0 = l->origin-frcharofpt(&l->f, Pt(s.max.x, my));
1383e12c5d1SDavid du Colombier rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
1393e12c5d1SDavid du Colombier y = rt.min.y;
1403e12c5d1SDavid du Colombier }else if(but == 2){
1413e12c5d1SDavid du Colombier y = my;
1423e12c5d1SDavid du Colombier if(y > s.max.y-2)
1433e12c5d1SDavid du Colombier y = s.max.y-2;
1443e12c5d1SDavid du Colombier }else if(but == 3){
1453e12c5d1SDavid du Colombier p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
1463e12c5d1SDavid du Colombier rt = scrpos(l->scroll, p0, p0+l->f.nchars, tot);
1473e12c5d1SDavid du Colombier y = rt.min.y;
1483e12c5d1SDavid du Colombier }
1493e12c5d1SDavid du Colombier if(y != oy){
1507dd7cddfSDavid du Colombier scrunmark(l, r);
1517dd7cddfSDavid du Colombier r = rectaddpt(scr, Pt(0, y-scr.min.y));
1527dd7cddfSDavid du Colombier scrmark(l, r);
1533e12c5d1SDavid du Colombier }
1543e12c5d1SDavid du Colombier }
1553e12c5d1SDavid du Colombier }while(button(but));
1563e12c5d1SDavid du Colombier if(in){
1573e12c5d1SDavid du Colombier h = s.max.y-s.min.y;
1587dd7cddfSDavid du Colombier scrunmark(l, r);
1593e12c5d1SDavid du Colombier p0 = 0;
1603e12c5d1SDavid du Colombier if(but == 1)
1613e12c5d1SDavid du Colombier p0 = (long)(my-s.min.y)/l->f.font->height+1;
1623e12c5d1SDavid du Colombier else if(but == 2){
1633e12c5d1SDavid du Colombier if(tot > 1024L*1024L)
1643e12c5d1SDavid du Colombier p0 = ((tot>>10)*(y-s.min.y)/h)<<10;
1653e12c5d1SDavid du Colombier else
1663e12c5d1SDavid du Colombier p0 = tot*(y-s.min.y)/h;
1673e12c5d1SDavid du Colombier }else if(but == 3){
1683e12c5d1SDavid du Colombier p0 = l->origin+frcharofpt(&l->f, Pt(s.max.x, my));
1693e12c5d1SDavid du Colombier if(p0 > tot)
1703e12c5d1SDavid du Colombier p0 = tot;
1713e12c5d1SDavid du Colombier }
1723e12c5d1SDavid du Colombier scrorigin(l, but, p0);
1733e12c5d1SDavid du Colombier }
1743e12c5d1SDavid du Colombier }
175