From 41f219192c6a9ee34a14d0cb149946eff9eeec50 Mon Sep 17 00:00:00 2001 From: Chris Young Date: Fri, 4 Sep 2015 00:26:52 +0100 Subject: Create back/forward context menu using menuclass Reconstructs itself periodically as it cannot be created on demand --- amiga/ctxmenu.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++------ amiga/ctxmenu.h | 17 +++++++ amiga/gui.c | 22 ++++++--- amiga/gui.h | 1 + 4 files changed, 164 insertions(+), 20 deletions(-) diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c index bf16e21b0..1fe34baad 100644 --- a/amiga/ctxmenu.c +++ b/amiga/ctxmenu.c @@ -41,6 +41,7 @@ #include "amiga/utf8.h" #include "desktop/browser.h" +#include "desktop/browser_history.h" #include "desktop/mouse.h" #include "utils/log.h" @@ -52,6 +53,27 @@ enum { AMI_CTX_ID_URLOPEN, AMI_CTX_ID_URLOPENWIN, AMI_CTX_ID_URLOPENTAB, + AMI_CTX_ID_HISTORY, + AMI_CTX_ID_HISTORY0, + AMI_CTX_ID_HISTORY1, + AMI_CTX_ID_HISTORY2, + AMI_CTX_ID_HISTORY3, + AMI_CTX_ID_HISTORY4, + AMI_CTX_ID_HISTORY5, + AMI_CTX_ID_HISTORY6, + AMI_CTX_ID_HISTORY7, + AMI_CTX_ID_HISTORY8, + AMI_CTX_ID_HISTORY9, + AMI_CTX_ID_HISTORY0F, + AMI_CTX_ID_HISTORY1F, + AMI_CTX_ID_HISTORY2F, + AMI_CTX_ID_HISTORY3F, + AMI_CTX_ID_HISTORY4F, + AMI_CTX_ID_HISTORY5F, + AMI_CTX_ID_HISTORY6F, + AMI_CTX_ID_HISTORY7F, + AMI_CTX_ID_HISTORY8F, + AMI_CTX_ID_HISTORY9F, AMI_CTX_ID_MAX }; @@ -62,11 +84,6 @@ static char *ctxmenu_item_label[AMI_CTX_ID_MAX]; static Object *ctxmenu_item_image[AMI_CTX_ID_MAX]; /** Menu functions - called automatically by RA_HandleInput **/ -HOOKF(void, ami_ctxmenu_item_test, APTR, window, struct IntuiMessage *) -{ - printf("testing\n"); -} - HOOKF(void, ami_ctxmenu_item_urlopentab, APTR, window, struct IntuiMessage *) { struct browser_window *bw; @@ -101,6 +118,16 @@ HOOKF(void, ami_ctxmenu_item_urlopenwin, APTR, window, struct IntuiMessage *) warn_user(messages_get_errorcode(error), 0); } +HOOKF(void, ami_ctxmenu_item_history, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + + browser_window_history_go(gwin->gw->bw, (struct history_entry *)hook->h_Data, false); +} + + /** Add an initialised item to a context menu **/ static void ami_ctxmenu_add_item(Object *root_menu, int id, APTR data) @@ -169,16 +196,19 @@ static uint32 ami_ctxmenu_hook_func(struct Hook *hook, struct Window *window, st static void ami_ctxmenu_alloc_item(int id, const char *label, const char *image, void *func) { ctxmenu_item_label[id] = ami_utf8_easy(messages_get(label)); - ctxmenu_item_image[id] = BitMapObj, - BITMAP_Screen, scrn, - BITMAP_SourceFile, image, - BITMAP_Masking, TRUE, - BitMapEnd; - SetAttrs(ctxmenu_item_image[id], - BITMAP_Width, 16, - BITMAP_Height, 16, - TAG_DONE); + if(image != NULL) { + ctxmenu_item_image[id] = BitMapObj, + BITMAP_Screen, scrn, + BITMAP_SourceFile, image, + BITMAP_Masking, TRUE, + BitMapEnd; + + SetAttrs(ctxmenu_item_image[id], + BITMAP_Width, 16, + BITMAP_Height, 16, + TAG_DONE); + } ctxmenu_item_hook[id].h_Entry = func; ctxmenu_item_hook[id].h_Data = 0; @@ -224,5 +254,91 @@ void ami_ctxmenu_free(void) if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj); ctxmenu_obj = NULL; } + + + +/** Create menu entries from browser history **/ +static bool ami_ctxmenu_history(int direction, struct gui_window_2 *gwin, const struct history_entry *entry) +{ + Object *history_root; + int id = AMI_CTX_ID_HISTORY0 + gwin->temp; + if(direction == AMI_CTXMENU_HISTORY_FORWARD) id += 10; + + if(gwin->temp >= 10) return false; + + ctxmenu_item_hook[id].h_Entry = (HOOKFUNC)ami_ctxmenu_item_history; + ctxmenu_item_hook[id].h_Data = (APTR)entry; + + history_root = (Object *)IDoMethod(gwin->history_ctxmenu[direction], MM_FINDID, 0, AMI_CTX_ID_HISTORY); + + IDoMethod(history_root, OM_ADDMEMBER, MStrip, + MA_Type, T_ITEM, + MA_Label, browser_window_history_entry_get_title(entry), + MA_ID, id, + MA_Image, NULL, + MA_UserData, &ctxmenu_item_hook[id], + MEnd); + + gwin->temp++; + + return true; +} + +/** Callback for browser_window_history_enumerate **/ +static bool ami_ctxmenu_history_back(const struct browser_window *bw, + int x0, int y0, int x1, int y1, + const struct history_entry *entry, void *user_data) +{ + return ami_ctxmenu_history(AMI_CTXMENU_HISTORY_BACK, (struct gui_window_2 *)user_data, entry); +} + +/** Callback for browser_window_history_enumerate **/ +static bool ami_ctxmenu_history_forward(const struct browser_window *bw, + int x0, int y0, int x1, int y1, + const struct history_entry *entry, void *user_data) +{ + return ami_ctxmenu_history(AMI_CTXMENU_HISTORY_FORWARD, (struct gui_window_2 *)user_data, entry); +} + +/** Exported interface documented in ctxmenu.h **/ +struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin) +{ + Object *obj; + + if(gwin->history_ctxmenu[direction] == NULL) { + if(ctxmenu_item_label[AMI_CTX_ID_HISTORY] == NULL) + ctxmenu_item_label[AMI_CTX_ID_HISTORY] = ami_utf8_easy(messages_get("History")); + + gwin->history_ctxmenu[direction] = MStrip, + MA_Type, T_ROOT, + MA_AddChild, MStrip, + MA_Type, T_MENU, + MA_ID, AMI_CTX_ID_HISTORY, + MA_Label, ctxmenu_item_label[AMI_CTX_ID_HISTORY], + MA_EmbeddedKey, FALSE, + //MA_FreeImage, FALSE, + MEnd, + MEnd; + } else { + for (int i = 0; i < 20; i++) { + obj = (Object *)IDoMethod(gwin->history_ctxmenu[direction], + MM_FINDID, 0, AMI_CTX_ID_HISTORY0 + i); + if(obj != NULL) IDoMethod(gwin->history_ctxmenu[direction], OM_REMMEMBER, obj); + } + + gwin->temp = 0; + + if(direction == AMI_CTXMENU_HISTORY_BACK) { + browser_window_history_enumerate_back(gwin->gw->bw, ami_ctxmenu_history_back, gwin); + } else { + browser_window_history_enumerate_forward(gwin->gw->bw, ami_ctxmenu_history_forward, gwin); + } + } + + return (struct Menu *)gwin->history_ctxmenu[direction]; +} + + + #endif diff --git a/amiga/ctxmenu.h b/amiga/ctxmenu.h index 678208647..39fce2f68 100644 --- a/amiga/ctxmenu.h +++ b/amiga/ctxmenu.h @@ -24,6 +24,13 @@ #define AMIGA_CTXMENU_H 1 struct Hook; +struct Menu; +struct gui_window_2; + +enum { + AMI_CTXMENU_HISTORY_BACK = 0, + AMI_CTXMENU_HISTORY_FORWARD = 1 +}; /** * Initialise context menus code (allocate label text, etc) @@ -50,6 +57,16 @@ struct Hook *ami_ctxmenu_get_hook(APTR data); * \param hook ptr to hook */ void ami_ctxmenu_release_hook(struct Hook *hook); + +/** + * Create history context menu. First run sets up the menu, next creates entries. + * + * \param gwin struct gui_window_2 * + * \returns pointer to menu + */ +struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin); + + #else inline void ami_ctxmenu_init(void) {} inline void ami_ctxmenu_free(void) {} diff --git a/amiga/gui.c b/amiga/gui.c index 9b312e52f..3a09a1e1b 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -1103,6 +1103,10 @@ static void ami_update_buttons(struct gui_window_2 *gwin) SetGadgetAttrs((struct Gadget *)gwin->objects[GID_CLOSETAB], gwin->win, NULL, GA_Disabled, tabclose, TAG_DONE); } + + /* Update the back/forward buttons history context menu */ + ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_BACK, gwin); + ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_FORWARD, gwin); } void ami_gui_history(struct gui_window_2 *gwin, bool back) @@ -3771,6 +3775,8 @@ gui_window_create(struct browser_window *bw, newprefs_hook.h_Data = 0; g->shared->ctxmenu_hook = ami_ctxmenu_get_hook(g->shared); + g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK] = NULL; + g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD] = NULL; if(nsoption_bool(window_simple_refresh) == true) { refresh_mode = WA_SimpleRefresh; @@ -3962,9 +3968,10 @@ gui_window_create(struct browser_window *bw, LAYOUT_AddChild, g->shared->objects[GID_TOOLBARLAYOUT] = LayoutHObj, LAYOUT_VertAlignment, LALIGN_CENTER, LAYOUT_AddChild, g->shared->objects[GID_BACK] = ButtonObj, - GA_ID,GID_BACK, - GA_RelVerify,TRUE, - GA_Disabled,TRUE, + GA_ID, GID_BACK, + GA_RelVerify, TRUE, + GA_Disabled, TRUE, + GA_ContextMenu, ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_BACK, g->shared), GA_HintInfo, g->shared->helphints[GID_BACK], BUTTON_RenderImage,BitMapObj, BITMAP_SourceFile,nav_west, @@ -3977,9 +3984,10 @@ gui_window_create(struct browser_window *bw, CHILD_WeightedWidth,0, CHILD_WeightedHeight,0, LAYOUT_AddChild, g->shared->objects[GID_FORWARD] = ButtonObj, - GA_ID,GID_FORWARD, - GA_RelVerify,TRUE, - GA_Disabled,TRUE, + GA_ID, GID_FORWARD, + GA_RelVerify, TRUE, + GA_Disabled, TRUE, + GA_ContextMenu, ami_ctxmenu_history_create(AMI_CTXMENU_HISTORY_FORWARD, g->shared), GA_HintInfo, g->shared->helphints[GID_FORWARD], BUTTON_RenderImage,BitMapObj, BITMAP_SourceFile,nav_east, @@ -4391,6 +4399,8 @@ static void gui_window_destroy(struct gui_window *g) ami_gui_opts_websearch_free(g->shared->web_search_list); if(g->shared->search_bm) DisposeObject(g->shared->search_bm); + DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_BACK]); + DisposeObject((Object *)g->shared->history_ctxmenu[AMI_CTXMENU_HISTORY_FORWARD]); ami_ctxmenu_release_hook(g->shared->ctxmenu_hook); ami_free_menulabs(g->shared); #ifndef __amigaos4__ diff --git a/amiga/gui.h b/amiga/gui.h index 9f8284b56..d23f9c919 100644 --- a/amiga/gui.h +++ b/amiga/gui.h @@ -133,6 +133,7 @@ struct gui_window_2 { struct Hook favicon_hook; struct Hook throbber_hook; struct Hook *ctxmenu_hook; + Object *history_ctxmenu[2]; gui_drag_type drag_op; struct IBox *ptr_lock; struct AppWindow *appwin; -- cgit v1.2.3