tacme: mouse movement for Del - plan9port - [fork] Plan 9 from user space
HTML git clone git://src.adamsgaard.dk/plan9port
DIR Log
DIR Files
DIR Refs
DIR README
DIR LICENSE
---
DIR commit 37f8ed2410ad5cbd46eda00a77f8bf4950bcf544
DIR parent 9dbe4a0df903ee76bf72fcaff43dea5bb5bf3f75
HTML 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;