lynx-dev
[Top][All Lists]
Advanced

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

lynx-dev [PATCH] Context-sensitive menu etc.


From: Ilya Zakharevich
Subject: lynx-dev [PATCH] Context-sensitive menu etc.
Date: Sun, 6 Dec 1998 00:15:37 -0500 (EST)

This patch adds following functionality to lynx:

        a) If one clicks mouse *near* a link, the "point/focus" is moved to 
                this link (without actual activation);
        b) One can bind keys with ordinals larger than DO_NOTHING;
        c) Primitive context sensitive menu added to the middle button of
           a mouse (currently ncurses only);

Current micro-problem with "c" is that I do not know how to refresh a
screen *before* triggering the action, so if the action choosen from
the menu would not redraw the screen, the menu outline is left on the
screen.

Enjoy,
Ilya

--- ./src/LYKeymap.c.pp Sat Dec  5 23:59:32 1998
+++ ./src/LYKeymap.c    Sat Dec  5 21:18:22 1998
@@ -339,7 +339,7 @@ LYK_DO_NOTHING,
    0,                  0,              0,             0,
    0,                  0,              0,             0,
    /* 290...293 */
-   0,                  0,              0,             0,
+   LYK_CHANGE_LINK,    0,              0,             0,
 };
 
 #if defined(DIRED_SUPPORT) && defined(OK_OVERRIDE)
