From 4a174fd6706497b41007ad3c862286c926ef88b6 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Mon, 28 Feb 2011 19:31:35 +0000 Subject: [PATCH] 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 --- amiga/context_menu.c | 339 ++++++++++++++++++++++++++----------------- amiga/context_menu.h | 26 +--- amiga/gui.c | 49 ++++--- amiga/gui.h | 2 + 4 files changed, 238 insertions(+), 178 deletions(-) diff --git a/amiga/context_menu.c b/amiga/context_menu.c index c8850ca5b..bab4aa74b 100755 --- a/amiga/context_menu.c +++ b/amiga/context_menu.c @@ -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; diff --git a/amiga/context_menu.h b/amiga/context_menu.h index 5e6bed88a..d95cd2628 100755 --- a/amiga/context_menu.h +++ b/amiga/context_menu.h @@ -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 diff --git a/amiga/gui.c b/amiga/gui.c index e445a9c80..b75e053a1 100755 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -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) && (xwin,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; +} diff --git a/amiga/gui.h b/amiga/gui.h index 637ba44bf..61e886cfd 100755 --- a/amiga/gui.h +++ b/amiga/gui.h @@ -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;