diff options
| author | Quentin Carbonneaux | 2014-08-24 21:50:39 -0400 |
|---|---|---|
| committer | Quentin Carbonneaux | 2014-08-24 21:50:39 -0400 |
| commit | fad898d3866ed1f9879284dba53cd30e80c5d00d (patch) | |
| tree | ad134fb51a6b805ab229e2e2b839b7cce94203d3 | |
| parent | 4bdd10f6677c953995d32142150748aaf178ea7f (diff) | |
lift mouse code for multi windows
| -rw-r--r-- | main.c | 29 | ||||
| -rw-r--r-- | win.c | 63 | ||||
| -rw-r--r-- | win.h | 2 |
3 files changed, 56 insertions, 38 deletions
@@ -28,6 +28,7 @@ static int gev(int fd, int flag, void *unused) { static unsigned selbeg; + unsigned pos; GEvent e; (void) fd; @@ -50,8 +51,8 @@ gev(int fd, int flag, void *unused) break; case GMouseDown: if (e.mouse.button == GBLeft) { - win_set_cursor(curwin, e.mouse.x, e.mouse.y); - selbeg = curwin->cu; + win_locus(e.mouse.x, e.mouse.y, &pos); + selbeg = pos; goto Select; } else if (e.mouse.button == GBWheelUp) { win_scroll(curwin, -4); @@ -60,22 +61,26 @@ gev(int fd, int flag, void *unused) } break; case GMouseSelect: - win_set_cursor(curwin, e.mouse.x, e.mouse.y); - if (selbeg != -1u && curwin->cu != selbeg) { + win_locus(e.mouse.x, e.mouse.y, &pos); + if (selbeg != -1u && pos != selbeg) { eb_setmark(curwin->eb, SelBeg, selbeg); - eb_setmark(curwin->eb, SelEnd, curwin->cu); + eb_setmark(curwin->eb, SelEnd, pos); } goto Select; default: break; } - selbeg = -1u; - Select: - - if (curwin->cu >= curwin->l[curwin->nl]) - curwin->cu = curwin->l[curwin->nl-1]; - if (curwin->cu < curwin->l[0]) - curwin->cu = curwin->l[0]; + if (0) { + Select: + curwin->cu = pos; + curwin->rev = 0; + } else { + selbeg = -1u; + if (curwin->cu >= curwin->l[curwin->nl]) + curwin->cu = curwin->l[curwin->nl-1]; + if (curwin->cu < curwin->l[0]) + curwin->cu = curwin->l[0]; + } } win_redraw_frame(); @@ -107,6 +107,44 @@ win_delete(W *w) memset(w, 0, sizeof(W)); w->eb = 0; // FIXME, create an invariant such that win_new can be simplified + // also, do not delete if only one window is left +} + +/* win_locus - Find a window on the screen at position [x1], + * [y1]. If the argument pointer is non null, it is used to + * store the position of the pointed rune. + */ +W * +win_locus(int x1, int y1, unsigned *pos) +{ + W *w; + int i, x; + unsigned p; + + for (i=0, x=0; (w = screen[i]); i++) + if (x <= x1 && x1 < x + w->gr.w) + break; + else + x += w->gr.w + g->border; + if (tag.visible && tag.owner == w) + if (y1 >= tag.win.gr.y) + w = &tag.win; + if (!pos || !w) + return w; + y1 = (y1 - g->vmargin - w->gr.y) / font.height; + if (y1 < 0 || y1 >= w->nl) { + *pos = -1u; + return w; + } + p = w->l[y1]; + x = w->gr.x; + for (; p < w ->l[y1+1] - 1; p++) { + x += runewidth(buf_get(&w->eb->b, p), x); + if (x + g->hmargin >= x1) + break; + } + *pos = p; + return w; } /* win_resize_frame - Called when the whole frame @@ -207,31 +245,6 @@ win_scroll(W *w, int n) win_update(w); } -/* win_set_cursor - Changes the cursor of [w] to be on - * on the rune displayed at position [x], [y]. The window - * [w] is marked for redraw. - */ -void -win_set_cursor(W *w, int x, int y) -{ - int lx; - unsigned p; - - y = (y - g->vmargin - w->gr.y) / font.height; - if (y < 0 || y >= w->nl) - return; - - p = w->l[y]; - lx = w->gr.x; - for (; p < w ->l[y+1] - 1; p++) { - lx += runewidth(buf_get(&w->eb->b, p), lx); - if (lx + g->hmargin >= x) - break; - } - w->rev = 0; - w->cu = p; -} - /* win_show_cursor - Find the cursor in [w] and adjust * the text view so that the cursor is displayed on the * screen. Depending on [where], the cursor will be @@ -35,10 +35,10 @@ enum CursorLoc { CTop, CMid, CBot }; void win_init(struct gui *g); W *win_new(EBuf *eb); void win_delete(W *); +W *win_locus(int, int, unsigned *); void win_resize_frame(int w, int h); void win_redraw_frame(void); void win_scroll(W *, int); -void win_set_cursor(W *, int, int); void win_show_cursor(W *, enum CursorLoc); W *win_tag_toggle(W *); W *win_text(W *); |
