diff options
author | Bram Moolenaar <Bram@vim.org> | 2010-07-25 15:49:07 +0200 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2010-07-25 15:49:07 +0200 |
commit | 8d9b40e71ab62f43c65a52225cb833ecc0d1bf6b (patch) | |
tree | a25e59faa9adfd7e352c407ded5beedf4242d1d2 /src | |
parent | 0fe849a13b4c0753d6b2424783879696a1fd4421 (diff) |
Add support for horizontal scroll wheel. (Bjorn Winckler)
Diffstat (limited to 'src')
-rw-r--r-- | src/edit.c | 46 | ||||
-rw-r--r-- | src/eval.c | 2 | ||||
-rw-r--r-- | src/ex_getln.c | 4 | ||||
-rw-r--r-- | src/gui.c | 117 | ||||
-rw-r--r-- | src/gui_gtk_x11.c | 8 | ||||
-rw-r--r-- | src/keymap.h | 7 | ||||
-rw-r--r-- | src/message.c | 1 | ||||
-rw-r--r-- | src/misc1.c | 2 | ||||
-rw-r--r-- | src/misc2.c | 8 | ||||
-rw-r--r-- | src/normal.c | 43 | ||||
-rw-r--r-- | src/proto/gui.pro | 2 | ||||
-rw-r--r-- | src/screen.c | 2 | ||||
-rw-r--r-- | src/term.c | 4 | ||||
-rw-r--r-- | src/vim.h | 12 |
14 files changed, 188 insertions, 70 deletions
diff --git a/src/edit.c b/src/edit.c index 3370a28f2d..4754fd9bde 100644 --- a/src/edit.c +++ b/src/edit.c @@ -224,7 +224,7 @@ static void ins_del __ARGS((void)); static int ins_bs __ARGS((int c, int mode, int *inserted_space_p)); #ifdef FEAT_MOUSE static void ins_mouse __ARGS((int c)); -static void ins_mousescroll __ARGS((int up)); +static void ins_mousescroll __ARGS((int dir)); #endif #if defined(FEAT_GUI_TABLINE) || defined(PROTO) static void ins_tabline __ARGS((int c)); @@ -1112,11 +1112,19 @@ doESCkey: break; case K_MOUSEDOWN: /* Default action for scroll wheel up: scroll up */ - ins_mousescroll(FALSE); + ins_mousescroll(MSCR_DOWN); break; case K_MOUSEUP: /* Default action for scroll wheel down: scroll down */ - ins_mousescroll(TRUE); + ins_mousescroll(MSCR_UP); + break; + + case K_MOUSELEFT: /* Scroll wheel left */ + ins_mousescroll(MSCR_LEFT); + break; + + case K_MOUSERIGHT: /* Scroll wheel right */ + ins_mousescroll(MSCR_RIGHT); break; #endif #ifdef FEAT_GUI_TABLINE @@ -3516,7 +3524,8 @@ ins_compl_prep(c) edit_submode_extra = NULL; /* Ignore end of Select mode mapping and mouse scroll buttons. */ - if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP) + if (c == K_SELECT || c == K_MOUSEDOWN || c == K_MOUSEUP + || c == K_MOUSELEFT || c == K_MOUSERIGHT) return retval; /* Set "compl_get_longest" when finding the first matches. */ @@ -8859,8 +8868,8 @@ ins_mouse(c) } static void -ins_mousescroll(up) - int up; +ins_mousescroll(dir) + int dir; { pos_T tpos; # if defined(FEAT_WINDOWS) @@ -8898,10 +8907,27 @@ ins_mousescroll(up) ) # endif { - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) - scroll_redraw(up, (long)(curwin->w_botline - curwin->w_topline)); + if (dir == MSCR_DOWN || dir == MSCR_UP) + { + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + scroll_redraw(dir, + (long)(curwin->w_botline - curwin->w_topline)); + else + scroll_redraw(dir, 3L); + } +#ifdef FEAT_GUI else - scroll_redraw(up, 3L); + { + int val, step = 6; + + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + step = W_WIDTH(curwin); + val = curwin->w_leftcol + (dir == MSCR_RIGHT ? -step : step); + if (val < 0) + val = 0; + gui_do_horiz_scroll(val, TRUE); + } +#endif # ifdef FEAT_INS_EXPAND did_scroll = TRUE; # endif @@ -8985,7 +9011,7 @@ ins_horscroll() undisplay_dollar(); tpos = curwin->w_cursor; - if (gui_do_horiz_scroll()) + if (gui_do_horiz_scroll(scrollbar_value, FALSE)) { start_arrow(&tpos); # ifdef FEAT_CINDENT diff --git a/src/eval.c b/src/eval.c index 4f1be3fa20..ac0ad26792 100644 --- a/src/eval.c +++ b/src/eval.c @@ -10927,6 +10927,8 @@ f_getchar(argvars, rettv) || n == K_X2MOUSE || n == K_X2DRAG || n == K_X2RELEASE + || n == K_MOUSELEFT + || n == K_MOUSERIGHT || n == K_MOUSEDOWN || n == K_MOUSEUP) { diff --git a/src/ex_getln.c b/src/ex_getln.c index 153271b5cc..7b7874ad4f 100644 --- a/src/ex_getln.c +++ b/src/ex_getln.c @@ -1334,6 +1334,8 @@ getcmdline(firstc, count, indent) /* Mouse scroll wheel: ignored here */ case K_MOUSEDOWN: case K_MOUSEUP: + case K_MOUSELEFT: + case K_MOUSERIGHT: /* Alternate buttons ignored here */ case K_X1MOUSE: case K_X1DRAG: @@ -1361,7 +1363,7 @@ getcmdline(firstc, count, indent) case K_HOR_SCROLLBAR: if (msg_scrolled == 0) { - gui_do_horiz_scroll(); + gui_do_horiz_scroll(scrollbar_value, FALSE); redrawcmd(); } goto cmdline_not_changed; @@ -31,6 +31,7 @@ static int gui_has_tabline __ARGS((void)); #endif static void gui_do_scrollbar __ARGS((win_T *wp, int which, int enable)); static colnr_T scroll_line_len __ARGS((linenr_T lnum)); +static linenr_T gui_find_longest_lnum __ARGS((void)); static void gui_update_horiz_scrollbar __ARGS((int)); static void gui_set_fg_color __ARGS((char_u *name)); static void gui_set_bg_color __ARGS((char_u *name)); @@ -2759,7 +2760,8 @@ fill_mouse_coord(p, col, row) * button --- may be any of MOUSE_LEFT, MOUSE_MIDDLE, MOUSE_RIGHT, * MOUSE_X1, MOUSE_X2 * MOUSE_DRAG, or MOUSE_RELEASE. - * MOUSE_4 and MOUSE_5 are used for a scroll wheel. + * MOUSE_4 and MOUSE_5 are used for vertical scroll wheel, + * MOUSE_6 and MOUSE_7 for horizontal scroll wheel. * x, y --- Coordinates of mouse in pixels. * repeated_click --- TRUE if this click comes only a short time after a * previous click. @@ -2803,6 +2805,12 @@ gui_send_mouse_event(button, x, y, repeated_click, modifiers) goto button_set; case MOUSE_5: button_char = KE_MOUSEUP; + goto button_set; + case MOUSE_6: + button_char = KE_MOUSELEFT; + goto button_set; + case MOUSE_7: + button_char = KE_MOUSERIGHT; button_set: { /* Don't put events in the input queue now. */ @@ -3845,14 +3853,14 @@ gui_drag_scrollbar(sb, value, still_dragging) scrollbar_value = value; if (State & NORMAL) - gui_do_horiz_scroll(); + gui_do_horiz_scroll(scrollbar_value, FALSE); else if (State & INSERT) ins_horscroll(); else if (State & CMDLINE) { if (msg_scrolled == 0) { - gui_do_horiz_scroll(); + gui_do_horiz_scroll(scrollbar_value, FALSE); redrawcmdline(); } } @@ -4319,6 +4327,51 @@ scroll_line_len(lnum) * search for it when scrolling horizontally. */ static linenr_T longest_lnum = 0; +/* + * Find longest visible line number. If this is not possible (or not desired, + * by setting 'h' in "guioptions") then the current line number is returned. + */ + static linenr_T +gui_find_longest_lnum() +{ + linenr_T ret = 0; + + /* Calculate maximum for horizontal scrollbar. Check for reasonable + * line numbers, topline and botline can be invalid when displaying is + * postponed. */ + if (vim_strchr(p_go, GO_HORSCROLL) == NULL + && curwin->w_topline <= curwin->w_cursor.lnum + && curwin->w_botline > curwin->w_cursor.lnum + && curwin->w_botline <= curbuf->b_ml.ml_line_count + 1) + { + linenr_T lnum; + colnr_T n; + long max = 0; + + /* Use maximum of all visible lines. Remember the lnum of the + * longest line, closest to the cursor line. Used when scrolling + * below. */ + for (lnum = curwin->w_topline; lnum < curwin->w_botline; ++lnum) + { + n = scroll_line_len(lnum); + if (n > (colnr_T)max) + { + max = n; + ret = lnum; + } + else if (n == (colnr_T)max + && abs((int)(lnum - curwin->w_cursor.lnum)) + < abs((int)(ret - curwin->w_cursor.lnum))) + ret = lnum; + } + } + else + /* Use cursor line only. */ + ret = curwin->w_cursor.lnum; + + return ret; +} + static void gui_update_horiz_scrollbar(force) int force; @@ -4358,38 +4411,9 @@ gui_update_horiz_scrollbar(force) { value = curwin->w_leftcol; - /* Calculate maximum for horizontal scrollbar. Check for reasonable - * line numbers, topline and botline can be invalid when displaying is - * postponed. */ - if (vim_strchr(p_go, GO_HORSCROLL) == NULL - && curwin->w_topline <= curwin->w_cursor.lnum - && curwin->w_botline > curwin->w_cursor.lnum - && curwin->w_botline <= curbuf->b_ml.ml_line_count + 1) - { - linenr_T lnum; - colnr_T n; + longest_lnum = gui_find_longest_lnum(); + max = scroll_line_len(longest_lnum); - /* Use maximum of all visible lines. Remember the lnum of the - * longest line, clostest to the cursor line. Used when scrolling - * below. */ - max = 0; - for (lnum = curwin->w_topline; lnum < curwin->w_botline; ++lnum) - { - n = scroll_line_len(lnum); - if (n > (colnr_T)max) - { - max = n; - longest_lnum = lnum; - } - else if (n == (colnr_T)max - && abs((int)(lnum - curwin->w_cursor.lnum)) - < abs((int)(longest_lnum - curwin->w_cursor.lnum))) - longest_lnum = lnum; - } - } - else - /* Use cursor line only. */ - max = scroll_line_len(curwin->w_cursor.lnum); #ifdef FEAT_VIRTUALEDIT if (virtual_active()) { @@ -4442,26 +4466,33 @@ gui_update_horiz_scrollbar(force) * Do a horizontal scroll. Return TRUE if the cursor moved, FALSE otherwise. */ int -gui_do_horiz_scroll() +gui_do_horiz_scroll(leftcol, compute_longest_lnum) + colnr_T leftcol; + int compute_longest_lnum; { /* no wrapping, no scrolling */ if (curwin->w_p_wrap) return FALSE; - if ((long_u)curwin->w_leftcol == scrollbar_value) + if (curwin->w_leftcol == leftcol) return FALSE; - curwin->w_leftcol = (colnr_T)scrollbar_value; + curwin->w_leftcol = leftcol; /* When the line of the cursor is too short, move the cursor to the - * longest visible line. Do a sanity check on "longest_lnum", just in - * case. */ + * longest visible line. */ if (vim_strchr(p_go, GO_HORSCROLL) == NULL - && longest_lnum >= curwin->w_topline - && longest_lnum < curwin->w_botline - && !virtual_active()) + && !virtual_active() + && leftcol > scroll_line_len(curwin->w_cursor.lnum)) { - if (scrollbar_value > (long_u)scroll_line_len(curwin->w_cursor.lnum)) + if (compute_longest_lnum) + { + curwin->w_cursor.lnum = gui_find_longest_lnum(); + curwin->w_cursor.col = 0; + } + /* Do a sanity check on "longest_lnum", just in case. */ + else if (longest_lnum >= curwin->w_topline + && longest_lnum < curwin->w_botline) { curwin->w_cursor.lnum = longest_lnum; curwin->w_cursor.col = 0; diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c index d8e2487382..2cde1ee490 100644 --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -1700,7 +1700,13 @@ scroll_event(GtkWidget *widget, case GDK_SCROLL_DOWN: button = MOUSE_5; break; - default: /* We don't care about left and right... Yet. */ + case GDK_SCROLL_LEFT: + button = MOUSE_7; + break; + case GDK_SCROLL_RIGHT: + button = MOUSE_6; + break; + default: /* This shouldn't happen */ return FALSE; } diff --git a/src/keymap.h b/src/keymap.h index 39837e554b..16d128a881 100644 --- a/src/keymap.h +++ b/src/keymap.h @@ -228,8 +228,13 @@ enum key_extra , KE_S_XF3 , KE_S_XF4 + /* NOTE: The scroll wheel events are inverted: i.e. UP is the same as + * moving the actual scroll wheel down, LEFT is the same as moving the + * scroll wheel right. */ , KE_MOUSEDOWN /* scroll wheel pseudo-button Down */ , KE_MOUSEUP /* scroll wheel pseudo-button Up */ + , KE_MOUSELEFT /* scroll wheel pseudo-button Left */ + , KE_MOUSERIGHT /* scroll wheel pseudo-button Right */ , KE_KINS /* keypad Insert key */ , KE_KDEL /* keypad Delete key */ @@ -440,6 +445,8 @@ enum key_extra #define K_MOUSEDOWN TERMCAP2KEY(KS_EXTRA, KE_MOUSEDOWN) #define K_MOUSEUP TERMCAP2KEY(KS_EXTRA, KE_MOUSEUP) +#define K_MOUSELEFT TERMCAP2KEY(KS_EXTRA, KE_MOUSELEFT) +#define K_MOUSERIGHT TERMCAP2KEY(KS_EXTRA, KE_MOUSERIGHT) #define K_CSI TERMCAP2KEY(KS_EXTRA, KE_CSI) #define K_SNR TERMCAP2KEY(KS_EXTRA, KE_SNR) diff --git a/src/message.c b/src/message.c index 7c94cbf8b2..3b1b458922 100644 --- a/src/message.c +++ b/src/message.c @@ -987,6 +987,7 @@ wait_return(redraw) || c == K_LEFTDRAG || c == K_LEFTRELEASE || c == K_MIDDLEDRAG || c == K_MIDDLERELEASE || c == K_RIGHTDRAG || c == K_RIGHTRELEASE + || c == K_MOUSELEFT || c == K_MOUSERIGHT || c == K_MOUSEDOWN || c == K_MOUSEUP || (!mouse_has(MOUSE_RETURN) && mouse_row < msg_row diff --git a/src/misc1.c b/src/misc1.c index fb04fb6b72..9371760a47 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -3158,6 +3158,8 @@ get_keystroke() || n == K_RIGHTRELEASE || n == K_MOUSEDOWN || n == K_MOUSEUP + || n == K_MOUSELEFT + || n == K_MOUSERIGHT || n == K_X1MOUSE || n == K_X1DRAG || n == K_X1RELEASE diff --git a/src/misc2.c b/src/misc2.c index 98f2991c45..6b9ffe151c 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -2362,8 +2362,12 @@ static struct key_name_entry {K_RIGHTMOUSE, (char_u *)"RightMouse"}, {K_RIGHTDRAG, (char_u *)"RightDrag"}, {K_RIGHTRELEASE, (char_u *)"RightRelease"}, - {K_MOUSEDOWN, (char_u *)"MouseDown"}, - {K_MOUSEUP, (char_u *)"MouseUp"}, + {K_MOUSEDOWN, (char_u *)"ScrollWheelUp"}, + {K_MOUSEUP, (char_u *)"ScrollWheelDown"}, + {K_MOUSELEFT, (char_u *)"ScrollWheelRight"}, + {K_MOUSERIGHT, (char_u *)"ScrollWheelLeft"}, + {K_MOUSEDOWN, (char_u *)"MouseDown"}, /* OBSOLETE: Use */ + {K_MOUSEUP, (char_u *)"MouseUp"}, /* ScrollWheelXXX instead */ {K_X1MOUSE, (char_u *)"X1Mouse"}, {K_X1DRAG, (char_u *)"X1Drag"}, {K_X1RELEASE, (char_u *)"X1Release"}, diff --git a/src/normal.c b/src/normal.c index d9e958840d..d880ee60dd 100644 --- a/src/normal.c +++ b/src/normal.c @@ -368,8 +368,10 @@ static const struct nv_cmd /* pound sign */ {POUND, nv_ident, 0, 0}, #ifdef FEAT_MOUSE - {K_MOUSEUP, nv_mousescroll, 0, TRUE}, - {K_MOUSEDOWN, nv_mousescroll, 0, FALSE}, + {K_MOUSEUP, nv_mousescroll, 0, MSCR_UP}, + {K_MOUSEDOWN, nv_mousescroll, 0, MSCR_DOWN}, + {K_MOUSELEFT, nv_mousescroll, 0, MSCR_LEFT}, + {K_MOUSERIGHT, nv_mousescroll, 0, MSCR_RIGHT}, {K_LEFTMOUSE, nv_mouse, 0, 0}, {K_LEFTMOUSE_NM, nv_mouse, 0, 0}, {K_LEFTDRAG, nv_mouse, 0, 0}, @@ -3861,7 +3863,7 @@ add_to_showcmd(c) K_LEFTMOUSE, K_LEFTDRAG, K_LEFTRELEASE, K_MIDDLEMOUSE, K_MIDDLEDRAG, K_MIDDLERELEASE, K_RIGHTMOUSE, K_RIGHTDRAG, K_RIGHTRELEASE, - K_MOUSEDOWN, K_MOUSEUP, + K_MOUSEDOWN, K_MOUSEUP, K_MOUSELEFT, K_MOUSERIGHT, K_X1MOUSE, K_X1DRAG, K_X1RELEASE, K_X2MOUSE, K_X2DRAG, K_X2RELEASE, K_CURSORHOLD, 0 @@ -4536,7 +4538,8 @@ nv_screengo(oap, dir, dist) /* * Mouse scroll wheel: Default action is to scroll three lines, or one page * when Shift or Ctrl is used. - * K_MOUSEUP (cap->arg == TRUE) or K_MOUSEDOWN (cap->arg == FALSE) + * K_MOUSEUP (cap->arg == 1) or K_MOUSEDOWN (cap->arg == 0) or + * K_MOUSELEFT (cap->arg == -1) or K_MOUSERIGHT (cap->arg == -2) */ static void nv_mousescroll(cap) @@ -4559,16 +4562,36 @@ nv_mousescroll(cap) } # endif - if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + if (cap->arg == MSCR_UP || cap->arg == MSCR_DOWN) { - (void)onepage(cap->arg ? FORWARD : BACKWARD, 1L); + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + { + (void)onepage(cap->arg ? FORWARD : BACKWARD, 1L); + } + else + { + cap->count1 = 3; + cap->count0 = 3; + nv_scroll_line(cap); + } } +# ifdef FEAT_GUI else { - cap->count1 = 3; - cap->count0 = 3; - nv_scroll_line(cap); + /* Horizontal scroll - only allowed when 'wrap' is disabled */ + if (!curwin->w_p_wrap) + { + int val, step = 6; + if (mod_mask & (MOD_MASK_SHIFT | MOD_MASK_CTRL)) + step = W_WIDTH(curwin); + val = curwin->w_leftcol + (cap->arg == MSCR_RIGHT ? -step : +step); + if (val < 0) + val = 0; + + gui_do_horiz_scroll(val, TRUE); + } } +# endif # if defined(FEAT_GUI) && defined(FEAT_WINDOWS) curwin->w_redr_status = TRUE; @@ -5166,7 +5189,7 @@ nv_hor_scrollbar(cap) clearopbeep(cap->oap); /* Even if an operator was pending, we still want to scroll */ - gui_do_horiz_scroll(); + gui_do_horiz_scroll(scrollbar_value, FALSE); } #endif diff --git a/src/proto/gui.pro b/src/proto/gui.pro index 136570cb11..fa5ce89441 100644 --- a/src/proto/gui.pro +++ b/src/proto/gui.pro @@ -46,7 +46,7 @@ void gui_drag_scrollbar __ARGS((scrollbar_T *sb, long value, int still_dragging) void gui_may_update_scrollbars __ARGS((void)); void gui_update_scrollbars __ARGS((int force)); int gui_do_scroll __ARGS((void)); -int gui_do_horiz_scroll __ARGS((void)); +int gui_do_horiz_scroll __ARGS((colnr_T leftcol, int compute_longest_lnum)); void gui_check_colors __ARGS((void)); guicolor_T gui_get_color __ARGS((char_u *name)); int gui_get_lightness __ARGS((guicolor_T pixel)); diff --git a/src/screen.c b/src/screen.c index 25772181b4..ca5827fe32 100644 --- a/src/screen.c +++ b/src/screen.c @@ -2822,7 +2822,7 @@ win_line(wp, lnum, startrow, endrow, nochange) int is_concealing = FALSE; int boguscols = 0; /* nonexistent columns added to force wrapping */ - int vcol_off = 0; /* offset for concealed characters */ + int vcol_off = 0; /* offset for concealed characters */ int did_wcol = FALSE; # define VCOL_HLC (vcol - vcol_off) #else diff --git a/src/term.c b/src/term.c index 57bb730e4f..8c426620c9 100644 --- a/src/term.c +++ b/src/term.c @@ -4167,6 +4167,8 @@ check_termcode(max_offset, buf, buflen) && key_name[0] == (int)KS_EXTRA && (key_name[1] == (int)KE_X1MOUSE || key_name[1] == (int)KE_X2MOUSE + || key_name[1] == (int)KE_MOUSELEFT + || key_name[1] == (int)KE_MOUSERIGHT || key_name[1] == (int)KE_MOUSEDOWN || key_name[1] == (int)KE_MOUSEUP)) { @@ -5054,7 +5056,7 @@ replace_termcodes(from, bufp, from_part, do_lt, special) { /* * If 'cpoptions' does not contain '<', check for special key codes, - * like "<C-S-MouseLeft>" + * like "<C-S-LeftMouse>" */ if (do_special && (do_lt || STRNCMP(src, "<lt>", 4) != 0)) { @@ -1721,12 +1721,18 @@ typedef int proftime_T; /* dummy for function prototypes */ # define MOUSE_CTRL 0x10 /* mouse buttons that are handled like a key press (GUI only) */ +/* Note that the scroll wheel keys are inverted: MOUSE_5 scrolls lines up but + * the result of this is that the window moves down, similarly MOUSE_6 scrolls + * columns left but the window moves right. */ # define MOUSE_4 0x100 /* scroll wheel down */ # define MOUSE_5 0x200 /* scroll wheel up */ # define MOUSE_X1 0x300 /* Mouse-button X1 (6th) */ # define MOUSE_X2 0x400 /* Mouse-button X2 */ +# define MOUSE_6 0x500 /* scroll wheel left */ +# define MOUSE_7 0x600 /* scroll wheel right */ + /* 0x20 is reserved by xterm */ # define MOUSE_DRAG_XTERM 0x40 @@ -2180,4 +2186,10 @@ typedef int VimClipboard; /* This is required for the prototypes. */ #define BFA_WIPE 2 /* buffer is going to be wiped out */ #define BFA_KEEP_UNDO 4 /* do not free undo information */ +/* direction for nv_mousescroll() and ins_mousescroll() */ +#define MSCR_DOWN 0 /* DOWN must be FALSE */ +#define MSCR_UP 1 +#define MSCR_LEFT -1 +#define MSCR_RIGHT -2 + #endif /* VIM__H */ |