emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] trunk r114660: Implement scrolling of TTY menus when the s


From: Eli Zaretskii
Subject: [Emacs-diffs] trunk r114660: Implement scrolling of TTY menus when the screen is too short.
Date: Mon, 14 Oct 2013 15:37:58 +0000
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 114660
revision-id: address@hidden
parent: address@hidden
committer: Eli Zaretskii <address@hidden>
branch nick: trunk
timestamp: Mon 2013-10-14 18:37:12 +0300
message:
  Implement scrolling of TTY menus when the screen is too short.
  
   src/term.c (tty_menu_display): Accept an additional argument, the
   menu item from which to start displaying the menu.  Account for
   the value of Y when limiting the menu to the number of available
   screen lines.
   (mi_result): New enumeration.
   (read_menu_input): Return enumerated value.  When the y coordinate
   hits min_y or max_y, return scroll indication instead of wrapping
   around the menu.
   (tty_menu_activate): Handle the scrolling indications from
   read_menu_input.  Compute the first menu item to display and pass
   it to tty_menu_display.
  
   lisp/menu-bar.el (tty-menu-navigation-map): Bind shifted mouse clicks
   to commands that scroll the menu.
modified:
  lisp/ChangeLog                 changelog-20091113204419-o5vbwnq5f7feedwu-1432
  lisp/menu-bar.el               menubar.el-20091113204419-o5vbwnq5f7feedwu-546
  src/ChangeLog                  changelog-20091113204419-o5vbwnq5f7feedwu-1438
  src/term.c                     term.c-20091113204419-o5vbwnq5f7feedwu-220
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2013-10-14 01:51:20 +0000
+++ b/lisp/ChangeLog    2013-10-14 15:37:12 +0000
@@ -1,3 +1,8 @@
+2013-10-14  Eli Zaretskii  <address@hidden>
+
+       * menu-bar.el (tty-menu-navigation-map): Bind shifted mouse clicks
+       to commands that scroll the menu.
+
 2013-10-14  Dmitry Gutov  <address@hidden>
 
        * progmodes/ruby-mode.el (ruby-smie--args-separator-p): Handle

