[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 */
{
/*
- lynx-dev [PATCH] Context-sensitive menu etc.,
Ilya Zakharevich <=