Allow context menus in arbitrary positions outside the browsing area.

Add a Local History item to a new back button context menu, eventually this will give
a recent history list.

svn path=/trunk/netsurf/; revision=11858
This commit is contained in:
Chris Young 2011-02-28 19:31:35 +00:00
parent c03890339e
commit 4a174fd670
4 changed files with 238 additions and 178 deletions

View File

@ -44,6 +44,30 @@ uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved);
bool ami_context_menu_copy_selection(const char *text, size_t length, struct box *box,
void *handle, const char *whitespace_text, size_t whitespace_length);
enum {
CMID_SELECTFILE,
CMID_COPYURL,
CMID_URLOPENWIN,
CMID_URLOPENTAB,
CMID_SAVEURL,
CMID_SHOWOBJ,
CMID_COPYOBJ,
CMID_CLIPOBJ,
CMID_SAVEOBJ,
CMID_SAVEIFFOBJ,
CMID_SELALL,
CMID_SELCLEAR,
CMID_SELCUT,
CMID_SELCOPY,
CMID_SELPASTE,
CMID_SELSEARCH,
CMSUB_OBJECT,
CMSUB_URL,
CMSUB_SEL,
CMID_HISTORY,
CMID_LAST
};
char *ctxmenulab[CMID_LAST];
struct ami_context_menu_selection
@ -76,6 +100,9 @@ void ami_context_menu_init(void)
ctxmenulab[CMSUB_OBJECT] = ami_utf8_easy((char *)messages_get("Object"));
ctxmenulab[CMSUB_URL] = ami_utf8_easy((char *)messages_get("Link"));
ctxmenulab[CMSUB_SEL] = ami_utf8_easy((char *)messages_get("Selection"));
/* Back button */
ctxmenulab[CMID_HISTORY] = ami_utf8_easy((char *)messages_get("HistLocalNS"));
}
void ami_context_menu_free(void)
@ -88,6 +115,28 @@ void ami_context_menu_free(void)
}
}
BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap)
{
int top, left, width, height;
if(option_context_menu == false) return;
if((option_kiosk_mode == false) && (trap == FALSE) &&
(gwin->bw->browser_window_type == BROWSER_WINDOW_NORMAL))
{
if(ami_gadget_hit(gwin->objects[GID_BACK],
gwin->win->MouseX, gwin->win->MouseY))
trap = TRUE;
}
if(gwin->rmbtrapped == trap) return;
SetWindowAttr(gwin->win, WA_RMBTrap, trap, 1);
gwin->rmbtrapped = trap;
return trap;
}
void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y)
{
struct hlcache_handle *cc = gwin->bw->current_content;
@ -108,147 +157,165 @@ void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y)
PMA_MenuHandler, &gwin->popuphook,
TAG_DONE);
curbox = html_get_box_tree(gwin->bw->current_content);
while(curbox = box_at_point(curbox,x,y,&box_x,&box_y,&cc))
if(gwin->bw && gwin->bw->history &&
ami_gadget_hit(gwin->objects[GID_BACK],
gwin->win->MouseX, gwin->win->MouseY))
{
if (curbox->style && css_computed_visibility(curbox->style) == CSS_VISIBILITY_HIDDEN) continue;
IDoMethod(gwin->objects[OID_MENU], PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_HISTORY],
PMIA_ID, CMID_HISTORY,
TAG_DONE),
~0);
if(curbox->href)
menuhascontent = true;
}
else
{
curbox = html_get_box_tree(gwin->bw->current_content);
while(curbox = box_at_point(curbox,x,y,&box_x,&box_y,&cc))
{
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMSUB_URL],
PMSIMPLESUB,
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENWIN],
PMIA_ID,CMID_URLOPENWIN,
PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENTAB],
PMIA_ID,CMID_URLOPENTAB,
PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_COPYURL],
PMIA_ID,CMID_COPYURL,
PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEURL],
PMIA_ID,CMID_SAVEURL,
PMIA_UserData,curbox->href,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
if (curbox->style &&
css_computed_visibility(curbox->style) == CSS_VISIBILITY_HIDDEN)
continue;
menuhascontent = true;
}
if (curbox->object)
{
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMSUB_OBJECT],
PMSIMPLESUB,
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SHOWOBJ],
PMIA_ID,CMID_SHOWOBJ,
PMIA_UserData, content_get_url(curbox->object),
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_COPYOBJ],
PMIA_ID,CMID_COPYOBJ,
PMIA_UserData, content_get_url(curbox->object),
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_CLIPOBJ],
PMIA_ID,CMID_CLIPOBJ,
PMIA_UserData,curbox->object,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEOBJ],
PMIA_ID,CMID_SAVEOBJ,
PMIA_UserData,curbox->object,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEIFFOBJ],
PMIA_ID,CMID_SAVEIFFOBJ,
PMIA_UserData,curbox->object,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
menuhascontent = true;
}
if(curbox->text)
{
BOOL disabled_readonly = selection_read_only(gwin->bw->sel);
BOOL disabled_noselection = !selection_defined(gwin->bw->sel);
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMSUB_SEL],
PMIA_SubMenu, NewObject(POPUPMENU_GetClass(), NULL,
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELCUT],
PMIA_ID,CMID_SELCUT,
PMIA_Disabled, disabled_noselection && disabled_readonly,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELCOPY],
PMIA_ID,CMID_SELCOPY,
PMIA_Disabled, disabled_noselection,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELPASTE],
PMIA_ID,CMID_SELPASTE,
PMIA_Disabled, (gwin->bw->window->c_h == 0),
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELALL],
PMIA_ID,CMID_SELALL,
//PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELCLEAR],
PMIA_ID,CMID_SELCLEAR,
PMIA_Disabled, disabled_noselection,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, ~0,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELSEARCH],
PMIA_ID,CMID_SELSEARCH,
PMIA_Disabled, disabled_noselection,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
menuhascontent = true;
}
if (curbox->gadget)
{
switch (curbox->gadget->type)
if(curbox->href)
{
case GADGET_FILE:
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELECTFILE],
PMIA_ID,CMID_SELECTFILE,
PMIA_UserData,curbox,
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMSUB_URL],
PMSIMPLESUB,
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENWIN],
PMIA_ID,CMID_URLOPENWIN,
PMIA_UserData,curbox->href,
TAG_DONE),
~0);
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_URLOPENTAB],
PMIA_ID,CMID_URLOPENTAB,
PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_COPYURL],
PMIA_ID,CMID_COPYURL,
PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEURL],
PMIA_ID,CMID_SAVEURL,
PMIA_UserData,curbox->href,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
menuhascontent = true;
break;
menuhascontent = true;
}
if (curbox->object)
{
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMSUB_OBJECT],
PMSIMPLESUB,
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SHOWOBJ],
PMIA_ID,CMID_SHOWOBJ,
PMIA_UserData, content_get_url(curbox->object),
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_COPYOBJ],
PMIA_ID,CMID_COPYOBJ,
PMIA_UserData, content_get_url(curbox->object),
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_CLIPOBJ],
PMIA_ID,CMID_CLIPOBJ,
PMIA_UserData,curbox->object,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEOBJ],
PMIA_ID,CMID_SAVEOBJ,
PMIA_UserData,curbox->object,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SAVEIFFOBJ],
PMIA_ID,CMID_SAVEIFFOBJ,
PMIA_UserData,curbox->object,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
menuhascontent = true;
}
if(curbox->text)
{
BOOL disabled_readonly = selection_read_only(gwin->bw->sel);
BOOL disabled_noselection = !selection_defined(gwin->bw->sel);
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMSUB_SEL],
PMIA_SubMenu, NewObject(POPUPMENU_GetClass(), NULL,
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELCUT],
PMIA_ID,CMID_SELCUT,
PMIA_Disabled, disabled_noselection && disabled_readonly,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELCOPY],
PMIA_ID,CMID_SELCOPY,
PMIA_Disabled, disabled_noselection,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELPASTE],
PMIA_ID,CMID_SELPASTE,
PMIA_Disabled, (gwin->bw->window->c_h == 0),
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELALL],
PMIA_ID,CMID_SELALL,
//PMIA_UserData,curbox->href,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELCLEAR],
PMIA_ID,CMID_SELCLEAR,
PMIA_Disabled, disabled_noselection,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, ~0,
TAG_DONE),
PMA_AddItem,NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELSEARCH],
PMIA_ID,CMID_SELSEARCH,
PMIA_Disabled, disabled_noselection,
TAG_DONE),
TAG_DONE),
TAG_DONE),
~0);
menuhascontent = true;
}
if (curbox->gadget)
{
switch (curbox->gadget->type)
{
case GADGET_FILE:
IDoMethod(gwin->objects[OID_MENU],PM_INSERT,
NewObject(POPUPMENU_GetItemClass(), NULL,
PMIA_Title, (ULONG)ctxmenulab[CMID_SELECTFILE],
PMIA_ID,CMID_SELECTFILE,
PMIA_UserData,curbox,
TAG_DONE),
~0);
menuhascontent = true;
break;
}
}
}
}
@ -405,6 +472,10 @@ uint32 ami_context_menu_hook(struct Hook *hook,Object *item,APTR reserved)
}
break;
case CMID_HISTORY:
ami_history_open(gwin->bw, gwin->bw->history);
break;
case CMID_SELCUT:
browser_window_key_press(gwin->bw, KEY_CUT_SELECTION);
break;