=== modified file 'lisp/menu-bar.el'
--- a/lisp/menu-bar.el  2013-10-13 05:20:15 +0000
+++ b/lisp/menu-bar.el  2013-10-14 15:37:12 +0000
@@ -2341,20 +2341,26 @@
     (define-key map [linefeed] 'tty-menu-select)
     (define-key map [down-mouse-1] 'tty-menu-select)
     (define-key map [drag-mouse-1] 'tty-menu-select)
+    ;; The following 4 bindings are for those whose text-mode mouse
+    ;; lack the wheel.
+    (define-key map [S-down-mouse-1] 'tty-menu-next-item)
+    (define-key map [S-drag-mouse-1] 'tty-menu-next-item)
+    (define-key map [S-down-mouse-2] 'tty-menu-prev-item)
+    (define-key map [S-drag-mouse-2] 'tty-menu-prev-item)
     (define-key map [mode-line drag-mouse-1] 'tty-menu-select)
     (define-key map [mode-line down-mouse-1] 'tty-menu-select)
     (define-key map [header-line mouse-1] 'tty-menu-select)
     (define-key map [header-line drag-mouse-1] 'tty-menu-select)
     (define-key map [header-line down-mouse-1] 'tty-menu-select)
+    ;; The mouse events must be bound to tty-menu-ignore, otherwise
+    ;; the initial mouse click will select and immediately pop down
+    ;; the menu.
     (define-key map [mode-line mouse-1] 'tty-menu-ignore)
     (define-key map [mode-line mouse-2] 'tty-menu-ignore)
     (define-key map [mode-line mouse-3] 'tty-menu-ignore)
     (define-key map [mode-line C-mouse-1] 'tty-menu-ignore)
     (define-key map [mode-line C-mouse-2] 'tty-menu-ignore)
     (define-key map [mode-line C-mouse-3] 'tty-menu-ignore)
-    ;; The mouse events must be bound to tty-menu-ignore, otherwise
-    ;; the initial mouse click will select and immediately pop down
-    ;; the menu.
     (define-key map [mouse-1] 'tty-menu-ignore)
     (define-key map [C-mouse-1] 'tty-menu-ignore)
     (define-key map [C-mouse-2] 'tty-menu-ignore)

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-10-14 12:19:21 +0000
+++ b/src/ChangeLog     2013-10-14 15:37:12 +0000
@@ -1,3 +1,19 @@
+2013-10-14  Eli Zaretskii  <address@hidden>
+
+       Implement scrolling of TTY menus when the screen is too short.
+
+       * term.c (tty_menu_display): Accept an additional argument, the
+       menu item from which to start displaying the menu.  Account for
+       the value of Y when limiting the menu to the number of available
+       screen lines.
+       (mi_result): New enumeration.
+       (read_menu_input): Return enumerated value.  When the y coordinate
+       hits min_y or max_y, return scroll indication instead of wrapping
+       around the menu.
+       (tty_menu_activate): Handle the scrolling indications from
+       read_menu_input.  Compute the first menu item to display and pass
+       it to tty_menu_display.
+
 2013-10-14  Dmitry Antipov  <address@hidden>
 
        * termhooks.h (FRAME_MUST_WRITE_SPACES, FRAME_LINE_INS_DEL_OK)

=== modified file 'src/term.c'
--- a/src/term.c        2013-10-14 12:19:21 +0000
+++ b/src/term.c        2013-10-14 15:37:12 +0000
@@ -2781,10 +2781,10 @@
    However, unlike on MSDOS, where the menu text is drawn directly to
    the display video memory, on a TTY we use display_string (see
    display_tty_menu_item in xdisp.c) to put the glyphs produced from
-   the menu items directly into the frame's 'desired_matrix' glyph
-   matrix, and then call update_frame_with_menu to deliver the results
-   to the glass.  The previous contents of the screen, in the form of
-   the current_matrix, is stashed away, and used to restore screen
+   the menu items into the frame's 'desired_matrix' glyph matrix, and
+   then call update_frame_with_menu to deliver the results to the
+   glass.  The previous contents of the screen, in the form of the
+   current_matrix, is stashed away, and used to restore screen
    contents when the menu selection changes or when the final
    selection is made and the menu should be popped down.
 
@@ -2911,11 +2911,12 @@
     }
 }
 
-/* Display MENU at (X,Y) using FACES.  */
+/* Display MENU at (X,Y) using FACES, starting with FIRST_ITEM
+   (zero-based).  */
 
 static void
 tty_menu_display (tty_menu *menu, int x, int y, int pn, int *faces,
-                 int mx, int my, int disp_help)
+                 int mx, int my, int first_item, int disp_help)
 {
   int i, face, width, enabled, mousehere, row, col;
   struct frame *sf = SELECTED_FRAME ();
@@ -2923,7 +2924,7 @@
   /* Don't try to display more menu items than the console can display
      using the available screen lines.  Exclude the echo area line, as
      it will be overwritten by the help-echo anyway.  */
-  int max_items = min (menu->count, FRAME_LINES (sf) - 1);
+  int max_items = min (menu->count - first_item, FRAME_LINES (sf) - 1 - y);
 
   menu_help_message = NULL;
 
@@ -2933,11 +2934,12 @@
   for (i = 0; i < max_items; i++)
     {
       int max_width = width + 2; /* +2 for padding blanks on each side */
+      int j = i + first_item;
 
-      if (menu->submenu[i])
+      if (menu->submenu[j])
        max_width += 2; /* for displaying " >" after the item */
       enabled
-       = (!menu->submenu[i] && menu->panenumber[i]) || (menu->submenu[i]);
+       = (!menu->submenu[j] && menu->panenumber[j]) || (menu->submenu[j]);
       mousehere = (y + i == my && x <= mx && mx < x + max_width);
       face = faces[enabled + mousehere * 2];
       /* Display the menu help string for the i-th menu item even if
@@ -2945,12 +2947,12 @@
         code does.  */
       if (disp_help && enabled + mousehere * 2 >= 2)
        {
-         menu_help_message = menu->help_text[i];
+         menu_help_message = menu->help_text[j];
          menu_help_paneno = pn - 1;
-         menu_help_itemno = i;
+         menu_help_itemno = j;
        }
-      display_tty_menu_item (menu->text[i], max_width, face, x, y + i,
-                            menu->submenu[i] != NULL);
+      display_tty_menu_item (menu->text[j], max_width, face, x, y + i,
+                            menu->submenu[j] != NULL);
     }
   update_frame_with_menu (sf);
   cursor_to (sf, row, col);
@@ -3124,14 +3126,20 @@
   update_frame_with_menu (f);
 }
 
+typedef enum {
+  MI_QUIT_MENU      = -1,
+  MI_CONTINUE       = 0,
+  MI_ITEM_SELECTED  = 1,
+  MI_NEXT_ITEM      = 2,
+  MI_PREV_ITEM      = 3,
+  MI_SCROLL_FORWARD = 4,
+  MI_SCROLL_BACK    = 5
+} mi_result;
+
 /* Read user input and return X and Y coordinates where that input
-   puts us.  We only consider mouse movement and click events and
-   keyboard movement commands; the rest are ignored.
-
-   Value is -1 if C-g was pressed, 1 if an item was selected, 2 or 3
-   if we need to move to the next or previous menu-bar menu, zero
-   otherwise.  */
-static int
+   puts us.  We only consider mouse movement and click events, and
+   keyboard movement commands; the rest are ignored.  */
+static mi_result
 read_menu_input (struct frame *sf, int *x, int *y, int min_y, int max_y,
                 bool *first_time)
 {
@@ -3144,7 +3152,7 @@
     {
       Lisp_Object cmd;
       int usable_input = 1;
-      int st = 0;
+      mi_result st = MI_CONTINUE;
       struct tty_display_info *tty = FRAME_TTY (sf);
       Lisp_Object saved_mouse_tracking = do_mouse_tracking;
 
@@ -3160,42 +3168,42 @@
       do_mouse_tracking = saved_mouse_tracking;
 
       if (EQ (cmd, Qt) || EQ (cmd, Qtty_menu_exit))
-       return -1;
+       return MI_QUIT_MENU;
       if (EQ (cmd, Qtty_menu_mouse_movement))
        mouse_get_xy (x, y);
       else if (EQ (cmd, Qtty_menu_next_menu))
        {
          usable_input = 0;
-         st = 2;
+         st = MI_NEXT_ITEM;
        }
       else if (EQ (cmd, Qtty_menu_prev_menu))
        {
          usable_input = 0;
-         st = 3;
+         st = MI_PREV_ITEM;
        }
       else if (EQ (cmd, Qtty_menu_next_item))
        {
          if (*y < max_y)
            *y += 1;
          else
-           *y = min_y;
+           st = MI_SCROLL_FORWARD;
        }
       else if (EQ (cmd, Qtty_menu_prev_item))
        {
          if (*y > min_y)
            *y -= 1;
          else
-           *y = max_y;
+           st = MI_SCROLL_BACK;
        }
       else if (EQ (cmd, Qtty_menu_select))
-       st = 1;
+       st = MI_ITEM_SELECTED;
       else if (!EQ (cmd, Qtty_menu_ignore))
        usable_input = 0;
       if (usable_input)
        sf->mouse_moved = 1;
       return st;
     }
-  return 0;
+  return MI_CONTINUE;
 }
 
 /* Display menu, wait for user's response, and return that response.  */
@@ -3214,6 +3222,7 @@
   struct tty_display_info *tty = FRAME_TTY (sf);
   bool first_time;
   Lisp_Object selectface;
+  int first_item = 0;
 
   /* Don't allow non-positive x0 and y0, lest the menu will wrap
      around the display.  */
@@ -3265,7 +3274,7 @@
      want to interpret them as zero-based column and row coordinates,
      and also because we want the first item of the menu, not its
      title, to appear at x0,y0.  */
-  tty_menu_display (menu, x0 - 1, y0 - 1, 1, title_faces, x0 - 1, y0 - 1, 0);
+  tty_menu_display (menu, x0 - 1, y0 - 1, 1, title_faces, x0 - 1, y0 - 1, 0, 
0);
 
   /* Turn off the cursor.  Otherwise it shows through the menu
      panes, which is ugly.  */
@@ -3292,7 +3301,7 @@
   leave = 0;
   while (!leave)
     {
-      int input_status;
+      mi_result input_status;
       int min_y = state[0].y;
       int max_y = min (min_y + state[0].menu->count, FRAME_LINES (sf) - 1) - 1;
 
@@ -3300,36 +3309,59 @@
       if (input_status)
        {
          leave = 1;
-         if (input_status == -1)
+         switch (input_status)
            {
+           case MI_QUIT_MENU:
              /* Remove the last help-echo, so that it doesn't
                 re-appear after "Quit".  */
              show_help_echo (Qnil, Qnil, Qnil, Qnil);
              result = TTYM_NO_SELECT;
-           }
-         else if (input_status == 2)
-           {
+             break;
+           case MI_NEXT_ITEM:
              if (kbd_navigation)
                result = TTYM_NEXT;
              else
                leave = 0;
-           }
-         else if (input_status == 3)
-           {
+             break;
+           case MI_PREV_ITEM:
              if (kbd_navigation)
                result = TTYM_PREV;
              else
                leave = 0;
+             break;
+           case MI_SCROLL_FORWARD:
+             if (y - min_y == state[0].menu->count - 1 - first_item)
+               {
+                 y = min_y;
+                 first_item = 0;
+               }
+             else
+               first_item++;
+             leave = 0;
+             break;
+           case MI_SCROLL_BACK:
+             if (first_item == 0)
+               {
+                 y = max_y;
+                 first_item = state[0].menu->count - 1 - (y - min_y);
+               }
+             else
+               first_item--;
+             leave = 0;
+             break;
+           default:
+             /* MI_ITEM_SELECTED is handled below, so nothing to do.  */
+             break;
            }
        }
-      if (sf->mouse_moved && input_status != -1)
+      if (sf->mouse_moved && input_status != MI_QUIT_MENU)
        {
          sf->mouse_moved = 0;
          result = TTYM_IA_SELECT;
          for (i = 0; i < statecount; i++)
            if (state[i].x <= x && x < state[i].x + state[i].menu->width + 2)
              {
-               int dy = y - state[i].y;
+               int dy = y - state[i].y + first_item;
                if (0 <= dy && dy < state[i].menu->count)
                  {
                    if (!state[i].menu->submenu[dy])
@@ -3358,7 +3390,7 @@
                                          state[i].x,
                                          state[i].y,
                                          state[i].pane,
-                                         faces, x, y, 1);
+                                         faces, x, y, first_item, 1);
                        state[statecount].menu = state[i].menu->submenu[dy];
                        state[statecount].pane = state[i].menu->panenumber[dy];
                        state[statecount].screen_behind
@@ -3374,7 +3406,7 @@
                            state[statecount - 1].x,
                            state[statecount - 1].y,
                            state[statecount - 1].pane,
-                           faces, x, y, 1);
+                           faces, x, y, first_item, 1);
          tty_hide_cursor (tty);
          fflush (tty->output);
        }


reply via email to

[Prev in Thread] Current Thread [Next in Thread]