tCleanup in preparation for multiline tags. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 33dc4226a8c21e640bc1b4d7c56f41e2f0bdcc3f
 (DIR) parent a47fbb16412bbec1507d00be3cade04cce2536fe
 (HTM) Author: rsc <devnull@localhost>
       Date:   Mon, 31 Oct 2005 18:39:19 +0000
       
       Cleanup in preparation for multiline tags.
       
       Diffstat:
         M src/cmd/acme/cols.c                 |      89 ++++++++++++-------------------
         M src/cmd/acme/dat.h                  |       8 ++++++--
         M src/cmd/acme/exec.c                 |       2 +-
         M src/cmd/acme/rows.c                 |       2 +-
         M src/cmd/acme/text.c                 |      23 +++++++++++++----------
         M src/cmd/acme/wind.c                 |      78 +++++++++++++++++++++----------
       
       6 files changed, 110 insertions(+), 92 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/acme/cols.c b/src/cmd/acme/cols.c
       t@@ -86,9 +86,9 @@ coladd(Column *c, Window *w, Window *clone, int y)
                        r.max.y = t;
                        draw(screen, r, textcols[BACK], nil, ZP);
                        r1 = r;
       -                y = min(y, t-(v->tag.fr.font->height+v->body.fr.font->height+Border+1));
       +                y = min(y, t-(v->tag.fr.font->height*v->taglines+v->body.fr.font->height+Border+1));
                        r1.max.y = min(y, v->body.fr.r.min.y+v->body.fr.nlines*v->body.fr.font->height);
       -                r1.min.y = winresize(v, r1, FALSE);
       +                r1.min.y = winresize(v, r1, FALSE, FALSE);
                        r1.max.y = r1.min.y+Border;
                        draw(screen, r1, display->black, nil, ZP);
                        r.min.y = r1.max.y;
       t@@ -100,9 +100,8 @@ coladd(Column *c, Window *w, Window *clone, int y)
                        wininit(w, clone, r);
                }else{
                        w->col = c;
       -                winresize(w, r, FALSE);
       +                winresize(w, r, FALSE, TRUE);
                }
       -//assert(w->body.w == w);
                w->tag.col = c;
                w->tag.row = c->row;
                w->body.col = c;
       t@@ -159,7 +158,7 @@ colclose(Column *c, Window *w, int dofree)
                }
                draw(screen, r, textcols[BACK], nil, ZP);
                if(c->safe)
       -                winresize(w, r, FALSE);
       +                winresize(w, r, FALSE, TRUE);
        }
        
        void
       t@@ -197,7 +196,7 @@ colresize(Column *c, Rectangle r)
                clearmouse();
                r1 = r;
                r1.max.y = r1.min.y + c->tag.fr.font->height;
       -        textresize(&c->tag, r1);
       +        textresize(&c->tag, r1, TRUE);
                draw(screen, c->tag.scrollr, colbutton, nil, colbutton->r.min);
                r1.min.y = r1.max.y;
                r1.max.y += Border;
       t@@ -214,7 +213,7 @@ colresize(Column *c, Rectangle r)
                        r2.max.y = r2.min.y+Border;
                        draw(screen, r2, display->black, nil, ZP);
                        r1.min.y = r2.max.y;
       -                r1.min.y = winresize(w, r1, FALSE);
       +                r1.min.y = winresize(w, r1, FALSE, i==c->nw-1);
                }
                c->r = r;
        }
       t@@ -270,7 +269,7 @@ colsort(Column *c)
                        r1.max.y = r1.min.y+Border;
                        draw(screen, r1, display->black, nil, ZP);
                        r.min.y = r1.max.y;
       -                y = winresize(w, r, FALSE);
       +                y = winresize(w, r, FALSE, TRUE);
                }
                free(rp);
                free(c->w);
       t@@ -297,7 +296,7 @@ colgrow(Column *c, Window *w, int but)
                                r.max.y = cr.max.y;
                        else
                                r.max.y = c->w[i+1]->r.min.y;
       -                winresize(w, r, FALSE);
       +                winresize(w, r, FALSE, TRUE);
                        return;
                }
                cr.min.y = c->w[0]->r.min.y;
       t@@ -308,7 +307,7 @@ colgrow(Column *c, Window *w, int but)
                                c->w[i] = v;
                        }
                        draw(screen, cr, textcols[BACK], nil, ZP);
       -                winresize(w, cr, FALSE);
       +                winresize(w, cr, FALSE, TRUE);
                        for(i=1; i<c->nw; i++)
                                c->w[i]->body.fr.maxlines = 0;
                        c->safe = FALSE;
       t@@ -320,7 +319,7 @@ colgrow(Column *c, Window *w, int but)
                ny = emalloc(c->nw * sizeof(int));
                tot = 0;
                for(j=0; j<c->nw; j++){
       -                l = c->w[j]->body.fr.maxlines;
       +                l = c->w[j]->taglines-1 + c->w[j]->body.fr.maxlines;
                        nl[j] = l;
                        tot += l;
                }
       t@@ -329,9 +328,9 @@ colgrow(Column *c, Window *w, int but)
                        memset(nl, 0, c->nw * sizeof(int));
                        goto Pack;
                }
       -        nnl = min(onl + max(min(5, w->maxlines), onl/2), tot);
       -        if(nnl < w->maxlines)
       -                nnl = (w->maxlines+nnl)/2;
       +        nnl = min(onl + max(min(5, w->taglines-1+w->maxlines), onl/2), tot);
       +        if(nnl < w->taglines-1+w->maxlines)
       +                nnl = (w->taglines-1+w->maxlines+nnl)/2;
                if(nnl == 0)
                        nnl = 2;
                dnl = nnl - onl;
       t@@ -361,14 +360,10 @@ colgrow(Column *c, Window *w, int but)
                        v = c->w[j];
                        r = v->r;
                        r.min.y = y1;
       -                r.max.y = y1+Dy(v->tag.all);
       +                r.max.y = y1+Dy(v->tagtop);
                        if(nl[j])
                                r.max.y += 1 + nl[j]*v->body.fr.font->height;
       -                if(!c->safe || !eqrect(v->r, r)){
       -                        draw(screen, r, textcols[BACK], nil, ZP);
       -                        winresize(v, r, c->safe);
       -                }
       -                r.min.y = v->r.max.y;
       +                r.min.y = winresize(v, r, c->safe, FALSE);
                        r.max.y += Border;
                        draw(screen, r, display->black, nil, ZP);
                        y1 = r.max.y;
       t@@ -378,7 +373,7 @@ colgrow(Column *c, Window *w, int but)
                for(j=c->nw-1; j>i; j--){
                        v = c->w[j];
                        r = v->r;
       -                r.min.y = y2-Dy(v->tag.all);
       +                r.min.y = y2-Dy(v->tagtop);
                        if(nl[j])
                                r.min.y -= 1 + nl[j]*v->body.fr.font->height;
                        r.min.y -= Border;
       t@@ -388,17 +383,12 @@ colgrow(Column *c, Window *w, int but)
                /* compute new size of window */
                r = w->r;
                r.min.y = y1;
       -        r.max.y = r.min.y+Dy(w->tag.all);
       +        r.max.y = y2;
                h = w->body.fr.font->height;
       -        if(y2-r.max.y >= 1+h+Border){
       -                r.max.y += 1;
       -                r.max.y += h*((y2-r.max.y)/h);
       -        }
       +        if(Dy(r) < Dy(w->tagtop)+1+h+Border)
       +                r.max.y = r.min.y+Dy(w->tagtop)+1+h+Border;
                /* draw window */
       -        if(!c->safe || !eqrect(w->r, r)){
       -                draw(screen, r, textcols[BACK], nil, ZP);
       -                winresize(w, r, c->safe);
       -        }
       +        winresize(w, r, c->safe, TRUE);
                if(i < c->nw-1){
                        r.min.y = r.max.y;
                        r.max.y += Border;
       t@@ -415,21 +405,20 @@ colgrow(Column *c, Window *w, int but)
                        r.max.y = y1+Dy(v->tag.all);
                        if(nl[j])
                                r.max.y += 1 + nl[j]*v->body.fr.font->height;
       -                if(!c->safe || !eqrect(v->r, r)){
       -                        draw(screen, r, textcols[BACK], nil, ZP);
       -                        winresize(v, r, c->safe);
       -                }
       +                y1 = winresize(v, r, c->safe, j+1==c->nw);
                        if(j < c->nw-1){        /* no border on last window */
       -                        r.min.y = v->r.max.y;
       +                        r.min.y = y1;
                                r.max.y += Border;
                                draw(screen, r, display->black, nil, ZP);
       +                        y1 = r.max.y;
                        }
       -                y1 = r.max.y;
                }
       +/*
                r = w->r;
                r.min.y = y1;
                r.max.y = c->r.max.y;
                draw(screen, r, textcols[BACK], nil, ZP);
       +*/
                free(nl);
                free(ny);
                c->safe = TRUE;
       t@@ -493,10 +482,10 @@ coldragwin(Column *c, Window *w, int but)
                if(i == 0)
                        return;
                v = c->w[i-1];
       -        if(p.y < v->tag.all.max.y)
       -                p.y = v->tag.all.max.y;
       -        if(p.y > w->r.max.y-Dy(w->tag.all)-Border)
       -                p.y = w->r.max.y-Dy(w->tag.all)-Border;
       +        if(p.y < v->tagtop.max.y)
       +                p.y = v->tagtop.max.y;
       +        if(p.y > w->r.max.y-Dy(w->tagtop)-Border)
       +                p.y = w->r.max.y-Dy(w->tagtop)-Border;
                r = v->r;
                r.max.y = p.y;
                if(r.max.y > v->body.fr.r.min.y){
       t@@ -504,11 +493,7 @@ coldragwin(Column *c, Window *w, int but)
                        if(v->body.fr.r.min.y == v->body.fr.r.max.y)
                                r.max.y++;
                }
       -        if(!eqrect(v->r, r)){
       -                draw(screen, r, textcols[BACK], nil, ZP);
       -                winresize(v, r, c->safe);
       -        }
       -        r.min.y = v->r.max.y;
       +        r.min.y = winresize(v, r, c->safe, FALSE);
                r.max.y = r.min.y+Border;
                draw(screen, r, display->black, nil, ZP);
                r.min.y = r.max.y;
       t@@ -516,10 +501,7 @@ coldragwin(Column *c, Window *w, int but)
                        r.max.y = c->r.max.y;
                else
                        r.max.y = c->w[i+1]->r.min.y-Border;
       -        if(!eqrect(w->r, r)){
       -                draw(screen, r, textcols[BACK], nil, ZP);
       -                winresize(w, r, c->safe);
       -        }
       +        winresize(w, r, c->safe, i+1==c->nw);
                c->safe = TRUE;
                    winmousebut(w);
        }
       t@@ -537,13 +519,12 @@ colwhich(Column *c, Point p)
                for(i=0; i<c->nw; i++){
                        w = c->w[i];
                        if(ptinrect(p, w->r)){
       -                        if(ptinrect(p, w->tag.all))
       +                        if(ptinrect(p, w->tagtop) || ptinrect(p, w->tag.fr.r))
                                        return &w->tag;
       -                        return &w->body;
       +                        if(ptinrect(p, w->body.scrollr) || ptinrect(p, w->body.fr.r))
       +                                return &w->body;
       +                        return nil;
                        }
       -                /* scrollr drops below w->r on low windows */
       -                if(ptinrect(p, w->body.scrollr))
       -                        return &w->body;
                }
                return nil;
        }
 (DIR) diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h
       t@@ -212,7 +212,7 @@ uint                textload(Text*, uint, char*, int);
        Rune                textreadc(Text*, uint);
        void                textredraw(Text*, Rectangle, Font*, Image*, int);
        void                textreset(Text*);
       -int                textresize(Text*, Rectangle);
       +int                textresize(Text*, Rectangle, int);
        void                textscrdraw(Text*);
        void                textscroll(Text*, int);
        void                textselect(Text*);
       t@@ -264,6 +264,10 @@ struct Window
                int                utflastqid;
                int                utflastboff;
                int                utflastq;
       +        int                tagsafe;                /* taglines is correct */
       +        int                tagexpand;
       +        int                taglines;
       +        Rectangle        tagtop;
        };
        
        void        wininit(Window*, Window*, Rectangle);
       t@@ -276,7 +280,7 @@ void        winsetname(Window*, Rune*, int);
        void        winsettag(Window*);
        void        winsettag1(Window*);
        void        wincommit(Window*, Text*);
       -int        winresize(Window*, Rectangle, int);
       +int        winresize(Window*, Rectangle, int, int);
        void        winclose(Window*);
        void        windelete(Window*);
        int        winclean(Window*, int);
 (DIR) diff --git a/src/cmd/acme/exec.c b/src/cmd/acme/exec.c
       t@@ -1289,7 +1289,7 @@ tab(Text *et, Text *_0, Text *argt, int _1, int _2, Rune *arg, int narg)
                if(tab > 0){
                        if(w->body.tabstop != tab){
                                w->body.tabstop = tab;
       -                        winresize(w, w->r, 1);
       +                        winresize(w, w->r, TRUE, TRUE);
                        }
                }else
                        warning(nil, "%.*S: Tab %d\n", w->body.file->nname, w->body.file->name, w->body.tabstop);
 (DIR) diff --git a/src/cmd/acme/rows.c b/src/cmd/acme/rows.c
       t@@ -111,7 +111,7 @@ rowresize(Row *row, Rectangle r)
                row->r = r;
                r1 = r;
                r1.max.y = r1.min.y + font->height;
       -        textresize(&row->tag, r1);
       +        textresize(&row->tag, r1, TRUE);
                r1.min.y = r1.max.y;
                r1.max.y += Border;
                draw(screen, r1, display->black, nil, ZP);
 (DIR) diff --git a/src/cmd/acme/text.c b/src/cmd/acme/text.c
       t@@ -69,23 +69,26 @@ textredraw(Text *t, Rectangle r, Font *f, Image *b, int odx)
        }
        
        int
       -textresize(Text *t, Rectangle r)
       +textresize(Text *t, Rectangle r, int keepextra)
        {
       -        int odx;
       -
       -        if(Dy(r) > 0)
       -                r.max.y -= Dy(r)%t->fr.font->height;
       -        else
       +        if(Dy(r) <= 0)
                        r.max.y = r.min.y;
       -        odx = Dx(t->all);
       +        if(!keepextra)
       +                r.max.y -= Dy(r)%t->fr.font->height;
                t->all = r;
                t->scrollr = r;
                t->scrollr.max.x = r.min.x+Scrollwid;
                t->lastsr = nullrect;
                r.min.x += Scrollwid+Scrollgap;
                frclear(&t->fr, 0);
       -        textredraw(t, r, t->fr.font, screen, odx);
       -        return r.max.y;
       +        textredraw(t, r, t->fr.font, screen, Dx(t->all));
       +        if(keepextra && t->fr.r.max.y < t->all.max.y){
       +                r.min.x -= Scrollgap;
       +                r.min.y = t->fr.r.max.y;
       +                r.max.y = t->all.max.y;
       +                draw(screen, r, t->fr.cols[BACK], nil, ZP);
       +        }
       +        return t->all.max.y;
        }
        
        void
       t@@ -279,7 +282,7 @@ textload(Text *t, uint q0, char *file, int setqid)
                        if(u != t){
                                if(u->org > u->file->b.nc)        /* will be 0 because of reset(), but safety first */
                                        u->org = 0;
       -                        textresize(u, u->all);
       +                        textresize(u, u->all, TRUE);
                                textbacknl(u, u->org, 0);        /* go to beginning of line */
                        }
                        textsetselect(u, q0, q0);
 (DIR) diff --git a/src/cmd/acme/wind.c b/src/cmd/acme/wind.c
       t@@ -23,6 +23,7 @@ wininit(Window *w, Window *clone, Rectangle r)
                int nc;
        
                w->tag.w = w;
       +        w->taglines = 1;
                w->body.w = w;
                w->id = ++winid;
                incref(&w->ref);
       t@@ -31,7 +32,11 @@ wininit(Window *w, Window *clone, Rectangle r)
                w->ctlfid = ~0;
                w->utflastqid = -1;
                r1 = r;
       -        r1.max.y = r1.min.y + font->height;
       +        
       +        w->tagtop = r;
       +        w->tagtop.max.y = r.min.y + font->height;
       +        
       +        r1.max.y = r1.min.y + w->taglines*font->height;
                incref(&reffont.ref);
                f = fileaddtext(nil, &w->tag);
                textinit(&w->tag, f, r1, &reffont, tagcols);
       t@@ -49,7 +54,7 @@ wininit(Window *w, Window *clone, Rectangle r)
                }
        //assert(w->body.w == w);
                r1 = r;
       -        r1.min.y += font->height + 1;
       +        r1.min.y += w->taglines*font->height + 1;
                if(r1.max.y < r1.min.y)
                        r1.max.y = r1.min.y;
                f = nil;
       t@@ -69,7 +74,6 @@ wininit(Window *w, Window *clone, Rectangle r)
                draw(screen, r1, tagcols[BORD], nil, ZP);
                textscrdraw(&w->body);
                w->r = r;
       -        w->r.max.y = w->body.fr.r.max.y;
                br.min = w->tag.scrollr.min;
                br.max.x = br.min.x + Dx(button->r);
                br.max.y = br.min.y + Dy(button->r);
       t@@ -86,19 +90,45 @@ wininit(Window *w, Window *clone, Rectangle r)
                }
        }
        
       +/*
       + * Compute number of tag lines required
       + * to display entire tag text.
       + */
       +int
       +wintaglines(Window *w, Rectangle r)
       +{
       +        int n;
       +        Rune rune;
       +
       +        if(!w->tagexpand)
       +                return 1;
       +        w->tag.fr.noredraw = 1;
       +        textresize(&w->tag, r, TRUE);
       +        w->tag.fr.noredraw = 0;
       +        if(w->tag.fr.nlines >= w->tag.fr.maxlines)
       +                return w->tag.fr.maxlines;
       +        n = w->tag.fr.nlines;
       +        bufread(&w->tag.file->b, w->tag.file->b.nc-1, &rune, 1);
       +        if(rune == '\n')
       +                n++;
       +        return n;
       +}
       +
        int
       -winresize(Window *w, Rectangle r, int safe)
       +winresize(Window *w, Rectangle r, int safe, int keepextra)
        {
       -        Rectangle r1;
                int y;
                Image *b;
       -        Rectangle br;
       +        Rectangle br, r1;
       +
       +        w->tagtop = r;
       +        w->tagtop.max.y = r.min.y+font->height;
        
                r1 = r;
       -        r1.max.y = r1.min.y + font->height;
       +        r1.max.y = min(r.max.y, r1.min.y + w->taglines*font->height);
                y = r1.max.y;
       -        if(!safe || !eqrect(w->tag.fr.r, r1)){
       -                y = textresize(&w->tag, r1);
       +        if(1 || !safe || !eqrect(w->tag.fr.r, r1)){
       +                y = textresize(&w->tag, r1, TRUE);
                        b = button;
                        if(w->body.file->mod && !w->isdir && !w->isscratch)
                                b = modbutton;
       t@@ -107,24 +137,23 @@ winresize(Window *w, Rectangle r, int safe)
                        br.max.y = br.min.y + Dy(b->r);
                        draw(screen, br, b, nil, b->r.min);
                }
       -        if(!safe || !eqrect(w->body.fr.r, r1)){
       -                if(y+1+font->height > r.max.y){                /* no body */
       +        
       +        r1 = r;
       +        r1.min.y = y;
       +        if(1 || !safe || !eqrect(w->body.fr.r, r1)){
       +                if(y+1+w->body.fr.font->height <= r.max.y){        /* room for one line */
       +                        r1.min.y = y;
       +                        r1.max.y = y+1;
       +                        draw(screen, r1, tagcols[BORD], nil, ZP);
       +                        y++;
       +                        r1.min.y = min(y, r.max.y);
       +                        r1.max.y = r.max.y;
       +                }else{
                                r1.min.y = y;
                                r1.max.y = y;
       -                        textresize(&w->body, r1);
       -                        w->r = r;
       -                        w->r.max.y = y;
       -                        return y;
                        }
       -                r1 = r;
       -                r1.min.y = y;
       -                r1.max.y = y + 1;
       -                draw(screen, r1, tagcols[BORD], nil, ZP);
       -                r1.min.y = y + 1;
       -                r1.max.y = r.max.y;
       -                y = textresize(&w->body, r1);
                        w->r = r;
       -                w->r.max.y = y;
       +                w->r.max.y = textresize(&w->body, r1, keepextra);
                        textscrdraw(&w->body);
                }
                w->maxlines = min(w->body.fr.nlines, max(w->maxlines, w->body.fr.maxlines));
       t@@ -173,7 +202,8 @@ winunlock(Window *w)
        void
        winmousebut(Window *w)
        {
       -        moveto(mousectl, divpt(addpt(w->tag.scrollr.min, w->tag.scrollr.max), 2));
       +        moveto(mousectl, addpt(w->tag.scrollr.min, 
       +                divpt(Pt(Dx(w->tag.scrollr), font->height), 2)));
        }
        
        void