]> git.wh0rd.org Git - nano.git/commitdiff
in do_mouseinput(), add mouse wheel support, per Helmut Jarausch's
authorDavid Lawrence Ramsey <pooka109@gmail.com>
Thu, 28 Jun 2007 16:26:15 +0000 (16:26 +0000)
committerDavid Lawrence Ramsey <pooka109@gmail.com>
Thu, 28 Jun 2007 16:26:15 +0000 (16:26 +0000)
suggestion, and add various mouse support-related simplifications

git-svn-id: svn://svn.savannah.gnu.org/nano/branches/nano_2_0_branch/nano@4114 35c25a1d-7b9e-4130-9fde-d3aeb78583b8

ChangeLog
src/browser.c
src/nano.c
src/prompt.c
src/proto.h
src/winio.c

index 464f22f4d2e659ab8b5aed1760f4a3fd73f19c0d..600c936fb949cab249deeeb51794869a285cd1c5 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,7 +1,25 @@
 CVS code -
+- General:
+       - Simplify processing of mouse events.  Instead of calling
+         wenclose() to get the window a mouse event took place in and
+         manually adjusting the returned coordinates to be relative to
+         that window the mouse event took place in, call
+         wmouse_trafo(), which does both.  Changes to do_browser(),
+         do_mouse(), do_statusbar_mouse(), do_yesno_prompt(), and
+         do_mouseinput(). (DLR)
 - winio.c:
   get_key_buffer()
        - Fix inaccurate comments. (DLR)
+  do_mouseinput()
+       - Add mouse wheel support.  Now, if mouse support is enabled,
+         and nano is using a version of ncurses compiled with the
+         --enable-ext-mouse option, rolling the mouse wheel up or down
+         will move the cursor three lines up or down.  Note that
+         ncurses built without --enable-ext-mouse needs to handle both
+         clicks and releases of the first mouse button, but ncurses
+         built with --enable-ext-mouse only needs to handle releases,
+         so keep dealing with both events. (DLR, suggested by Helmut
+         Jarausch)
 
 GNU nano 2.0.6 - 2007.04.26
 - text.c:
index 44d94825495e4580698522bd0cc91bb124b4e165..b04c366235446d37218a3283ebb7b902f39714f6 100644 (file)
@@ -131,38 +131,32 @@ char *do_browser(char *path, DIR *dir)
                {
                    int mouse_x, mouse_y;
 
-                   if (!get_mouseinput(&mouse_x, &mouse_y, TRUE)) {
-                       /* We can click in the edit window to select a
-                        * filename. */
-                       if (wenclose(edit, mouse_y, mouse_x)) {
-                           /* Subtract out the size of topwin. */
-                           mouse_y -= 2 - no_more_space();
-
-                           /* longest is the width of each column.
-                            * There are two spaces between each
-                            * column. */
-                           selected = (fileline / editwinrows) *
+                   /* We can click on the edit window to select a
+                    * filename. */
+                   if (get_mouseinput(&mouse_x, &mouse_y, TRUE) == 0 &&
+                       wmouse_trafo(edit, &mouse_y, &mouse_x, FALSE)) {
+                       /* longest is the width of each column.  There
+                        * are two spaces between each column. */
+                       selected = (fileline / editwinrows) *
                                (editwinrows * width) + (mouse_y *
                                width) + (mouse_x / (longest + 2));
 
-                           /* If they clicked beyond the end of a row,
-                            * select the filename at the end of that
-                            * row. */
-                           if (mouse_x > width * (longest + 2))
-                               selected--;
-
-                           /* If we're off the screen, select the last
-                            * filename. */
-                           if (selected > filelist_len - 1)
-                               selected = filelist_len - 1;
-
-                           /* If we selected the same filename as last
-                            * time, put back the Enter key so that it's
-                            * read in. */
-                           if (old_selected == selected)
-                               unget_kbinput(NANO_ENTER_KEY, FALSE,
-                                       FALSE);
-                       }
+                       /* If they clicked beyond the end of a row,
+                        * select the filename at the end of that
+                        * row. */
+                       if (mouse_x > width * (longest + 2))
+                           selected--;
+
+                       /* If we're off the screen, select the last
+                        * filename. */
+                       if (selected > filelist_len - 1)
+                           selected = filelist_len - 1;
+
+                       /* If we selected the same filename as last
+                        * time, put back the Enter key so that it's
+                        * read in. */
+                       if (old_selected == selected)
+                           unget_kbinput(NANO_ENTER_KEY, FALSE, FALSE);
                    }
                }
                break;
index 66f6f4a380920d0349b3bcf258a450976335c8af..59d498c155feeac2bd4f63e586a9e8e6b5f77699 100644 (file)
@@ -1332,7 +1332,7 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
        /* If we got a mouse click and it was on a shortcut, read in the
         * shortcut character. */
        if (*func_key && input == KEY_MOUSE) {
-           if (do_mouse())
+           if (do_mouse() == 1)
                input = get_kbinput(edit, meta_key, func_key);
            else {
                *meta_key = FALSE;
@@ -1490,50 +1490,43 @@ int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
 
 #ifndef DISABLE_MOUSE
 /* Handle a mouse click on the edit window or the shortcut list. */
-bool do_mouse(void)
+int do_mouse(void)
 {
     int mouse_x, mouse_y;
-    bool retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
-
-    if (!retval) {
-       /* We can click in the edit window to move the cursor. */
-       if (wenclose(edit, mouse_y, mouse_x)) {
-           bool sameline;
-               /* Did they click on the line with the cursor?  If they
-                * clicked on the cursor, we set the mark. */
-           const filestruct *current_save = openfile->current;
-           size_t current_x_save = openfile->current_x;
-           size_t pww_save = openfile->placewewant;
-
-           /* Subtract out the size of topwin. */
-           mouse_y -= 2 - no_more_space();
-
-           sameline = (mouse_y == openfile->current_y);
-
-           /* Move to where the click occurred. */
-           for (; openfile->current_y < mouse_y &&
-               openfile->current != openfile->filebot;
-               openfile->current_y++)
-               openfile->current = openfile->current->next;
-           for (; openfile->current_y > mouse_y &&
-               openfile->current != openfile->fileage;
-               openfile->current_y--)
-               openfile->current = openfile->current->prev;
-
-           openfile->current_x = actual_x(openfile->current->data,
+    int retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
+
+    /* We can click on the edit window to move the cursor. */
+    if (retval == 0 && wmouse_trafo(edit, &mouse_y, &mouse_x, FALSE)) {
+       bool sameline;
+           /* Did they click on the line with the cursor?  If they
+            * clicked on the cursor, we set the mark. */
+       const filestruct *current_save = openfile->current;
+       size_t current_x_save = openfile->current_x;
+       size_t pww_save = openfile->placewewant;
+
+       sameline = (mouse_y == openfile->current_y);
+
+       /* Move to where the click occurred. */
+       for (; openfile->current_y < mouse_y && openfile->current !=
+               openfile->filebot; openfile->current_y++)
+           openfile->current = openfile->current->next;
+       for (; openfile->current_y > mouse_y && openfile->current !=
+               openfile->fileage; openfile->current_y--)
+           openfile->current = openfile->current->prev;
+
+       openfile->current_x = actual_x(openfile->current->data,
                get_page_start(xplustabs()) + mouse_x);
-           openfile->placewewant = xplustabs();
+       openfile->placewewant = xplustabs();
 
 #ifndef NANO_TINY
-           /* Clicking where the cursor is toggles the mark, as does
-            * clicking beyond the line length with the cursor at the
-            * end of the line. */
-           if (sameline && openfile->current_x == current_x_save)
-               do_mark();
+       /* Clicking where the cursor is toggles the mark, as does
+        * clicking beyond the line length with the cursor at the end of
+        * the line. */
+       if (sameline && openfile->current_x == current_x_save)
+           do_mark();
 #endif
 
-           edit_redraw(current_save, pww_save);
-       }
+       edit_redraw(current_save, pww_save);
     }
 
     return retval;
index af1c7dd7f12230099d41df0b53af74f8c3ce967f..a213efe28df89056673a1755507e845308b962f2 100644 (file)
@@ -76,7 +76,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
        /* If we got a mouse click and it was on a shortcut, read in the
         * shortcut character. */
        if (*func_key && input == KEY_MOUSE) {
-           if (do_statusbar_mouse())
+           if (do_statusbar_mouse() == 1)
                input = get_kbinput(bottomwin, meta_key, func_key);
            else {
                *meta_key = FALSE;
@@ -273,37 +273,32 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
 
 #ifndef DISABLE_MOUSE
 /* Handle a mouse click on the statusbar prompt or the shortcut list. */
-bool do_statusbar_mouse(void)
+int do_statusbar_mouse(void)
 {
     int mouse_x, mouse_y;
-    bool retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
+    int retval = get_mouseinput(&mouse_x, &mouse_y, TRUE);
 
-    if (!retval) {
-       /* We can click in the statusbar window text to move the
-        * cursor. */
-       if (wenclose(bottomwin, mouse_y, mouse_x)) {
-           size_t start_col;
+    /* We can click on the statusbar window text to move the cursor. */
+    if (retval == 0 && wmouse_trafo(bottomwin, &mouse_y, &mouse_x,
+       FALSE)) {
+       size_t start_col;
 
-           assert(prompt != NULL);
+       assert(prompt != NULL);
 
-           start_col = strlenpt(prompt) + 1;
+       start_col = strlenpt(prompt) + 1;
 
-           /* Subtract out the sizes of topwin and edit. */
-           mouse_y -= (2 - no_more_space()) + editwinrows;
+       /* Move to where the click occurred. */
+       if (mouse_x > start_col && mouse_y == 0) {
+           size_t pww_save = statusbar_pww;
 
-           /* Move to where the click occurred. */
-           if (mouse_x > start_col && mouse_y == 0) {
-               size_t pww_save = statusbar_pww;
-
-               statusbar_x = actual_x(answer,
+           statusbar_x = actual_x(answer,
                        get_statusbar_page_start(start_col, start_col +
-                       statusbar_xplustabs()) + mouse_x - start_col -
-                       1);
-               statusbar_pww = statusbar_xplustabs();
+                       statusbar_xplustabs()) + mouse_x -
+                       start_col - 1);
+           statusbar_pww = statusbar_xplustabs();
 
-               if (need_statusbar_horizontal_update(pww_save))
-                   update_statusbar_line(answer, statusbar_x);
-           }
+           if (need_statusbar_horizontal_update(pww_save))
+               update_statusbar_line(answer, statusbar_x);
        }
     }
 
@@ -1337,18 +1332,17 @@ int do_yesno_prompt(bool all, const char *msg)
                break;
 #ifndef DISABLE_MOUSE
            case KEY_MOUSE:
-               get_mouseinput(&mouse_x, &mouse_y, FALSE);
-
-               if (wenclose(bottomwin, mouse_y, mouse_x) &&
-                       !ISSET(NO_HELP) && mouse_x < (width * 2) &&
-                       mouse_y - (2 - no_more_space()) -
-                       editwinrows - 1 >= 0) {
+               /* We can click on the shortcut list to select an
+                * answer. */
+               if (get_mouseinput(&mouse_x, &mouse_y, FALSE) == 0 &&
+                       wmouse_trafo(bottomwin, &mouse_y, &mouse_x,
+                       FALSE) && !ISSET(NO_HELP) && mouse_x <
+                       (width * 2) && mouse_y > 0) {
                    int x = mouse_x / width;
                        /* Calculate the x-coordinate relative to the
                         * two columns of the Yes/No/All shortcuts in
                         * bottomwin. */
-                   int y = mouse_y - (2 - no_more_space()) -
-                       editwinrows - 1;
+                   int y = mouse_y - 1;
                        /* Calculate the y-coordinate relative to the
                         * beginning of the Yes/No/All shortcuts in
                         * bottomwin, i.e. with the sizes of topwin,
index 0250b5a006ef3f47f0976b40157c695faf3be5ee..2bd0bfde59857c9d735261625909e18313a41cb4 100644 (file)
@@ -485,7 +485,7 @@ void terminal_init(void);
 int do_input(bool *meta_key, bool *func_key, bool *s_or_t, bool
        *ran_func, bool *finished, bool allow_funcs);
 #ifndef DISABLE_MOUSE
-bool do_mouse(void);
+int do_mouse(void);
 #endif
 void do_output(char *output, size_t output_len, bool allow_cntrls);
 
@@ -494,7 +494,7 @@ int do_statusbar_input(bool *meta_key, bool *func_key, bool *s_or_t,
        bool *ran_func, bool *finished, bool allow_funcs, void
        (*refresh_func)(void));
 #ifndef DISABLE_MOUSE
-bool do_statusbar_mouse(void);
+int do_statusbar_mouse(void);
 #endif
 void do_statusbar_output(char *output, size_t output_len, bool
        *got_enter, bool allow_cntrls);
@@ -749,7 +749,7 @@ void unparse_kbinput(char *output, size_t output_len);
 int *get_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
 int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len);
 #ifndef DISABLE_MOUSE
-bool get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
+int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts);
 #endif
 const shortcut *get_shortcut(const shortcut *s_list, int *kbinput, bool
        *meta_key, bool *func_key);
index b3082b84333941f420ee993456cde74544ef66fc..9569f060179db9e797d7c76aa46f89337237e6b5 100644 (file)
@@ -1621,15 +1621,19 @@ int *parse_verbatim_kbinput(WINDOW *win, size_t *kbinput_len)
 }
 
 #ifndef DISABLE_MOUSE
-/* Check for a mouse event, and if one's taken place, save the
- * coordinates where it took place in mouse_x and mouse_y.  After that,
- * assuming allow_shortcuts is FALSE, if the shortcut list on the
- * bottom two lines of the screen is visible and the mouse event took
- * place on it, figure out which shortcut was clicked and put back the
- * equivalent keystroke(s).  Return FALSE if no keystrokes were
- * put back, or TRUE if at least one was.  Assume that KEY_MOUSE has
+/* Handle any mouse events that may have occurred.  We currently handle
+ * releases/clicks of the first mouse button.  If allow_shortcuts is
+ * TRUE, releasing/clicking on a visible shortcut will put back the
+ * keystroke associated with that shortcut.  If NCURSES_MOUSE_VERSION is
+ * at least 2, we also currently handle presses of the fourth mouse
+ * button (upward rolls of the mouse wheel) by putting back the
+ * keystrokes to move up, and presses of the fifth mouse button
+ * (downward rolls of the mouse wheel) by putting back the keystrokes to
+ * move down.  Return -1 on error, 0 if the mouse event needs to be
+ * handled, 1 if it's been handled by putting back keystrokes that need
+ * to be handled. or 2 if it's been ignored.  Assume that KEY_MOUSE has
  * already been read in. */
-bool get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
+int get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
 {
     MEVENT mevent;
 
@@ -1638,90 +1642,142 @@ bool get_mouseinput(int *mouse_x, int *mouse_y, bool allow_shortcuts)
 
     /* First, get the actual mouse event. */
     if (getmouse(&mevent) == ERR)
-       return FALSE;
-
-    /* If it's not a release or click of the first mouse button, get
-     * out. */
-    if (!(mevent.bstate & (BUTTON1_RELEASED | BUTTON1_CLICKED)))
-       return FALSE;
+       return -1;
 
     /* Save the screen coordinates where the mouse event took place. */
     *mouse_x = mevent.x;
     *mouse_y = mevent.y;
 
-    /* If we're allowing shortcuts, the current shortcut list is being
-     * displayed on the last two lines of the screen, and the mouse
-     * event took place inside it, we need to figure out which shortcut
-     * was clicked and put back the equivalent keystroke(s) for it. */
-    if (allow_shortcuts && !ISSET(NO_HELP) && wenclose(bottomwin,
-       *mouse_y, *mouse_x)) {
-       int i, j;
-       size_t currslen;
-           /* The number of shortcuts in the current shortcut list. */
-       const shortcut *s = currshortcut;
-           /* The actual shortcut we clicked on, starting at the first
-            * one in the current shortcut list. */
-
-       /* Get the shortcut lists' length. */
-       if (currshortcut == main_list)
-           currslen = MAIN_VISIBLE;
-       else {
-           currslen = length_of_list(currshortcut);
-
-           /* We don't show any more shortcuts than the main list
-            * does. */
-           if (currslen > MAIN_VISIBLE)
+    /* Handle clicks/releases of the first mouse button. */
+    if (mevent.bstate & (BUTTON1_RELEASED | BUTTON1_CLICKED)) {
+       /* If we're allowing shortcuts, the current shortcut list is
+        * being displayed on the last two lines of the screen, and the
+        * first mouse button was released on/clicked inside it, we need
+        * to figure out which shortcut was released on/clicked and put
+        * back the equivalent keystroke(s) for it. */
+       if (allow_shortcuts && !ISSET(NO_HELP) &&
+               wmouse_trafo(bottomwin, mouse_y, mouse_x, FALSE)) {
+           int i;
+               /* The width of all the shortcuts, except for the last
+                * two, in the shortcut list in bottomwin. */
+           int j;
+               /* The y-coordinate relative to the beginning of the
+                * shortcut list in bottomwin. */
+           size_t currslen;
+               /* The number of shortcuts in the current shortcut
+                * list. */
+           const shortcut *s;
+               /* The actual shortcut we released on, starting at the
+                * first one in the current shortcut list. */
+
+           /* Ignore releases/clicks of the first mouse button on the
+            * statusbar. */
+           if (*mouse_y == 0)
+               return 2;
+
+           /* Calculate the y-coordinate relative to the beginning of
+            * the shortcut list in bottomwin. */
+           j = *mouse_y - 1;
+
+           /* Get the shortcut lists' length. */
+           if (currshortcut == main_list)
                currslen = MAIN_VISIBLE;
-       }
+           else {
+               currslen = length_of_list(currshortcut);
 
-       /* Calculate the width of all of the shortcuts in the list
-        * except for the last two, which are longer by (COLS % i)
-        * columns so as to not waste space. */
-       if (currslen < 2)
-           i = COLS / (MAIN_VISIBLE / 2);
-       else
-           i = COLS / ((currslen / 2) + (currslen % 2));
-
-       /* Calculate the y-coordinate relative to the beginning of
-        * the shortcut list in bottomwin, i.e. with the sizes of
-        * topwin, edit, and the first line of bottomwin subtracted
-        * out, and set j to it. */
-       j = *mouse_y - (2 - no_more_space()) - editwinrows - 1;
-
-       /* If we're on the statusbar, don't do anything. */
-       if (j < 0)
-           return FALSE;
-
-       /* Calculate the x-coordinate relative to the beginning of the
-        * shortcut list in bottomwin, and add it to j.  j should now be
-        * the index in the shortcut list of the shortcut we clicked. */
-       j = (*mouse_x / i) * 2 + j;
-
-       /* Adjust j if we clicked in the last two shortcuts. */
-       if ((j >= currslen) && (*mouse_x % i < COLS % i))
-           j -= 2;
-
-       /* If we're beyond the last shortcut, don't do anything. */
-       if (j >= currslen)
-           return FALSE;
-
-       /* Go through the shortcut list to determine which shortcut was
-        * clicked. */
-       for (; j > 0; j--)
-           s = s->next;
-
-       /* And put back the equivalent key.  Assume that each shortcut
-        * has, at the very least, an equivalent control key, an
-        * equivalent primary meta key sequence, or both. */
-       if (s->ctrlval != NANO_NO_KEY) {
-           unget_kbinput(s->ctrlval, FALSE, FALSE);
-           return TRUE;
-       } else if (s->metaval != NANO_NO_KEY) {
-           unget_kbinput(s->metaval, TRUE, FALSE);
-           return TRUE;
-       }
+               /* We don't show any more shortcuts than the main list
+                * does. */
+               if (currslen > MAIN_VISIBLE)
+                   currslen = MAIN_VISIBLE;
+           }
+
+           /* Calculate the width of all of the shortcuts in the list
+            * except for the last two, which are longer by (COLS % i)
+            * columns so as to not waste space. */
+           if (currslen < 2)
+               i = COLS / (MAIN_VISIBLE / 2);
+           else
+               i = COLS / ((currslen / 2) + (currslen % 2));
+
+           /* Calculate the x-coordinate relative to the beginning of
+            * the shortcut list in bottomwin, and add it to j.  j
+            * should now be the index in the shortcut list of the
+            * shortcut we released/clicked on. */
+           j = (*mouse_x / i) * 2 + j;
+
+           /* Adjust j if we released on the last two shortcuts. */
+           if ((j >= currslen) && (*mouse_x % i < COLS % i))
+               j -= 2;
+
+           /* Ignore releases/clicks of the first mouse button beyond
+            * the last shortcut. */
+           if (j >= currslen)
+               return 2;
+
+           /* Go through the shortcut list to determine which shortcut
+            * we released/clicked on. */
+           s = currshortcut;
+
+           for (; j > 0; j--)
+               s = s->next;
+
+           /* And put back the equivalent key.  Assume that each
+            * shortcut has, at the very least, an equivalent control
+            * key, an equivalent primary meta key sequence, or both. */
+           if (s->ctrlval != NANO_NO_KEY) {
+               unget_kbinput(s->ctrlval, FALSE, FALSE);
+               return 1;
+           } else if (s->metaval != NANO_NO_KEY) {
+               unget_kbinput(s->metaval, TRUE, FALSE);
+               return 1;
+           }
+       } else
+           /* Handle releases/clicks of the first mouse button that
+            * aren't on the current shortcut list elsewhere. */
+           return 0;
     }
-    return FALSE;
+#if NCURSES_MOUSE_VERSION >= 2
+    /* Handle presses of the fourth mouse button (upward rolls of the
+     * mouse wheel) and presses of the fifth mouse button (downward
+     * rolls of the mouse wheel) . */
+    else if (mevent.bstate & (BUTTON4_PRESSED | BUTTON5_PRESSED)) {
+       bool in_edit = wmouse_trafo(edit, mouse_y, mouse_x, FALSE);
+       bool in_bottomwin = wmouse_trafo(bottomwin, mouse_y, mouse_x,
+               FALSE);
+
+       if (in_edit || in_bottomwin) {
+           int i;
+               /* The y-coordinate relative to the beginning of the
+                * shortcut list in bottomwin. */
+
+           /* Ignore presses of the fourth mouse button and presses of
+            * the fifth mouse button below the statusbar. */
+           if (in_bottomwin && *mouse_y > 0)
+               return 2;
+
+           /* Calculate the y-coordinate relative to the beginning of
+            * the shortcut list in bottomwin. */
+           i = *mouse_y - 1;
+
+           /* One upward roll of the mouse wheel is equivalent to
+            * moving up three lines, and one downward roll of the mouse
+            * wheel is equivalent to moving down three lines. */
+           for (i = 0; i < 3; i++)
+               unget_kbinput((mevent.bstate & BUTTON4_PRESSED) ?
+                       NANO_PREVLINE_KEY : NANO_NEXTLINE_KEY, FALSE,
+                       FALSE);
+
+           return 1;
+       } else
+           /* Ignore presses of the fourth mouse button and presses of
+            * the fifth mouse buttons that aren't on the edit window or
+            * the statusbar. */
+           return 2;
+    }
+#endif
+    else
+       /* Ignore all other mouse events. */
+       return 2;
 }
 #endif /* !DISABLE_MOUSE */