tacme: mouse movement for Del - 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 37f8ed2410ad5cbd46eda00a77f8bf4950bcf544
 (DIR) parent 9dbe4a0df903ee76bf72fcaff43dea5bb5bf3f75
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Sun, 23 Sep 2012 22:01:56 -0400
       
       acme: mouse movement for Del
       
       If the mouse was in the tag of the old window,
       it was most likely pointing at Del. If bringing up a
       new window from below and not moving the mouse
       somewhere else, adjust it so that it ends up pointing
       at Del in the replacement window's tag too.
       This makes it easy to Del a sequence of windows in
       a column, from top to bottom.
       
       http://www.youtube.com/watch?v=ET8w6RT6u5M
       
       R=r
       http://codereview.appspot.com/6558047
       
       Diffstat:
         M src/cmd/acme/cols.c                 |      15 +++++++++++----
         M src/cmd/acme/dat.h                  |       1 +
         M src/cmd/acme/fns.h                  |       3 ++-
         M src/cmd/acme/util.c                 |      10 ++++++++--
         M src/cmd/acme/wind.c                 |      41 ++++++++++++++++++++++++++++++-
       
       5 files changed, 62 insertions(+), 8 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/acme/cols.c b/src/cmd/acme/cols.c
       t@@ -157,7 +157,7 @@ void
        colclose(Column *c, Window *w, int dofree)
        {
                Rectangle r;
       -        int i;
       +        int i, didmouse, up;
        
                /* w is locked */
                if(!c->safe)
       t@@ -171,7 +171,7 @@ colclose(Column *c, Window *w, int dofree)
                w->tag.col = nil;
                w->body.col = nil;
                w->col = nil;
       -        restoremouse(w);
       +        didmouse = restoremouse(w);
                if(dofree){
                        windelete(w);
                        winclose(w);
       t@@ -183,17 +183,24 @@ colclose(Column *c, Window *w, int dofree)
                        draw(screen, r, display->white, nil, ZP);
                        return;
                }
       +        up = 0;
                if(i == c->nw){                /* extend last window down */
                        w = c->w[i-1];
                        r.min.y = w->r.min.y;
                        r.max.y = c->r.max.y;
                }else{                        /* extend next window up */
       +                up = 1;
                        w = c->w[i];
                        r.max.y = w->r.max.y;
                }
                draw(screen, r, textcols[BACK], nil, ZP);
       -        if(c->safe)
       +        if(c->safe) {
       +                if(!didmouse && up)
       +                        w->showdel = TRUE;
                        winresize(w, r, FALSE, TRUE);
       +                if(!didmouse && up)
       +                        movetodel(w);
       +        }
        }
        
        void
       t@@ -535,7 +542,7 @@ coldragwin(Column *c, Window *w, int but)
                        r.max.y = c->w[i+1]->r.min.y-Border;
                winresize(w, r, c->safe, TRUE);
                c->safe = TRUE;
       -            winmousebut(w);
       +        winmousebut(w);
        }
        
        Text*
 (DIR) diff --git a/src/cmd/acme/dat.h b/src/cmd/acme/dat.h
       t@@ -239,6 +239,7 @@ struct Window
                uchar        filemenu;
                uchar        dirty;
                uchar        autoindent;
       +        uchar        showdel;
                int                id;
                Range        addr;
                Range        limit;
 (DIR) diff --git a/src/cmd/acme/fns.h b/src/cmd/acme/fns.h
       t@@ -22,10 +22,11 @@ void        new(Text*, Text*, Text*, int, int, Rune*, int);
        void        undo(Text*, Text*, Text*, int, int, Rune*, int);
        void        scrsleep(uint);
        void        savemouse(Window*);
       -void        restoremouse(Window*);
       +int        restoremouse(Window*);
        void        clearmouse(void);
        void        allwindows(void(*)(Window*, void*), void*);
        uint loadfile(int, uint, int*, int(*)(void*, uint, Rune*, int), void*);
       +void        movetodel(Window*);
        
        Window*        errorwin(Mntdir*, int);
        Window*        errorwinforwin(Window*);
 (DIR) diff --git a/src/cmd/acme/util.c b/src/cmd/acme/util.c
       t@@ -383,12 +383,18 @@ savemouse(Window *w)
                mousew = w;
        }
        
       -void
       +int
        restoremouse(Window *w)
        {
       -        if(mousew!=nil && mousew==w)
       +        int did;
       +
       +        did = 0;
       +        if(mousew!=nil && mousew==w) {
                        moveto(mousectl, prevmouse);
       +                did = 1;
       +        }
                mousew = nil;
       +        return did;
        }
        
        void
 (DIR) diff --git a/src/cmd/acme/wind.c b/src/cmd/acme/wind.c
       t@@ -106,6 +106,34 @@ windrawbutton(Window *w)
                draw(screen, br, b, nil, b->r.min);
        }
        
       +int
       +delrunepos(Window *w)
       +{
       +        int n;
       +        Rune rune;
       +        
       +        for(n=0; n<w->tag.file->b.nc; n++) {
       +                bufread(&w->tag.file->b, n, &rune, 1);
       +                if(rune == ' ')
       +                        break;
       +        }
       +        n += 2;
       +        if(n >= w->tag.file->b.nc)
       +                return -1;
       +        return n;
       +}
       +
       +void
       +movetodel(Window *w)
       +{
       +        int n;
       +        
       +        n = delrunepos(w);
       +        if(n < 0)
       +                return;
       +        moveto(mousectl, addpt(frptofchar(&w->tag.fr, n), Pt(4, w->tag.fr.font->height-4)));
       +}
       +
        /*
         * Compute number of tag lines required
         * to display entire tag text.
       t@@ -115,14 +143,25 @@ wintaglines(Window *w, Rectangle r)
        {
                int n;
                Rune rune;
       +        Point p;
        
       -        if(!w->tagexpand)
       +        if(!w->tagexpand && !w->showdel)
                        return 1;
       +        w->showdel = FALSE;
                w->tag.fr.noredraw = 1;
                textresize(&w->tag, r, TRUE);
                w->tag.fr.noredraw = 0;
                w->tagsafe = FALSE;
                
       +        if(!w->tagexpand) {
       +                /* use just as many lines as needed to show the Del */
       +                n = delrunepos(w);
       +                if(n < 0)
       +                        return 1;
       +                p = subpt(frptofchar(&w->tag.fr, n), w->tag.fr.r.min);
       +                return 1 + p.y / w->tag.fr.font->height;
       +        }
       +                
                /* can't use more than we have */
                if(w->tag.fr.nlines >= w->tag.fr.maxlines)
                        return w->tag.fr.maxlines;