Add a couple of context menu items for links for testing.

This commit is contained in:
Chris Young 2015-09-03 19:57:04 +01:00
parent 944248ce32
commit cdaae7b30e
4 changed files with 161 additions and 41 deletions

View File

@ -23,29 +23,43 @@
#ifdef __amigaos4__ #ifdef __amigaos4__
#include <string.h> #include <string.h>
#include <proto/exec.h>
#include <proto/intuition.h> #include <proto/intuition.h>
#include <classes/window.h>
#include <proto/bitmap.h>
#include <images/bitmap.h> #include <images/bitmap.h>
#include <proto/window.h>
#include <classes/window.h>
#include <intuition/menuclass.h> #include <intuition/menuclass.h>
#include <reaction/reaction_macros.h> #include <reaction/reaction_macros.h>
#include "amiga/ctxmenu.h" #include "amiga/ctxmenu.h"
#include "amiga/gui.h" #include "amiga/gui.h"
#include "amiga/libs.h" #include "amiga/libs.h"
#include "amiga/theme.h"
#include "amiga/utf8.h"
#include "desktop/browser.h"
#include "desktop/mouse.h"
#include "utils/log.h" #include "utils/log.h"
#include "utils/messages.h"
#include "utils/nsoption.h"
enum { enum {
AMI_CTX_ID_TEST = 1, AMI_CTX_ID_TEST = 1,
AMI_CTX_ID_URLOPEN,
AMI_CTX_ID_URLOPENWIN,
AMI_CTX_ID_URLOPENTAB,
AMI_CTX_ID_MAX AMI_CTX_ID_MAX
}; };
static Object *ctxmenu_obj = NULL; static Object *ctxmenu_obj = NULL;
static struct Hook ctxmenu_hook;
static struct Hook ctxmenu_item_hook[AMI_CTX_ID_MAX]; static struct Hook ctxmenu_item_hook[AMI_CTX_ID_MAX];
static char *ctxmenu_item_label[AMI_CTX_ID_MAX]; static char *ctxmenu_item_label[AMI_CTX_ID_MAX];
static char *ctxmenu_item_image[AMI_CTX_ID_MAX]; static Object *ctxmenu_item_image[AMI_CTX_ID_MAX];
/** Menu functions - called automatically by RA_HandleInput **/ /** Menu functions - called automatically by RA_HandleInput **/
HOOKF(void, ami_ctxmenu_item_test, APTR, window, struct IntuiMessage *) HOOKF(void, ami_ctxmenu_item_test, APTR, window, struct IntuiMessage *)
@ -53,57 +67,143 @@ HOOKF(void, ami_ctxmenu_item_test, APTR, window, struct IntuiMessage *)
printf("testing\n"); printf("testing\n");
} }
/** Hook function called by Intuition, creates context menu structure **/ HOOKF(void, ami_ctxmenu_item_urlopentab, APTR, window, struct IntuiMessage *)
static uint32 ctxmenu_hook_func(struct Hook *hook, struct Window *window, struct ContextMenuMsg *msg)
{ {
if(msg->State != CM_QUERY) return 0; struct browser_window *bw;
nsurl *url = (nsurl *)hook->h_Data;
struct gui_window_2 *gwin;
ctxmenu_item_hook[AMI_CTX_ID_TEST].h_Entry = (void *)ami_ctxmenu_item_test; GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
ctxmenu_item_hook[AMI_CTX_ID_TEST].h_Data = 0; nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY | BW_CREATE_TAB,
url,
browser_window_get_url(gwin->gw->bw),
gwin->gw->bw,
&bw);
if (error != NSERROR_OK)
warn_user(messages_get_errorcode(error), 0);
}
HOOKF(void, ami_ctxmenu_item_urlopenwin, APTR, window, struct IntuiMessage *)
{
struct browser_window *bw;
nsurl *url = (nsurl *)hook->h_Data;
struct gui_window_2 *gwin;
GetAttr(WINDOW_UserData, (Object *)window, (ULONG *)&gwin);
nserror error = browser_window_create(BW_CREATE_CLONE | BW_CREATE_HISTORY,
url,
browser_window_get_url(gwin->gw->bw),
gwin->gw->bw,
&bw);
if (error != NSERROR_OK)
warn_user(messages_get_errorcode(error), 0);
}
/** Add an initialised item to a context menu **/
static void ami_ctxmenu_add_item(Object *root_menu, int id, APTR data)
{
ctxmenu_item_hook[id].h_Data = data;
IDoMethod(root_menu, OM_ADDMEMBER, MStrip,
MA_Type, T_ITEM,
MA_Label, ctxmenu_item_label[id],
MA_ID, id,
MA_Image, ctxmenu_item_image[id],
MA_UserData, &ctxmenu_item_hook[id],
MEnd);
}
/** Hook function called by Intuition, creates context menu structure **/
static uint32 ami_ctxmenu_hook_func(struct Hook *hook, struct Window *window, struct ContextMenuMsg *msg)
{
Object *root_menu;
bool ctxmenu_has_content = false;
struct gui_window_2 *gwin = hook->h_Data;
struct hlcache_handle *cc = browser_window_get_content(gwin->gw->bw);
struct browser_window_features ccdata;
int mx = window->MouseX;
int my = window->MouseY;
int x, y;
if(msg->State != CM_QUERY) return 0;
if(nsoption_bool(kiosk_mode) == true) return 0;
// check window is active
if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj); if(ctxmenu_obj != NULL) DisposeObject(ctxmenu_obj);
ctxmenu_obj = MStrip, ctxmenu_obj = MStrip,
MA_Type, T_ROOT, MA_Type, T_ROOT,
MA_AddChild, MStrip, MA_AddChild, root_menu = MStrip,
MA_Type, T_MENU, MA_Type, T_MENU,
MA_Label, NULL, //"NetSurf", MA_Label, NULL, //"NetSurf",
MA_AddChild, MStrip, MA_EmbeddedKey, FALSE,
MA_Type, T_ITEM, MA_FreeImage, FALSE,
MA_Label, ctxmenu_item_label[AMI_CTX_ID_TEST],
MA_ID, AMI_CTX_ID_TEST,
MA_Image, BitMapObj,
IA_Scalable, TRUE,
BITMAP_SourceFile, ctxmenu_item_image[AMI_CTX_ID_TEST],
BITMAP_Screen, scrn,
BITMAP_Masking, TRUE,
BITMAP_Width, 16,
BITMAP_Height, 16,
BitMapEnd,
MA_UserData, &ctxmenu_item_hook[AMI_CTX_ID_TEST],
MEnd,
MEnd, MEnd,
MEnd; MEnd;
msg->Menu = ctxmenu_obj; if(ami_mouse_to_ns_coords(gwin, &x, &y, mx, my) == false) {
/* Outside browser render area */
return 0;
}
browser_window_get_features(gwin->gw->bw, x, y, &ccdata);
if(ccdata.link) {
ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENTAB, ccdata.link);
ami_ctxmenu_add_item(root_menu, AMI_CTX_ID_URLOPENWIN, ccdata.link);
ctxmenu_has_content = true;
}
if(ctxmenu_has_content == true) {
msg->Menu = ctxmenu_obj;
ami_set_pointer(gwin, GUI_POINTER_DEFAULT, false);
}
return 0; return 0;
} }
/** Exported interface documented in ctxmenu.h **/ /** Initial menu item creation **/
struct Hook *ami_ctxmenu_get_hook(void) static void ami_ctxmenu_alloc_item(int id, const char *label, const char *image, void *func)
{ {
return &ctxmenu_hook; 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);
ctxmenu_item_hook[id].h_Entry = func;
ctxmenu_item_hook[id].h_Data = 0;
}
/** Exported interface documented in ctxmenu.h **/
struct Hook *ami_ctxmenu_get_hook(APTR data)
{
return AllocSysObjectTags(ASOT_HOOK,
ASOHOOK_Entry, (HOOKFUNC)ami_ctxmenu_hook_func,
ASOHOOK_Data, data,
TAG_DONE);
}
/** Exported interface documented in ctxmenu.h **/
void ami_ctxmenu_release_hook(struct Hook *hook)
{
FreeSysObject(ASOT_HOOK, hook);
} }
/** Exported interface documented in ctxmenu.h **/ /** Exported interface documented in ctxmenu.h **/
void ami_ctxmenu_init(void) void ami_ctxmenu_init(void)
{ {
ctxmenu_hook.h_Entry = (HOOKFUNC)ctxmenu_hook_func; ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENWIN, "LinkNewWin", "TBImages:list_app", ami_ctxmenu_item_urlopenwin);
ctxmenu_hook.h_Data = 0; ami_ctxmenu_alloc_item(AMI_CTX_ID_URLOPENTAB, "LinkNewTab", "TBImages:list_add", ami_ctxmenu_item_urlopentab);
ctxmenu_item_label[AMI_CTX_ID_TEST] = strdup("test item");
ctxmenu_item_image[AMI_CTX_ID_TEST] = strdup("TBimages:list_info");
} }
/** Exported interface documented in ctxmenu.h **/ /** Exported interface documented in ctxmenu.h **/
@ -111,11 +211,12 @@ void ami_ctxmenu_free(void)
{ {
for(int i = 1; i < AMI_CTX_ID_MAX; i++) { for(int i = 1; i < AMI_CTX_ID_MAX; i++) {
if(ctxmenu_item_label[i] != NULL) { if(ctxmenu_item_label[i] != NULL) {
free(ctxmenu_item_label[i]); ami_utf8_free(ctxmenu_item_label[i]);
ctxmenu_item_label[i] = NULL; ctxmenu_item_label[i] = NULL;
} }
if(ctxmenu_item_image[i] != NULL) { if(ctxmenu_item_image[i] != NULL) {
free(ctxmenu_item_image[i]); DisposeObject(ctxmenu_item_image[i]);
ctxmenu_item_image[i] = NULL; ctxmenu_item_image[i] = NULL;
} }
} }

View File

@ -26,7 +26,8 @@
struct Hook; struct Hook;
/** /**
* Initialise context menus code * Initialise context menus code (allocate label text, etc)
* Must be called *after* NetSurf's screen pointer is obtained.
*/ */
void ami_ctxmenu_init(void); void ami_ctxmenu_init(void);
@ -38,8 +39,20 @@ void ami_ctxmenu_free(void);
/** /**
* Get a Hook for WA_ContextMenuHook * Get a Hook for WA_ContextMenuHook
* *
* \param data ptr for the hook to use (struct gui_window_2 *)
* \returns pointer to a struct Hook * \returns pointer to a struct Hook
*/ */
struct Hook *ami_ctxmenu_get_hook(void); struct Hook *ami_ctxmenu_get_hook(APTR data);
#endif
/**
* Release a Hook for WA_ContextMenuHook
*
* \param hook ptr to hook
*/
void ami_ctxmenu_release_hook(struct Hook *hook);
#else
inline void ami_ctxmenu_init(void) {}
inline void ami_ctxmenu_free(void) {}
inline struct Hook *ami_ctxmenu_get_hook(APTR data) {return NULL;}
inline void ami_ctxmenu_release_hook(struct Hook *hook) {}
#endif

View File

@ -1318,7 +1318,7 @@ static bool ami_spacebox_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
return true; return true;
} }
static bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y, bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
int mouse_x, int mouse_y) int mouse_x, int mouse_y)
{ {
int ns_x, ns_y; int ns_x, ns_y;
@ -3769,6 +3769,8 @@ gui_window_create(struct browser_window *bw,
newprefs_hook.h_Entry = (void *)ami_gui_newprefs_hook; newprefs_hook.h_Entry = (void *)ami_gui_newprefs_hook;
newprefs_hook.h_Data = 0; newprefs_hook.h_Data = 0;
g->shared->ctxmenu_hook = ami_ctxmenu_get_hook(g->shared);
if(nsoption_bool(window_simple_refresh) == true) { if(nsoption_bool(window_simple_refresh) == true) {
refresh_mode = WA_SimpleRefresh; refresh_mode = WA_SimpleRefresh;
@ -3932,7 +3934,7 @@ gui_window_create(struct browser_window *bw,
WA_ReportMouse,TRUE, WA_ReportMouse,TRUE,
refresh_mode, TRUE, refresh_mode, TRUE,
WA_SizeBBottom, TRUE, WA_SizeBBottom, TRUE,
WA_ContextMenuHook, ami_ctxmenu_get_hook(), WA_ContextMenuHook, g->shared->ctxmenu_hook,
WA_IDCMP, IDCMP_MENUPICK | IDCMP_MOUSEMOVE | WA_IDCMP, IDCMP_MENUPICK | IDCMP_MOUSEMOVE |
IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
IDCMP_RAWKEY | idcmp_sizeverify | IDCMP_RAWKEY | idcmp_sizeverify |
@ -4376,7 +4378,6 @@ static void gui_window_destroy(struct gui_window *g)
DisposeObject(g->shared->objects[OID_MAIN]); DisposeObject(g->shared->objects[OID_MAIN]);
ami_gui_appicon_remove(g->shared); ami_gui_appicon_remove(g->shared);
if(g->shared->appwin) RemoveAppWindow(g->shared->appwin); if(g->shared->appwin) RemoveAppWindow(g->shared->appwin);
ami_gui_hotlist_toolbar_free(g->shared, &g->shared->hotlist_toolbar_list); ami_gui_hotlist_toolbar_free(g->shared, &g->shared->hotlist_toolbar_list);
/* These aren't freed by the above. /* These aren't freed by the above.
@ -4390,6 +4391,7 @@ static void gui_window_destroy(struct gui_window *g)
ami_gui_opts_websearch_free(g->shared->web_search_list); ami_gui_opts_websearch_free(g->shared->web_search_list);
if(g->shared->search_bm) DisposeObject(g->shared->search_bm); if(g->shared->search_bm) DisposeObject(g->shared->search_bm);
ami_ctxmenu_release_hook(g->shared->ctxmenu_hook);
ami_free_menulabs(g->shared); ami_free_menulabs(g->shared);
#ifndef __amigaos4__ #ifndef __amigaos4__
ami_menu_free_os3(g->shared); ami_menu_free_os3(g->shared);
@ -5433,7 +5435,6 @@ int main(int argc, char** argv)
ami_amiupdate(); /* set env-vars for AmiUpdate */ ami_amiupdate(); /* set env-vars for AmiUpdate */
ami_init_fonts(); ami_init_fonts();
ami_context_menu_init(); ami_context_menu_init();
ami_ctxmenu_init();
save_complete_init(); save_complete_init();
ami_theme_init(); ami_theme_init();
ami_init_mouse_pointers(); ami_init_mouse_pointers();
@ -5449,6 +5450,8 @@ int main(int argc, char** argv)
gui_init2(argc, argv); gui_init2(argc, argv);
ami_ctxmenu_init(); /* Requires screen pointer */
ami_gui_splash_close(splash_window); ami_gui_splash_close(splash_window);
strlcpy(script, nsoption_charp(arexx_dir), 1024); strlcpy(script, nsoption_charp(arexx_dir), 1024);

3
amiga/gui.h Executable file → Normal file
View File

@ -132,6 +132,7 @@ struct gui_window_2 {
struct DiskObject *dobj; /* iconify appicon */ struct DiskObject *dobj; /* iconify appicon */
struct Hook favicon_hook; struct Hook favicon_hook;
struct Hook throbber_hook; struct Hook throbber_hook;
struct Hook *ctxmenu_hook;
gui_drag_type drag_op; gui_drag_type drag_op;
struct IBox *ptr_lock; struct IBox *ptr_lock;
struct AppWindow *appwin; struct AppWindow *appwin;
@ -174,6 +175,8 @@ void ami_schedule_redraw(struct gui_window_2 *gwin, bool full_redraw);
STRPTR ami_locale_langs(void); STRPTR ami_locale_langs(void);
int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie); int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie);
bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y); bool ami_text_box_at_point(struct gui_window_2 *gwin, ULONG *x, ULONG *y);
bool ami_mouse_to_ns_coords(struct gui_window_2 *gwin, int *x, int *y,
int mouse_x, int mouse_y);
BOOL ami_gadget_hit(Object *obj, int x, int y); BOOL ami_gadget_hit(Object *obj, int x, int y);
void ami_gui_history(struct gui_window_2 *gwin, bool back); void ami_gui_history(struct gui_window_2 *gwin, bool back);
void ami_gui_hotlist_update_all(void); void ami_gui_hotlist_update_all(void);