View File

@ -20,30 +20,8 @@
#define AMIGA_CONTEXT_MENU_H
#include "amiga/gui.h"
enum {
CMID_SELECTFILE,
CMID_COPYURL,
CMID_URLOPENWIN,
CMID_URLOPENTAB,
CMID_SAVEURL,
CMID_SHOWOBJ,
CMID_COPYOBJ,
CMID_CLIPOBJ,
CMID_SAVEOBJ,
CMID_SAVEIFFOBJ,
CMID_SELALL,
CMID_SELCLEAR,
CMID_SELCUT,
CMID_SELCOPY,
CMID_SELPASTE,
CMID_SELSEARCH,
CMSUB_OBJECT,
CMSUB_URL,
CMSUB_SEL,
CMID_LAST
};
void ami_context_menu_init(void);
void ami_context_menu_free(void);
void ami_context_menu_show(struct gui_window_2 *gwin,int x,int y);
BOOL ami_context_menu_mouse_trap(struct gui_window_2 *gwin, BOOL trap);
void ami_context_menu_show(struct gui_window_2 *gwin, int x, int y);
#endif

View File

@ -142,7 +142,6 @@ struct ApplicationIFace *IApplication=NULL;
Class *urlStringClass;
BOOL rmbtrapped;
BOOL locked_screen = FALSE;
BOOL screen_closed = FALSE;
struct MsgPort *applibport = NULL;
@ -1054,12 +1053,7 @@ void ami_handle_msg(void)
if((x>=xs) && (y>=ys) && (x<width+xs) && (y<height+ys))
{
ami_update_quals(gwin);
if(option_context_menu && rmbtrapped == FALSE)
{
SetWindowAttr(gwin->win,WA_RMBTrap,(APTR)TRUE,1);
rmbtrapped=TRUE; // crash points to this line
}
ami_context_menu_mouse_trap(gwin, TRUE);
if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
{
@ -1078,11 +1072,7 @@ void ami_handle_msg(void)
}
else
{
if(option_context_menu && rmbtrapped == TRUE)
{
SetWindowAttr(gwin->win,WA_RMBTrap,FALSE,1);
rmbtrapped=FALSE;
}
ami_context_menu_mouse_trap(gwin, FALSE);
if(!gwin->mouse_state) ami_update_pointer(gwin->win,GUI_POINTER_DEFAULT);
}
@ -1119,14 +1109,6 @@ void ami_handle_msg(void)
browser_window_mouse_click(gwin->bw,BROWSER_MOUSE_PRESS_2 | gwin->key_state,x,y);
gwin->mouse_state=BROWSER_MOUSE_PRESS_2;
break;
case MENUDOWN:
if(!option_sticky_context_menu) ami_context_menu_show(gwin,x,y);
break;
case MENUUP:
if(option_sticky_context_menu) ami_context_menu_show(gwin,x,y);
break;
}
}
@ -1137,6 +1119,16 @@ void ami_handle_msg(void)
switch(code)
{
case MENUDOWN:
if(!option_sticky_context_menu)
ami_context_menu_show(gwin,x,y);
break;
case MENUUP:
if(option_sticky_context_menu)
ami_context_menu_show(gwin,x,y);
break;
case SELECTUP:
if(gwin->mouse_state & BROWSER_MOUSE_PRESS_1)
{
@ -2844,6 +2836,7 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw,
TAG_DONE);
}
gwin->shared->rmbtrapped = FALSE;
gwin->shared->bw = bw;
curbw = bw;
@ -3900,3 +3893,19 @@ struct box *ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y)
}
return text_box;
}
BOOL ami_gadget_hit(Object *obj, int x, int y)
{
int top, left, width, height;
GetAttrs(obj,
GA_Left, &left,
GA_Top, &top,
GA_Width, &width,
GA_Height, &height,
TAG_DONE);
if((x >= left) && (x <= (left + width)) && (y >= top) && (y <= (top + height)))
return TRUE;
else return FALSE;
}

View File

@ -107,6 +107,7 @@ struct gui_window_2 {
char *wintitle;
char *helphints[GID_LAST];
struct timeval lastclick;
BOOL rmbtrapped;
};
struct gui_window
@ -134,6 +135,7 @@ void ami_do_redraw(struct gui_window_2 *g);
STRPTR ami_locale_langs(void);
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
struct box *ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
BOOL ami_gadget_hit(Object *obj, int x, int y);
struct TextFont *origrpfont;
struct MinList *window_list;