diff options
author | stanley lieber <stanley.lieber@gmail.com> | 2015-02-08 13:19:47 -0500 |
---|---|---|
committer | stanley lieber <stanley.lieber@gmail.com> | 2015-02-08 13:19:47 -0500 |
commit | 20f2add592f8463ef6820afd07a342acb26da304 (patch) | |
tree | dffce8d23bc315158cbbd796b7a7fad1849fa91b /sys/src | |
parent | b2c2d1ed2a0ce84f3ebe34065d35cec0789653cb (diff) |
mothra: add side scrolling, controlled by left and right buttons on the keyboard. if desired, x-scrollbar can be set visible via the visxbar variable in mothra.c. (thanks, jpm_)
Diffstat (limited to 'sys/src')
-rw-r--r-- | sys/src/cmd/mothra/libpanel/draw.c | 2 | ||||
-rw-r--r-- | sys/src/cmd/mothra/libpanel/pack.c | 1 | ||||
-rw-r--r-- | sys/src/cmd/mothra/libpanel/panel.h | 2 | ||||
-rw-r--r-- | sys/src/cmd/mothra/libpanel/pldefs.h | 8 | ||||
-rw-r--r-- | sys/src/cmd/mothra/libpanel/rtext.c | 80 | ||||
-rw-r--r-- | sys/src/cmd/mothra/libpanel/textview.c | 115 | ||||
-rw-r--r-- | sys/src/cmd/mothra/mothra.c | 65 |
7 files changed, 189 insertions, 84 deletions
diff --git a/sys/src/cmd/mothra/libpanel/draw.c b/sys/src/cmd/mothra/libpanel/draw.c index fb51a0983..168363943 100644 --- a/sys/src/cmd/mothra/libpanel/draw.c +++ b/sys/src/cmd/mothra/libpanel/draw.c @@ -243,7 +243,7 @@ void pl_sliderupd(Image *b, Rectangle r1, int dir, int lo, int hi){ } void pl_draw1(Panel *p, Image *b); void pl_drawall(Panel *p, Image *b){ - if(p->flags&INVIS) return; + if(p->flags&INVIS || p->flags&IGNORE) return; p->b=b; p->draw(p); for(p=p->child;p;p=p->next) pl_draw1(p, b); diff --git a/sys/src/cmd/mothra/libpanel/pack.c b/sys/src/cmd/mothra/libpanel/pack.c index d5e1f0249..397202d85 100644 --- a/sys/src/cmd/mothra/libpanel/pack.c +++ b/sys/src/cmd/mothra/libpanel/pack.c @@ -97,6 +97,7 @@ void pl_setrect(Panel *p, Point ul, Point avail){ slack=subpt(space, p->childreq); share=pl_getshare(p->child); for(c=p->child;c;c=c->next){ + if(c->flags&IGNORE) continue; if(c->flags&EXPAND){ switch(c->flags&PACK){ case PACKN: diff --git a/sys/src/cmd/mothra/libpanel/panel.h b/sys/src/cmd/mothra/libpanel/panel.h index 11351ac6f..8c9680c10 100644 --- a/sys/src/cmd/mothra/libpanel/panel.h +++ b/sys/src/cmd/mothra/libpanel/panel.h @@ -86,6 +86,8 @@ struct Panel{ #define MAXX 0x1000 /* make x size as big as biggest sibling's */ #define MAXY 0x2000 /* make y size as big as biggest sibling's */ #define BITMAP 0x4000 /* text argument is a bitmap, not a string */ +/* pldefs.h flags 0x08000-0x40000 */ +#define IGNORE 0x080000 /* ignore this panel totally */ #define USERFL 0x100000 /* start of user flag */ /* diff --git a/sys/src/cmd/mothra/libpanel/pldefs.h b/sys/src/cmd/mothra/libpanel/pldefs.h index 8e96f1a4d..f5d461b3c 100644 --- a/sys/src/cmd/mothra/libpanel/pldefs.h +++ b/sys/src/cmd/mothra/libpanel/pldefs.h @@ -5,10 +5,10 @@ * Variable-font text routines * These could make a separate library. */ -int pl_rtfmt(Rtext *, int); -void pl_rtdraw(Image *, Rectangle, Rtext *, int); -void pl_rtredraw(Image *, Rectangle, Rtext *, int, int); -Rtext *pl_rthit(Rtext *, int, Point, Point); +Point pl_rtfmt(Rtext *, int); +void pl_rtdraw(Image *, Rectangle, Rtext *, Point); +void pl_rtredraw(Image *, Rectangle, Rtext *, Point, Point, int); +Rtext *pl_rthit(Rtext *, Point, Point, Point); #define HITME 0x08000 /* tells ptinpanel not to look at children */ #define LEAF 0x10000 /* newpanel will refuse to attach children */ #define INVIS 0x20000 /* don't draw this */ diff --git a/sys/src/cmd/mothra/libpanel/rtext.c b/sys/src/cmd/mothra/libpanel/rtext.c index a18be62f5..68bccfad3 100644 --- a/sys/src/cmd/mothra/libpanel/rtext.c +++ b/sys/src/cmd/mothra/libpanel/rtext.c @@ -67,14 +67,16 @@ int pl_space(int space, int pos, int indent){ } /* * initialize rectangles & nextlines of text starting at t, - * galley width is wid. Returns the total length of the text + * galley width is wid. Returns the total width/height of the text */ -int pl_rtfmt(Rtext *t, int wid){ +Point pl_rtfmt(Rtext *t, int wid){ Rtext *tp, *eline; - int ascent, descent, x, space, a, d, w, topy, indent; + int ascent, descent, x, space, a, d, w, topy, indent, maxwid; Point p; + p=Pt(0,0); eline=t; + maxwid=0; while(t){ ascent=0; descent=0; @@ -147,9 +149,10 @@ int pl_rtfmt(Rtext *t, int wid){ if(t==eline) break; p.x+=pl_space(t->space, p.x, indent); } + if(p.x>maxwid) maxwid=p.x; p.y+=descent+LEAD; } - return p.y; + return Pt(maxwid, p.y); } /* @@ -163,9 +166,9 @@ void pl_stuffbitmap(Panel *p, Image *b){ pl_stuffbitmap(p, b); } -void pl_rtdraw(Image *b, Rectangle r, Rtext *t, int yoffs){ +void pl_rtdraw(Image *b, Rectangle r, Rtext *t, Point offs){ static Image *backup; - Point offs, lp; + Point lp; Rectangle dr; Image *bb; @@ -178,11 +181,13 @@ void pl_rtdraw(Image *b, Rectangle r, Rtext *t, int yoffs){ b=backup; pl_clr(b, r); lp=ZP; - offs=subpt(r.min, Pt(0, yoffs)); + offs=subpt(r.min, offs); for(;t;t=t->next) if(!eqrect(t->r, Rect(0,0,0,0))){ dr=rectaddpt(t->r, offs); if(dr.max.y>r.min.y - && dr.min.y<r.max.y){ + && dr.min.y<r.max.y + && dr.max.x>r.min.x + && dr.min.x<r.max.x){ if(t->b){ draw(b, insetrect(dr, BORD), t->b, 0, t->b->r.min); if(t->flags&PL_HOT) border(b, dr, 1, display->black, ZP); @@ -232,30 +237,51 @@ void pl_reposition(Rtext *t, Image *b, Point p, Rectangle r){ * Rectangle r of Image b contains an image of Rtext t, offset by oldoffs. * Redraw the text to have offset yoffs. */ -void pl_rtredraw(Image *b, Rectangle r, Rtext *t, int yoffs, int oldoffs){ - int dy, size; - dy=oldoffs-yoffs; - size=r.max.y-r.min.y; - if(dy>=size || -dy>=size) - pl_rtdraw(b, r, t, yoffs); - else if(dy<0){ - pl_reposition(t, b, r.min, - Rect(r.min.x, r.min.y-dy, r.max.x, r.max.y)); - pl_rtdraw(b, Rect(r.min.x, r.max.y+dy, r.max.x, r.max.y), - t, yoffs+size+dy); - } - else if(dy>0){ - pl_reposition(t, b, Pt(r.min.x, r.min.y+dy), - Rect(r.min.x, r.min.y, r.max.x, r.max.y-dy)); - pl_rtdraw(b, Rect(r.min.x, r.min.y, r.max.x, r.min.y+dy), t, yoffs); +void pl_rtredraw(Image *b, Rectangle r, Rtext *t, Point offs, Point oldoffs, int dir){ + int d, size; + + if(dir==VERT){ + d=oldoffs.y-offs.y; + size=r.max.y-r.min.y; + if(d>=size || -d>=size) /* move more than screenful */ + pl_rtdraw(b, r, t, offs); + else if(d<0){ /* down */ + pl_reposition(t, b, r.min, + Rect(r.min.x, r.min.y-d, r.max.x, r.max.y)); + pl_rtdraw(b, Rect(r.min.x, r.max.y+d, r.max.x, r.max.y), + t, Pt(offs.x, offs.y+size+d)); + } + else if(d>0){ /* up */ + pl_reposition(t, b, Pt(r.min.x, r.min.y+d), + Rect(r.min.x, r.min.y, r.max.x, r.max.y-d)); + pl_rtdraw(b, Rect(r.min.x, r.min.y, r.max.x, r.min.y+d), + t, offs); + } + }else{ /* dir==HORIZ */ + d=oldoffs.x-offs.x; + size=r.max.x-r.min.x; + if(d>=size || -d>=size) /* move more than screenful */ + pl_rtdraw(b, r, t, offs); + else if(d<0){ /* right */ + pl_reposition(t, b, r.min, + Rect(r.min.x-d, r.min.y, r.max.x, r.max.y)); + pl_rtdraw(b, Rect(r.max.x+d, r.min.y, r.max.x, r.max.y), + t, Pt(offs.x+size+d, offs.y)); + } + else if(d>0){ /* left */ + pl_reposition(t, b, Pt(r.min.x+d, r.min.y), + Rect(r.min.x, r.min.y, r.max.x-d, r.max.y)); + pl_rtdraw(b, Rect(r.min.x, r.min.y, r.min.x+d, r.max.y), + t, offs); + } } } -Rtext *pl_rthit(Rtext *t, int yoffs, Point p, Point ul){ +Rtext *pl_rthit(Rtext *t, Point offs, Point p, Point ul){ Rectangle r; Point lp; if(t==0) return 0; - p.x-=ul.x; - p.y+=yoffs-ul.y; + p.x+=offs.x-ul.x; + p.y+=offs.y-ul.y; while(t->nextline && t->nextline->topy<=p.y) t=t->nextline; lp=ZP; for(;t!=0;t=t->next){ diff --git a/sys/src/cmd/mothra/libpanel/textview.c b/sys/src/cmd/mothra/libpanel/textview.c index be5be06c5..6d561660e 100644 --- a/sys/src/cmd/mothra/libpanel/textview.c +++ b/sys/src/cmd/mothra/libpanel/textview.c @@ -15,11 +15,12 @@ typedef struct Textview Textview; struct Textview{ void (*hit)(Panel *, int, Rtext *); /* call back to user on hit */ Rtext *text; /* text */ - int yoffs; /* offset of top of screen */ + Point offs; /* offset of left/top of screen */ Rtext *hitword; /* text to hilite */ Rtext *hitfirst; /* first word in range select */ - int twid; /* text width */ - int thgt; /* text height */ + int twid; /* text width (visible) */ + int thgt; /* text height (total) */ + int maxwid; /* width of longest line */ Point minsize; /* smallest acceptible window size */ int buttons; }; @@ -27,25 +28,35 @@ struct Textview{ void pl_setscrpos(Panel *p, Textview *tp, Rectangle r){ Panel *sb; int lo, hi; - lo=tp->yoffs; + + lo=tp->offs.y; hi=lo+r.max.y-r.min.y; /* wrong? */ - sb=p->yscroller; - if(sb && sb->setscrollbar) sb->setscrollbar(sb, lo, hi, tp->thgt); + sb=p->yscroller; + if(sb && sb->setscrollbar) + sb->setscrollbar(sb, lo, hi, tp->thgt); + lo=tp->offs.x; + hi=lo+r.max.x-r.min.x; + sb=p->xscroller; + if(sb && sb->setscrollbar) + sb->setscrollbar(sb, lo, hi, tp->maxwid); } void pl_drawtextview(Panel *p){ int twid; Rectangle r; Textview *tp; + Point size; + tp=p->data; r=pl_outline(p->b, p->r, UP); twid=r.max.x-r.min.x; if(twid!=tp->twid){ tp->twid=twid; - tp->thgt=pl_rtfmt(tp->text, tp->twid); - p->scr.size.y=tp->thgt; + size=pl_rtfmt(tp->text, tp->twid); + p->scr.size.x=tp->maxwid=size.x; + p->scr.size.y=tp->thgt=size.y; } - p->scr.pos.y=tp->yoffs; - pl_rtdraw(p->b, r, tp->text, tp->yoffs); + p->scr.pos = tp->offs; + pl_rtdraw(p->b, r, tp->text, tp->offs); pl_setscrpos(p, tp, r); } /* @@ -62,7 +73,6 @@ int pl_hittextview(Panel *p, Mouse *m){ Textview *tp; tp=p->data; - hitme=0; oldstate=p->state; oldhitword=tp->hitword; @@ -78,7 +88,7 @@ int pl_hittextview(Panel *p, Mouse *m){ ul=p->r.min; size=subpt(p->r.max, p->r.min); pl_interior(p->state, &ul, &size); - tp->hitword=pl_rthit(tp->text, tp->yoffs, m->xy, ul); + tp->hitword=pl_rthit(tp->text, tp->offs, m->xy, ul); if(tp->hitword==0) if(oldhitword!=0 && oldstate==DOWN) tp->hitword=oldhitword; @@ -108,37 +118,63 @@ int pl_hittextview(Panel *p, Mouse *m){ return 0; } void pl_scrolltextview(Panel *p, int dir, int buttons, int num, int den){ - int yoffs; + int xoffs, yoffs; Point ul, size; Textview *tp; Rectangle r; - if(dir!=VERT) return; tp=p->data; ul=p->r.min; size=subpt(p->r.max, p->r.min); pl_interior(p->state, &ul, &size); - switch(buttons){ - default: - SET(yoffs); - break; - case 1: /* left -- top moves to pointer */ - yoffs=(vlong)tp->yoffs-num*size.y/den; - if(yoffs<0) yoffs=0; - break; - case 2: /* middle -- absolute index of file */ - yoffs=(vlong)tp->thgt*num/den; - break; - case 4: /* right -- line pointed at moves to top */ - yoffs=tp->yoffs+(vlong)num*size.y/den; - if(yoffs>tp->thgt) yoffs=tp->thgt; - break; - } - if(yoffs!=tp->yoffs){ - r=pl_outline(p->b, p->r, p->state); - pl_rtredraw(p->b, r, tp->text, yoffs, tp->yoffs); - p->scr.pos.y=tp->yoffs=yoffs; - pl_setscrpos(p, tp, r); + if(dir==VERT){ + switch(buttons){ + default: + SET(yoffs); + break; + case 1: /* left -- top moves to pointer */ + yoffs=(vlong)tp->offs.y-num*size.y/den; + if(yoffs<0) yoffs=0; + break; + case 2: /* middle -- absolute index of file */ + yoffs=(vlong)tp->thgt*num/den; + break; + case 4: /* right -- line pointed at moves to top */ + yoffs=tp->offs.y+(vlong)num*size.y/den; + if(yoffs>tp->thgt) yoffs=tp->thgt; + break; + } + if(yoffs!=tp->offs.y){ + r=pl_outline(p->b, p->r, p->state); + pl_rtredraw(p->b, r, tp->text, + Pt(tp->offs.x, yoffs), tp->offs, dir); + p->scr.pos.y=tp->offs.y=yoffs; + pl_setscrpos(p, tp, r); + } + }else{ /* dir==HORIZ */ + switch(buttons){ + default: + SET(xoffs); + break; + case 1: /* left */ + xoffs=(vlong)tp->offs.x-num*size.x/den; + if(xoffs<0) xoffs=0; + break; + case 2: /* middle */ + xoffs=(vlong)tp->maxwid*num/den; + break; + case 4: /* right */ + xoffs=tp->offs.x+(vlong)num*size.x/den; + if(xoffs>tp->maxwid) xoffs=tp->maxwid; + break; + } + if(xoffs!=tp->offs.x){ + r=pl_outline(p->b, p->r, p->state); + pl_rtredraw(p->b, r, tp->text, + Pt(xoffs, tp->offs.y), tp->offs, dir); + p->scr.pos.x=tp->offs.x=xoffs; + pl_setscrpos(p, tp, r); + } } } void pl_typetextview(Panel *g, Rune c){ @@ -162,7 +198,7 @@ int pl_pritextview(Panel *p, Point xy){ ul=p->r.min; size=subpt(p->r.max, p->r.min); pl_interior(p->state, &ul, &size); - h=pl_rthit(tp->text, tp->yoffs, xy, ul); + h=pl_rthit(tp->text, tp->offs, xy, ul); if(h && h->b==0 && h->p!=0){ p=pl_ptinpanel(xy, h->p); if(p) return p->pri(p, xy); @@ -189,12 +225,13 @@ void plinittextview(Panel *v, int flags, Point minsize, Rtext *t, void (*hit)(Pa tp->hit=hit; tp->minsize=minsize; tp->text=t; - tp->yoffs=0; + tp->offs=ZP; tp->hitfirst=0; tp->hitword=0; v->scroll=pl_scrolltextview; v->snarf=pl_snarftextview; tp->twid=-1; + tp->maxwid=0; v->scr.pos=Pt(0,0); v->scr.size=Pt(0,1); } @@ -205,9 +242,9 @@ Panel *pltextview(Panel *parent, int flags, Point minsize, Rtext *t, void (*hit) return v; } int plgetpostextview(Panel *p){ - return ((Textview *)p->data)->yoffs; + return ((Textview *)p->data)->offs.y; } void plsetpostextview(Panel *p, int yoffs){ - ((Textview *)p->data)->yoffs=yoffs; + ((Textview *)p->data)->offs.y=yoffs; pldraw(p, p->b); } diff --git a/sys/src/cmd/mothra/mothra.c b/sys/src/cmd/mothra/mothra.c index c1faf8ffd..44f94e23f 100644 --- a/sys/src/cmd/mothra/mothra.c +++ b/sys/src/cmd/mothra/mothra.c @@ -15,6 +15,8 @@ int debug=0; int verbose=0; /* -v flag causes html errors to be written to file-descriptor 2 */ int defdisplay=1; /* is the default (initial) display visible? */ +int visxbar=0; /* horizontal scrollbar visible? */ +int topxbar=0; /* horizontal scrollbar at top? */ Panel *root; /* the whole display */ Panel *alt; /* the alternate display */ Panel *alttext; /* the alternate text window */ @@ -152,16 +154,46 @@ void scrolltext(int dy, int whence) s.pos.y = s.size.y+dy; break; } - if(s.pos.y < 0) - s.pos.y = 0; if(s.pos.y > s.size.y) s.pos.y = s.size.y; + if(s.pos.y < 0) + s.pos.y = 0; + plsetscroll(text, s); +} + +void sidescroll(int dx, int whence) +{ + Scroll s; + + s = plgetscroll(text); + switch(whence){ + case 0: + s.pos.x = dx; + break; + case 1: + s.pos.x += dx; + break; + case 2: + s.pos.x = s.size.x+dx; + break; + } + if(s.pos.x > s.size.x - text->size.x + 5) + s.pos.x = s.size.x - text->size.x + 5; + if(s.pos.x < 0) + s.pos.x = 0; plsetscroll(text, s); } void mkpanels(void){ - Panel *p, *bar, *swap; + Panel *p, *xbar, *ybar, *swap; + int xflags; + if(topxbar) + xflags=PACKN|USERFL; + else + xflags=PACKS|USERFL; + if(!visxbar) + xflags|=IGNORE; menu3=plmenu(0, 0, buttons, PACKN|FILLX, hit3); root=plpopup(root, EXPAND, 0, 0, menu3); p=plgroup(root, PACKN|FILLX); @@ -170,23 +202,24 @@ void mkpanels(void){ pllabel(p, PACKW, "Go:"); cmd=plentry(p, PACKN|FILLX, 0, "", docmd); p=plgroup(root, PACKN|FILLX); - bar=plscrollbar(p, PACKW); + ybar=plscrollbar(p, PACKW); list=pllist(p, PACKN|FILLX, genwww, 8, doprev); - plscroll(list, 0, bar); + plscroll(list, 0, ybar); p=plgroup(root, PACKN|FILLX); pllabel(p, PACKW, "Url:"); cururl=pllabel(p, PACKE|EXPAND, "---"); plplacelabel(cururl, PLACEW); p=plgroup(root, PACKN|EXPAND); - bar=plscrollbar(p, PACKW|USERFL); + ybar=plscrollbar(p, PACKW|USERFL); + xbar=plscrollbar(p, xflags); text=pltextview(p, PACKE|EXPAND, Pt(0, 0), 0, dolink); - plscroll(text, 0, bar); + plscroll(text, xbar, ybar); plgrabkb(cmd); alt=plpopup(0, PACKE|EXPAND, 0, 0, menu3); - bar=plscrollbar(alt, PACKW|USERFL); + ybar=plscrollbar(alt, PACKW|USERFL); + xbar=plscrollbar(alt, xflags); alttext=pltextview(alt, PACKE|EXPAND, Pt(0, 0), 0, dolink); - plscroll(alttext, 0, bar); - + plscroll(alttext, xbar, ybar); if(!defdisplay){ swap=root; root=alt; @@ -318,11 +351,11 @@ void main(int argc, char *argv[]){ plinit(screen->depth); if(debug) notify(dienow); getfonts(); - hrule=allocimage(display, Rect(0, 0, 2048, 5), screen->chan, 0, DWhite); + hrule=allocimage(display, Rect(0, 0, 1, 5), screen->chan, 1, DWhite); if(hrule==0) sysfatal("can't allocimage!"); - draw(hrule, Rect(0,1,1280,3), display->black, 0, ZP); - linespace=allocimage(display, Rect(0, 0, 2048, 5), screen->chan, 0, DWhite); + draw(hrule, Rect(0,1,1,3), display->black, 0, ZP); + linespace=allocimage(display, Rect(0, 0, 1, 5), screen->chan, 1, DWhite); if(linespace==0) sysfatal("can't allocimage!"); bullet=allocimage(display, Rect(0,0,25, 8), screen->chan, 0, DWhite); @@ -390,6 +423,12 @@ void main(int argc, char *argv[]){ case Kack: search(); break; + case Kright: + sidescroll(text->size.x/4, 1); + break; + case Kleft: + sidescroll(-text->size.x/4, 1); + break; } break; case Emouse: |