diff --git a/amiga/ctxmenu.c b/amiga/ctxmenu.c index 17c3d6d46..42d0da38b 100644 --- a/amiga/ctxmenu.c +++ b/amiga/ctxmenu.c @@ -78,6 +78,9 @@ enum { AMI_CTX_ID_HISTORY0, AMI_CTX_ID_HISTORY9F = AMI_CTX_ID_HISTORY0 + 19, + /* Tabs */ + AMI_CTX_ID_TABNEW, + AMI_CTX_ID_MAX }; @@ -85,8 +88,8 @@ static Object *ctxmenu_obj = NULL; static struct Hook ctxmenu_item_hook[AMI_CTX_ID_MAX]; static char *ctxmenu_item_label[AMI_CTX_ID_MAX]; +static char *ctxmenu_item_shortcut[AMI_CTX_ID_MAX]; static Object *ctxmenu_item_image[AMI_CTX_ID_MAX]; -static char ctxmenu_item_shortcut[AMI_CTX_ID_MAX]; /**************************** * Menu item hook functions * @@ -211,6 +214,15 @@ HOOKF(void, ami_ctxmenu_item_frameshow, APTR, window, struct IntuiMessage *) NULL); } +/** Hooks for clicktab context menu entries **/ +HOOKF(void, ami_ctxmenu_item_tabnew, APTR, window, struct IntuiMessage *) +{ + struct gui_window_2 *gwin; + + GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin); + ami_gui_new_blank_tab(gwin); +} + /** Hook for history context menu entries **/ HOOKF(void, ami_ctxmenu_item_history, APTR, window, struct IntuiMessage *) { @@ -233,11 +245,11 @@ static void ami_ctxmenu_add_item(Object *root_menu, int id, APTR data) IDoMethod(root_menu, OM_ADDMEMBER, MStrip, MA_Type, T_ITEM, - MA_Label, ctxmenu_item_label[id], MA_ID, id, + MA_Label, ctxmenu_item_label[id], + MA_Key, ctxmenu_item_shortcut[id], MA_Image, ctxmenu_item_image[id], MA_UserData, &ctxmenu_item_hook[id], - MA_Key, &ctxmenu_item_shortcut[id], MEnd); } @@ -328,7 +340,7 @@ static uint32 ami_ctxmenu_hook_func(struct Hook *hook, struct Window *window, st } /** Initial menu item creation **/ -static void ami_ctxmenu_alloc_item(int id, const char *label, char key, const char *image, void *func) +static void ami_ctxmenu_alloc_item(int id, const char *label, const char *key, const char *image, void *func) { if(label == ML_SEPARATOR) { ctxmenu_item_label[id] = ML_SEPARATOR; @@ -336,7 +348,11 @@ static void ami_ctxmenu_alloc_item(int id, const char *label, char key, const ch ctxmenu_item_label[id] = ami_utf8_easy(messages_get(label)); } - ctxmenu_item_shortcut[id] = key; + if(key != NULL) { + ctxmenu_item_shortcut[id] = strdup(key); + } else { + ctxmenu_item_shortcut[id] = NULL; + } if(image != NULL) { ctxmenu_item_image[id] = BitMapObj, @@ -374,9 +390,14 @@ void ami_ctxmenu_release_hook(struct Hook *hook) void ami_ctxmenu_free(void) { for(int i = 1; i < AMI_CTX_ID_MAX; i++) { - if(ctxmenu_item_label[i] != NULL) { + if((ctxmenu_item_label[i] != NULL) && (ctxmenu_item_label[i] != ML_SEPARATOR)) { ami_utf8_free(ctxmenu_item_label[i]); - ctxmenu_item_label[i] = NULL; + } + ctxmenu_item_label[i] = NULL; + + if(ctxmenu_item_shortcut[i] != NULL) { + free(ctxmenu_item_shortcut[i]); + ctxmenu_item_shortcut[i] = NULL; } if(ctxmenu_item_image[i] != NULL) { @@ -392,30 +413,32 @@ void ami_ctxmenu_free(void) /** Exported interface documented in ctxmenu.h **/ void ami_ctxmenu_init(void) { - ami_ctxmenu_alloc_item(AMI_CTX_ID_NONE, ML_SEPARATOR, 0, NULL, NULL); + ami_ctxmenu_alloc_item(AMI_CTX_ID_NONE, ML_SEPARATOR, NULL, NULL, NULL); - ami_ctxmenu_alloc_item(AMI_CTX_ID_SELCOPY, "CopyNS", 'C', "TBImages:list_copy", + ami_ctxmenu_alloc_item(AMI_CTX_ID_SELCOPY, "CopyNS", "C", "TBImages:list_copy", ami_ctxmenu_item_selcopy); - ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENTAB, "LinkNewTab", 0, "TBImages:list_tab", + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENTAB, "LinkNewTab", NULL, "TBImages:list_tab", ami_ctxmenu_item_urlopentab); - ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENWIN, "LinkNewWin", 0, "TBImages:list_app", + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENWIN, "LinkNewWin", NULL, "TBImages:list_app", ami_ctxmenu_item_urlopenwin); - ami_ctxmenu_alloc_item(AMI_CTX_ID_URLDOWNLOAD, "LinkDload", 0, "TBImages:list_save", + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLDOWNLOAD, "LinkDload", NULL, "TBImages:list_save", ami_ctxmenu_item_urldownload); - ami_ctxmenu_alloc_item(AMI_CTX_ID_URLCOPY, "CopyURL", 0, "TBImages:list_copy", + ami_ctxmenu_alloc_item(AMI_CTX_ID_URLCOPY, "CopyURL", NULL, "TBImages:list_copy", ami_ctxmenu_item_urlcopy); - ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJSHOW, "ObjShow", 0, "TBImages:list_preview", + ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJSHOW, "ObjShow", NULL, "TBImages:list_preview", ami_ctxmenu_item_objshow); - ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCOPY, "CopyClip", 0, "TBImages:list_copy", + ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCOPY, "CopyClip", NULL, "TBImages:list_copy", ami_ctxmenu_item_objcopy); - ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCMD, "ExternalApp", 0, "TBImages:list_tool", + ami_ctxmenu_alloc_item(AMI_CTX_ID_OBJCMD, "ExternalApp", NULL, "TBImages:list_tool", ami_ctxmenu_item_objcmd); - ami_ctxmenu_alloc_item(AMI_CTX_ID_FRAMESHOW, "FrameOnly", 0, "TBImages:list_preview", + ami_ctxmenu_alloc_item(AMI_CTX_ID_FRAMESHOW, "FrameOnly", NULL, "TBImages:list_preview", ami_ctxmenu_item_frameshow); + ami_ctxmenu_alloc_item(AMI_CTX_ID_TABNEW, "NewTab", "T", "TBImages:list_add", + ami_ctxmenu_item_tabnew); } /******************************** @@ -504,6 +527,31 @@ struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin } +/************************** + * ClickTab context menus * + **************************/ + +/** Exported interface documented in ctxmenu.h **/ +struct Menu *ami_ctxmenu_clicktab_create(struct gui_window_2 *gwin) +{ + Object *root_menu; + + if(gwin->clicktab_ctxmenu != NULL) return (struct Menu *)gwin->clicktab_ctxmenu; + + gwin->clicktab_ctxmenu = MStrip, + MA_Type, T_ROOT, + MA_AddChild, root_menu = MStrip, + MA_Type, T_MENU, + MA_Label, NULL, + MA_EmbeddedKey, FALSE, + MEnd, + MEnd; + + ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_TABNEW, gwin); + + return (struct Menu *)gwin->clicktab_ctxmenu; +} + #endif diff --git a/amiga/ctxmenu.h b/amiga/ctxmenu.h index 15009d3b0..79c0dc793 100644 --- a/amiga/ctxmenu.h +++ b/amiga/ctxmenu.h @@ -62,7 +62,7 @@ void ami_ctxmenu_release_hook(struct Hook *hook); * Create history context menu * The first time this is run it will create an empty menu, * Subsequent runs will (re-)populate with the history. - * This is to allow the pointer to be obtained before the browser_winodw is opened. + * This is to allow the pointer to be obtained before the browser_window is opened. * * \param direction AMI_CTXMENU_HISTORY_(BACK|FORWARD) * \param gwin struct gui_window_2 * @@ -71,6 +71,15 @@ void ami_ctxmenu_release_hook(struct Hook *hook); */ struct Menu *ami_ctxmenu_history_create(int direction, struct gui_window_2 *gwin); +/** + * Create ClickTab context menu + * + * \param gwin struct gui_window_2 * + * \returns pointer to menu (for convenience, is also stored in gwin structure) + * The returned pointer MUST be disposed of with DisposeObject before program exit. + */ +struct Menu *ami_ctxmenu_clicktab_create(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 3a09a1e1b..d65f2254a 100644 --- a/amiga/gui.c +++ b/amiga/gui.c @@ -3226,6 +3226,7 @@ static void ami_toggletabbar(struct gui_window_2 *gwin, bool show) GA_ID, GID_TABS, GA_RelVerify, TRUE, GA_Underscore, 13, // disable kb shortcuts + GA_ContextMenu, ami_ctxmenu_clicktab_create(gwin), CLICKTAB_Labels, &gwin->tab_list, CLICKTAB_LabelTruncate, TRUE, CLICKTAB_CloseImage, gwin->objects[GID_CLOSETAB_BM], @@ -3777,6 +3778,7 @@ gui_window_create(struct browser_window *bw, 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; + g->shared->clicktab_ctxmenu = NULL; if(nsoption_bool(window_simple_refresh) == true) { refresh_mode = WA_SimpleRefresh; @@ -4342,8 +4344,7 @@ static void gui_window_destroy(struct gui_window *g) cur_gw = NULL; - if(g->shared->tabs > 1) - { + if(g->shared->tabs > 1) { SetGadgetAttrs((struct Gadget *)g->shared->objects[GID_TABS],g->shared->win,NULL, CLICKTAB_Labels,~0, TAG_DONE); @@ -4399,6 +4400,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); + /* This appears to be disposed along with the ClickTab object + if(g->shared->clicktab_ctxmenu) DisposeObject((Object *)g->shared->clicktab_ctxmenu); */ 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); @@ -4414,8 +4417,7 @@ static void gui_window_destroy(struct gui_window *g) free(g->shared->helphints[gid]); DelObject(g->shared->node); - if(g->tab_node) - { + if(g->tab_node) { Remove(g->tab_node); FreeClickTabNode(g->tab_node); } diff --git a/amiga/gui.h b/amiga/gui.h index d23f9c919..536071c77 100644 --- a/amiga/gui.h +++ b/amiga/gui.h @@ -134,6 +134,7 @@ struct gui_window_2 { struct Hook throbber_hook; struct Hook *ctxmenu_hook; Object *history_ctxmenu[2]; + Object *clicktab_ctxmenu; gui_drag_type drag_op; struct IBox *ptr_lock; struct AppWindow *appwin;