@@ -583,6 +583,7 @@ PRIVATE struct rmap revmap[] = {
 { "CLEAR_AUTH",                "clear all authorization info for this session" 
},
 { "SWITCH_DTD",                "switch between two ways of parsing HTML" },
 { "ELGOTO",            "edit the current link's URL or ACTION and go to it" },
+{ "CHANGE_LINK",       "force reset of the current link on the page" },
 #ifdef USE_EXTERNALS
 { "EXTERN",            "run external program with url" },
 #endif
@@ -936,7 +939,7 @@ PUBLIC BOOL LYisNonAlnumKeyname ARGS2(
 {
     if ((ch >= '0' && ch <= '9') ||
         (ch >= 'A' && ch <= 'z') ||
-       ch < 0 || ch > 269)
+       ch < 0 || ch >= TABLESIZE(keymap))
        return (FALSE);
 
     return(keymap[ch+1] == key_name);
--- ./src/LYMainLoop.c.pp       Sat Dec  5 23:59:20 1998
+++ ./src/LYMainLoop.c  Sat Dec  5 20:31:12 1998
@@ -2501,6 +2501,18 @@ new_cmd:  /*
            }
            break;
 
+       case LYK_CHANGE_LINK:
+       {
+           /* Is there a mouse-clicked link waiting? */
+           int mouse_tmp = get_mouse_link();
+           /* If yes, use it as the link */
+           if (mouse_tmp != -1) {
+               highlight(OFF, curdoc.link, prev_target);
+               curdoc.link = mouse_tmp;                 
+           }
+           break;
+       }
+
        case LYK_RIGHT_LINK:
            if (curdoc.link<nlinks-1 &&
                        links[curdoc.link].ly == links[curdoc.link+1].ly) {
--- ./src/LYOptions.c.pp        Sat Dec  5 23:59:32 1998
+++ ./src/LYOptions.c   Sun Nov 29 03:12:00 1998
@@ -33,13 +33,6 @@ PRIVATE int boolean_choice PARAMS((
        int             line,
        int             column,
        char **         choices));
-PRIVATE int popup_choice PARAMS((
-       int             cur_choice,
-       int             line,
-       int             column,
-       char **         choices,
-       int             i_length,
-       int             disabled));
 
 #define MAXCHOICES 10
 
@@ -2178,7 +2171,7 @@ PRIVATE int get_popup_choice_number ARGS
  *  option via a popup window which functions like
  *  that for selection of options in a form. - FM
  */
-PRIVATE int popup_choice ARGS6(
+PUBLIC int popup_choice ARGS6(
        int,            cur_choice,
        int,            line,
        int,            column,
--- ./src/LYOptions.h.pp        Sat Dec  5 23:59:32 1998
+++ ./src/LYOptions.h   Sun Nov 29 03:12:26 1998
@@ -6,6 +6,13 @@
 extern BOOLEAN term_options; /* for LYgetstr() */
 
 extern void edit_bookmarks NOPARAMS;
+extern  int popup_choice PARAMS((
+       int             cur_choice,
+       int             line,
+       int             column,
+       char **         choices,
+       int             i_length,
+       int             disabled));
 
 #ifndef NO_OPTION_FORMS
 extern int postoptions PARAMS((document *newdoc));
--- ./src/LYStrings.c.pp        Sun Dec  6 00:06:42 1998
+++ ./src/LYStrings.c   Sat Dec  5 23:52:56 1998
@@ -37,6 +37,7 @@ extern HTCJKlang HTCJK;
 
 /* The number of the link selected w/ the mouse (-1 if none) */
 static int mouse_link = -1;
+static int mouse_is_exact;
 
 static int have_levent;
 
@@ -74,6 +75,20 @@ PUBLIC int peek_mouse_link NOARGS
   return mouse_link;
 }
 
+PRIVATE int XYdist ARGS5(int,x1,int,y1,int,x2,int,y2,int,dx2)
+{
+    int xerr = x2 - x1, yerr = y2 - y1;
+
+    if (xerr < 0)
+       xerr = x1 - x2 - dx2;
+    if (xerr < 0)
+       xerr = 0;
+    if (yerr < 0)
+       yerr = -yerr;
+    return xerr + yerr;
+}
+
+
 /* Given X and Y coordinates of a mouse event, set mouse_link to the
 ** index of the corresponding hyperlink, or set mouse_link to -1 if no
 ** link matches the event.  Returns -1 if no link matched the click,
@@ -100,6 +115,8 @@ PRIVATE int set_clicked_link ARGS3(int,x
        else if (x > right) c = '\b';
        else c = PGUP;
     } else {
+       int mouse_err = 1000000, cur_err;
+
        /* Loop over the links and see if we can get a match */
        for (i = 0; i < nlinks; i++) {
            int len, lx = links[i].lx, is_text = 0;
@@ -116,26 +133,39 @@ PRIVATE int set_clicked_link ARGS3(int,x
                len = strlen(links[i].hightext );
 
            /* Check the first line of the link */
-           if ( links[i].hightext != NULL &&
-               links[i].ly == y && (x - lx) < len && (x >= lx)) {
-               int cury, curx;
+           if ( links[i].hightext != NULL) {
+               cur_err = XYdist(x,y,links[i].lx,links[i].ly,len);
+               if (cur_err == 0) {
+                   int cury, curx;
                
-               if (code != FOR_INPUT
-                   /* Do not pick up the current input field */
-                   || !(LYGetYX(cury,curx), 
-                        (cury == y && (curx >= lx) && ((curx - lx) <= len)))) {
-                   if (is_text)
-                       have_levent = 1;
+                   if (code != FOR_INPUT
+                       /* Do not pick up the current input field */
+                       || !(LYGetYX(cury,curx), 
+                            (cury == y && (curx >= lx) && ((curx - lx) <= 
len)))) {
+                       if (is_text)
+                           have_levent = 1;
+                       mouse_link = i;
+                   } else
+                       mouse_link = -1;
+                   mouse_err = 0;
+                   break;
+               } else if (cur_err < mouse_err) {
+                   mouse_err = cur_err;
                    mouse_link = i;
-
-}              break;              
+               }
            }
            /* Check the second line */
-           if (links[i].hightext2 != NULL &&
-               1+links[i].ly == y &&
-               (x - links[i].hightext2_offset) < 
(int)strlen(links[i].hightext2) ) {
-               mouse_link = i;
-               break;
+           if (links[i].hightext2 != NULL) {       
+               cur_err = XYdist(x,y,links[i].hightext2_offset,links[i].ly+1,
+                                strlen(links[i].hightext2));
+               if (cur_err == 0) {
+                   mouse_link = i;
+                   mouse_err = 0;
+                   break;
+               } else if (cur_err < mouse_err) {
+                   mouse_err = cur_err;
+                   mouse_link = i;
+               }               
            }
        }
        /*
@@ -143,8 +173,12 @@ PRIVATE int set_clicked_link ARGS3(int,x
         * LYK_ACTIVATE We expect to find LYK_ACTIVATE (it's usually mapped to
         * the Enter key).
         */
-       if (mouse_link >= 0)
-           c = lookup_keymap(LYK_ACTIVATE);
+       if (mouse_link >= 0) {
+           if (mouse_err == 0)
+               c = lookup_keymap(LYK_ACTIVATE);
+           else if (mouse_err < 1000000)
+               c = lookup_keymap(LYK_CHANGE_LINK);
+       }
     }
     return c;
 }
@@ -828,6 +862,91 @@ PUBLIC int lynx_initialize_keymaps NOARG
 
 #endif                                /* USE_KEYMAPS */
 
+PRIVATE int LYmouse_menu ARGS3(int, x, int, y, int, atlink)
+{
+    char *choices[] = {
+       "Quit",
+       "Home page",
+       "Previous document",
+       "Beginning of document",
+       "Page up",
+       "Half page up",
+       "Two lines up",
+       "History",
+       "Help",
+       "Do nothing (refresh)",
+       "Load again",
+       "Edit URL and load",
+       "Show info",
+       "Search",
+       "Print",
+       "Two lines down",
+       "Half page down",
+       "Page down",
+       "End of document",
+       "Bookmarks",
+/*     "Cookie jar", */
+       "Search index",
+       "Set Options",
+       NULL
+    };
+    char *choices_link[] = {
+       "Help",
+       "Do nothing",
+       "Activate this link",
+       "Show info",
+       "Download",
+       NULL
+    };
+    int actions[] = {
+       LYK_ABORT,
+       LYK_MAIN_MENU,
+       LYK_PREV_DOC,
+       LYK_HOME,
+       LYK_PREV_PAGE,
+       LYK_UP_HALF,
+       LYK_UP_TWO,
+       LYK_HISTORY,
+       LYK_HELP,
+       LYK_REFRESH,
+       LYK_RELOAD,
+       LYK_ECGOTO,
+       LYK_INFO,
+       LYK_WHEREIS,
+       LYK_PRINT,
+       LYK_DOWN_TWO,
+       LYK_DOWN_HALF,
+       LYK_NEXT_PAGE,
+       LYK_END,
+       LYK_VIEW_BOOKMARK,
+/*     LYK_COOKIE_JAR, */
+       LYK_INDEX_SEARCH,
+       LYK_OPTIONS
+    };
+    int actions_link[] = {
+       LYK_HELP,
+       LYK_REFRESH,
+       LYK_ACTIVATE,
+       LYK_INFO,
+       LYK_DOWNLOAD
+    };
+    int c;
+    
+    if (LYlines < 24) {
+        HTAlert(OPTION_SCREEN_NEEDS_24);
+        return;
+    }
+    /* Somehow the mouse is over the number instead of being over the
+       name, so we decrease x. */
+    c = popup_choice((atlink ? 2 : 9) - 1, y, (x >= 5 ? x-5 : 0), 
+                    (atlink ? choices_link : choices), 
+                    (atlink 
+                     ? (sizeof(actions_link)/sizeof(int)) 
+                     : (sizeof(actions)/sizeof(int))), FALSE);
+    
+    return atlink ? (actions_link[c]) : (actions[c]);
+}
+
 #if defined(USE_KEYMAPS) && defined(USE_SLANG)
 
 /* We cannot guarantee the type for 'GetChar', and should not use a cast. */
@@ -1197,6 +1316,23 @@ re_read:
                        c = LYReverseKeymap(LYK_MAIN_MENU);
                } else if (event.bstate & BUTTON3_CLICKED) {
                    c = LYReverseKeymap (LYK_PREV_DOC);
+               } else if (event.bstate & BUTTON2_CLICKED) {
+                   int atlink;
+
+                   c = set_clicked_link(event.x, event.y, code);
+                   atlink = c == LYReverseKeymap (LYK_ACTIVATE);
+                   if (!atlink)
+                       mouse_link = -1; /* Forget about approx stuff. */
+
+                   c = LYmouse_menu(event.x, event.y, atlink);
+                   if (c == LYK_ACTIVATE && mouse_link == -1) {
+                       HTAlert("No link chosen");
+                       c = LYK_DO_NOTHING;
+                       c = LYK_REFRESH; /* refresh() below does not work... */
+                   }
+                   c = LYReverseKeymap(c);
+                   lynx_force_repaint();
+                   refresh();
                }
                if (code == FOR_INPUT && mouse_link == -1) {
                    ungetmouse(&event); /* Caller will process this. */
@@ -1295,7 +1431,7 @@ re_read:
 #if (defined(__DJGPP__) || defined(_WINDOWS))
     if (c > 659)
 #else
-    if (c > DO_NOTHING)
+    if (c >= 0x293)
 #endif /* __DJGPP__ || _WINDOWS */
     {
        /*

reply via email to

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