From c415f9bf989f83c7ced6bb930e3421dab6f4093b Mon Sep 17 00:00:00 2001 From: Ole Loots Date: Sun, 18 Nov 2012 23:22:43 +0100 Subject: Start to remove windom, wip. - Refactored menu event handling. - Load plain GEM resources. - Refactored Event handling --- atari/deskmenu.c | 660 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 660 insertions(+) create mode 100644 atari/deskmenu.c (limited to 'atari/deskmenu.c') diff --git a/atari/deskmenu.c b/atari/deskmenu.c new file mode 100644 index 000000000..d486803f8 --- /dev/null +++ b/atari/deskmenu.c @@ -0,0 +1,660 @@ +#include +#include + +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/url.h" +#include "desktop/browser.h" +#include "desktop/browser_private.h" +#include "desktop/options.h" +#include "desktop/save_complete.h" + +#include "atari/res/netsurf.rsh" +#include "atari/gemtk/gemtk.h" +#include "atari/deskmenu.h" +#include "atari/hotlist.h" +#include "atari/history.h" +#include "atari/toolbar.h" +#include "atari/settings.h" +#include "atari/search.h" +#include "atari/misc.h" +#include "atari/gui.h" +#include "atari/findfile.h" +#include "atari/browser.h" +#include "atari/rootwin.h" + +typedef void __CDECL (*menu_evnt_func)(short item, short title, void * data); + +struct s_accelerator +{ + char ascii; /* either ascii or */ + long keycode; /* normalised keycode is valid */ + short mod; /* shift / ctrl etc */ +}; + +struct s_menu_item_evnt { + short title; /* to which menu this item belongs */ + short rid; /* resource ID */ + menu_evnt_func menu_func; /* click handler */ + struct s_accelerator accel; /* accelerator info */ + char * menustr; +}; + +static void register_menu_str(struct s_menu_item_evnt * mi); +static void __CDECL evnt_menu(WINDOW * win, short buff[8]); + +extern void *h_gem_rsrc; +extern bool html_redraw_debug; +extern struct gui_window * input_window; +extern char options[PATH_MAX]; +extern const char * option_homepage_url; +extern int option_window_width; +extern int option_window_height; +extern int option_window_x; +extern int option_window_y; + +static OBJECT * h_gem_menu; + + +/* Zero based resource tree ids: */ +#define T_ABOUT 0 +#define T_FILE MAINMENU_T_FILE - MAINMENU_T_FILE + 1 +#define T_EDIT MAINMENU_T_EDIT - MAINMENU_T_FILE + 1 +#define T_VIEW MAINMENU_T_VIEW - MAINMENU_T_FILE + 1 +#define T_NAV MAINMENU_T_NAVIGATE - MAINMENU_T_FILE + 1 +#define T_UTIL MAINMENU_T_UTIL - MAINMENU_T_FILE + 1 +#define T_HELP MAINMENU_T_NAVIGATE - MAINMENU_T_FILE + 1 +/* Count of the above defines: */ +#define NUM_MENU_TITLES 7 + + +static void __CDECL menu_about(short item, short title, void *data); +static void __CDECL menu_new_win(short item, short title, void *data); +static void __CDECL menu_open_url(short item, short title, void *data); +static void __CDECL menu_open_file(short item, short title, void *data); +static void __CDECL menu_close_win(short item, short title, void *data); +static void __CDECL menu_save_page(short item, short title, void *data); +static void __CDECL menu_quit(short item, short title, void *data); +static void __CDECL menu_cut(short item, short title, void *data); +static void __CDECL menu_copy(short item, short title, void *data); +static void __CDECL menu_paste(short item, short title, void *data); +static void __CDECL menu_find(short item, short title, void *data); +static void __CDECL menu_choices(short item, short title, void *data); +static void __CDECL menu_stop(short item, short title, void *data); +static void __CDECL menu_reload(short item, short title, void *data); +static void __CDECL menu_toolbars(short item, short title, void *data); +static void __CDECL menu_savewin(short item, short title, void *data); +static void __CDECL menu_debug_render(short item, short title, void *data); +static void __CDECL menu_fg_images(short item, short title, void *data); +static void __CDECL menu_bg_images(short item, short title, void *data); +static void __CDECL menu_back(short item, short title, void *data); +static void __CDECL menu_forward(short item, short title, void *data); +static void __CDECL menu_home(short item, short title, void *data); +static void __CDECL menu_lhistory(short item, short title, void *data); +static void __CDECL menu_ghistory(short item, short title, void *data); +static void __CDECL menu_add_bookmark(short item, short title, void *data); +static void __CDECL menu_bookmarks(short item, short title, void *data); +static void __CDECL menu_vlog(short item, short title, void *data); +static void __CDECL menu_help_content(short item, short title, void *data); + +struct s_menu_item_evnt menu_evnt_tbl[] = +{ + {T_ABOUT,MAINMENU_M_ABOUT, menu_about, {0,0,0}, NULL }, + {T_FILE, MAINMENU_M_NEWWIN, menu_new_win, {0,0,0}, NULL}, + {T_FILE, MAINMENU_M_OPENURL, menu_open_url, {'G',0,K_CTRL}, NULL}, + {T_FILE, MAINMENU_M_OPENFILE, menu_open_file, {'O',0,K_CTRL}, NULL}, + {T_FILE, MAINMENU_M_CLOSEWIN, menu_close_win, {0,0,0}, NULL}, + {T_FILE, MAINMENU_M_SAVEPAGE, menu_save_page, {0,NK_F3,0}, NULL}, + {T_FILE, MAINMENU_M_QUIT, menu_quit, {'Q',0,K_CTRL}, NULL}, + {T_EDIT, MAINMENU_M_CUT, menu_cut, {'X',0,K_CTRL}, NULL}, + {T_EDIT, MAINMENU_M_COPY, menu_copy, {'C',0,K_CTRL}, NULL}, + {T_EDIT, MAINMENU_M_PASTE, menu_paste, {'V',0,K_CTRL}, NULL}, + {T_EDIT, MAINMENU_M_FIND, menu_find, {0,NK_F4,0}, NULL}, + {T_VIEW, MAINMENU_M_RELOAD, menu_reload, {0,NK_F5,0}, NULL}, + {T_VIEW, MAINMENU_M_TOOLBARS, menu_toolbars, {0,NK_F1,K_CTRL}, NULL}, + {T_VIEW, MAINMENU_M_SAVEWIN, menu_savewin, {0,0,0}, NULL}, + {T_VIEW, MAINMENU_M_DEBUG_RENDER, menu_debug_render, {0,0,0}, NULL}, + {T_VIEW, MAINMENU_M_FG_IMAGES, menu_fg_images, {0,0,0}, NULL}, + {T_VIEW, MAINMENU_M_BG_IMAGES, menu_bg_images, {0,0,0}, NULL}, + {T_VIEW, MAINMENU_M_STOP, menu_stop, {0,NK_ESC,K_ALT}, NULL}, + {T_NAV, MAINMENU_M_BACK, menu_back, {0,NK_LEFT,K_ALT}, NULL}, + {T_NAV, MAINMENU_M_FORWARD, menu_forward, {0,NK_RIGHT,K_ALT}, NULL}, + {T_NAV, MAINMENU_M_HOME, menu_home, {0,NK_CLRHOME,0}, NULL}, + {T_UTIL, MAINMENU_M_LHISTORY,menu_lhistory, {0,NK_F7,0}, NULL}, + {T_UTIL, MAINMENU_M_GHISTORY, menu_ghistory, {0,NK_F7,K_CTRL}, NULL}, + {T_UTIL, MAINMENU_M_ADD_BOOKMARK, menu_add_bookmark, {'D',0,K_CTRL}, NULL}, + {T_UTIL, MAINMENU_M_BOOKMARKS, menu_bookmarks, {0,NK_F6,0}, NULL}, + {T_UTIL, MAINMENU_M_CHOICES, menu_choices, {0,0,0}, NULL}, + {T_UTIL, MAINMENU_M_VLOG, menu_vlog, {'V',0,K_ALT}, NULL}, + {T_HELP, MAINMENU_M_HELP_CONTENT, menu_help_content, {0,NK_F1,0}, NULL}, + {-1, -1, NULL,{0,0,0}, NULL } +}; + + +/* + Parse encoded menu key shortcut + + The format is: + + "[" - marks start of the shortcut + "@,^,<" - If the keyshortcut is only valid + with modifier keys, one of these characters must directly + follow the start mark. + Meaning: + @ -> Alternate + ^ -> Control + "#" - keycode or ascii character. + The value is handled as keycode if the character value + is <= 28 ( Atari chracter table ) + or if it is interpreted as function key string. + (strings: F1 - F10) + +*/ +static void register_menu_str( struct s_menu_item_evnt * mi ) +{ + OBJECT *gem_menu = deskmenu_get_obj_tree(); + + assert(gem_menu != NULL); + + char * str = ObjcString( gem_menu, mi->rid, NULL ); + int l = strlen(str); + int i = l; + int x = -1; + struct s_accelerator * accel = &mi->accel; + + while (i > 2) { + if( str[i] == '['){ + x = i; + break; + } + i--; + } + if( x > -1 ){ + mi->menustr = malloc( l+1 ); + strcpy(mi->menustr, str ); + mi->menustr[x]=' '; + x++; + if( str[x] == '@' ){ + accel->mod = K_ALT; + mi->menustr[x] = 0x07; + x++; + } + else if( str[x] == '^' ) { + accel->mod = K_CTRL; + x++; + } + if( str[x] <= 28 ){ + // parse symbol + unsigned short keycode=0; + switch( str[x] ){ + case 0x03: + accel->keycode = NK_RIGHT; + break; + case 0x04: + accel->keycode = NK_LEFT; + break; + case 0x1B: + accel->keycode = NK_ESC; + break; + default: + break; + } + } else { + if(str[x] == 'F' && ( str[x+1] >= '1' && str[x+1] <= '9') ){ + // parse function key + short fkey = atoi( &str[x+1] ); + if( (fkey >= 0) && (fkey <= 10) ){ + accel->keycode = NK_F1 - 1 + fkey; + } + } else { + accel->ascii = str[x]; + } + } + } +} + +static void __CDECL evnt_menu(WINDOW * win, short buff[8]) +{ + int title = buff[3]; + INT16 x,y; + char *str; + struct gui_window * gw = window_list; + int i=0; + + deskmenu_dispatch_item(buff[3], buff[4]); +} + +/* + Menu item event handlers: +*/ + +static void __CDECL menu_about(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + char buf[PATH_MAX]; + strcpy((char*)&buf, "file://"); + strncat((char*)&buf, (char*)"./doc/README.TXT", + PATH_MAX - (strlen("file://")+1) ); + browser_window_create((char*)&buf, 0, 0, true, false); +} + +static void __CDECL menu_new_win(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + browser_window_create(option_homepage_url, 0, 0, true, false); +} + +static void __CDECL menu_open_url(short item, short title, void *data) +{ + struct gui_window * gw; + struct browser_window * bw ; + LOG(("%s", __FUNCTION__)); + + gw = input_window; + if( gw == NULL ) { + bw = browser_window_create("", 0, 0, true, false); + gw = bw->window; + + } + /* Loose focus: */ + window_set_focus( gw, WIDGET_NONE, NULL ); + + /* trigger on-focus event (select all text): */ + window_set_focus( gw, URL_WIDGET, &gw->root->toolbar->url ); + + /* delete selection: */ + tb_url_input( gw, NK_DEL ); +} + +static void __CDECL menu_open_file(short item, short title, void *data) +{ + struct gui_window * gw; + struct browser_window * bw ; + + LOG(("%s", __FUNCTION__)); + + const char * filename = file_select( messages_get("OpenFile"), "" ); + if( filename != NULL ){ + char * url = local_file_to_url( filename ); + if( url ){ + bw = browser_window_create(url, NULL, NULL, true, false); + free( url ); + } + } +} + +static void __CDECL menu_close_win(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window == NULL ) + return; + gui_window_destroy( input_window ); +} + +static void __CDECL menu_save_page(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + static bool init = true; + bool is_folder=false; + const char * path; + + if( !input_window ) + return; + + if( init ){ + init = false; + save_complete_init(); + } + + do { + // TODO: localize string + path = file_select("Select folder", ""); + if (path) + is_folder = is_dir(path); + } while( !is_folder && path != NULL ); + + if( path != NULL ){ + save_complete( input_window->browser->bw->current_content, path, NULL ); + } + +} + +static void __CDECL menu_quit(short item, short title, void *data) +{ + short buff[8]; + memset( &buff, 0, sizeof(short)*8 ); + LOG(("%s", __FUNCTION__)); + netsurf_quit = true; +} + +static void __CDECL menu_cut(short item, short title, void *data) +{ + if( input_window != NULL ) + browser_window_key_press( input_window->browser->bw, KEY_CUT_SELECTION); +} + +static void __CDECL menu_copy(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window != NULL ) + browser_window_key_press( input_window->browser->bw, KEY_COPY_SELECTION); +} + +static void __CDECL menu_paste(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window != NULL ) + browser_window_key_press( input_window->browser->bw, KEY_PASTE); +} + +static void __CDECL menu_find(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window != NULL ) + open_browser_search( input_window ); +} + +static void __CDECL menu_choices(short item, short title, void *data) +{ + static WINDOW * settings_dlg = NULL; + LOG(("%s", __FUNCTION__)); + settings_dlg = open_settings(); +} + +static void __CDECL menu_stop(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window == NULL ) + return; + tb_stop_click( input_window ); + +} + +static void __CDECL menu_reload(short item, short title, void *data) +{ + if( input_window == NULL) + return; + tb_reload_click( input_window ); + LOG(("%s", __FUNCTION__)); +} + +static void __CDECL menu_toolbars(short item, short title, void *data) +{ + static int state = 0; + LOG(("%s", __FUNCTION__)); + if( input_window != null && input_window->root->toolbar != null ){ + state = !state; + tb_hide( input_window, state ); + } +} + +static void __CDECL menu_savewin(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if (input_window && input_window->browser) { + GRECT rect; + wind_get_grect(input_window->root->handle->handle, WF_CURRXYWH, &rect); + option_window_width = rect.g_w; + option_window_height = rect.g_h; + option_window_x = rect.g_x; + option_window_y = rect.g_y; + nsoption_set_int(window_width, rect.g_w); + nsoption_set_int(window_height, rect.g_h); + nsoption_set_int(window_x, rect.g_x); + nsoption_set_int(window_y, rect.g_y); + nsoption_write((const char*)&options); + } + +} + +static void __CDECL menu_debug_render(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + html_redraw_debug = !html_redraw_debug; + if( input_window != NULL ) { + if ( input_window->browser != NULL + && input_window->browser->bw != NULL) { + LGRECT rect; + browser_get_rect( input_window, BR_CONTENT, &rect ); + browser_window_reformat(input_window->browser->bw, false, + rect.g_w, rect.g_h ); + MenuIcheck(NULL, MAINMENU_M_DEBUG_RENDER, + (html_redraw_debug) ? 1 : 0 ); + } + } +} + +static void __CDECL menu_fg_images(short item, short title, void *data) +{ + nsoption_set_bool(foreground_images, !nsoption_bool(foreground_images)); + MenuIcheck( NULL, MAINMENU_M_FG_IMAGES, + (nsoption_bool(foreground_images)) ? 1 : 0); +} + +static void __CDECL menu_bg_images(short item, short title, void *data) +{ + nsoption_set_bool(background_images, !nsoption_bool(background_images)); + MenuIcheck( NULL, MAINMENU_M_BG_IMAGES, + (nsoption_bool(background_images)) ? 1 : 0); +} + +static void __CDECL menu_back(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window == NULL ) + return; + tb_back_click( input_window ); +} + +static void __CDECL menu_forward(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window == NULL ) + return; + tb_forward_click( input_window ); +} + +static void __CDECL menu_home(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window == NULL ) + return; + tb_home_click( input_window ); +} + +static void __CDECL menu_lhistory(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if( input_window == NULL ) + return; +} + +static void __CDECL menu_ghistory(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + global_history_open(); +} + +static void __CDECL menu_add_bookmark(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + if (input_window) { + if( input_window->browser->bw->current_content != NULL ){ + atari_hotlist_add_page( + nsurl_access(hlcache_handle_get_url(input_window->browser->bw->current_content)), + NULL + ); + } + } +} + +static void __CDECL menu_bookmarks(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + hotlist_open(); +} + +static void __CDECL menu_vlog(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); + verbose_log = !verbose_log; + MenuIcheck(NULL, MAINMENU_M_VLOG, (verbose_log) ? 1 : 0 ); +} + +static void __CDECL menu_help_content(short item, short title, void *data) +{ + LOG(("%s", __FUNCTION__)); +} + +/* + Public deskmenu interface: +*/ + + +/** +* Setup & display an desktop menu. +*/ + +void deskmenu_init(void) +{ + int i; + + h_gem_menu = get_tree(MAINMENU); + + // TODO: remove that call somehow... + + /* parse and update menu items: */ + i = 0; + while( menu_evnt_tbl[i].rid != -1 ) { + char * str = ObjcString(h_gem_menu, menu_evnt_tbl[i].rid, NULL ); + register_menu_str( &menu_evnt_tbl[i] ); + /* Update menu string if not null: */ + if( menu_evnt_tbl[i].menustr != NULL ){ + menu_text(h_gem_menu, menu_evnt_tbl[i].rid, + menu_evnt_tbl[i].menustr); + } + i++; + } + deskmenu_update(); + + /* Install menu: */ + menu_bar(h_gem_menu, MENU_INSTALL); + /* Redraw menu: */ + menu_bar(h_gem_menu, MENU_UPDATE); +} + +/** +* Uninstall the desktop menu +*/ +void deskmenu_destroy(void) +{ + int i; + + /* Remove menu from desktop: */ + menu_bar(h_gem_menu, MENU_REMOVE); + + /* Free modified menu titles: */ + i=0; + while(menu_evnt_tbl[i].rid != -1) { + if( menu_evnt_tbl[i].menustr != NULL ) + free(menu_evnt_tbl[i].menustr); + i++; + } +} + +/** +* Return the deskmenu AES OBJECT tree +*/ +OBJECT * deskmenu_get_obj_tree(void) +{ + return(h_gem_menu); +} + +/** +* Handle an menu item event +*/ +int deskmenu_dispatch_item(short title, short item) +{ + int i=0; + int retval = 0; + OBJECT * menu_root = deskmenu_get_obj_tree(); + + menu_tnormal(menu_root, item, 1); + menu_tnormal(menu_root, title, 1); + menu_bar(menu_root, 1); + + // legacy code, is this sensible?: + /* + while( gw ) { + window_set_focus( gw, WIDGET_NONE, NULL ); + gw = gw->next; + } + */ + + + while (menu_evnt_tbl[i].rid != -1) { + if (menu_evnt_tbl[i].rid == item) { + if (menu_evnt_tbl[i].menu_func != NULL) { + menu_evnt_tbl[i].menu_func(item, title, NULL); + } + break; + } + i++; + } + + return(retval); +} + +/** +* Handle an keypress (check for accelerator) +*/ +int deskmenu_dispatch_keypress(unsigned short kcode, unsigned short kstate, + unsigned short nkc) +{ + char sascii; + bool done = 0; + int i = 0; + + sascii = keybd2ascii(kcode, K_LSHIFT); + + /* Iterate through the menu function table: */ + while( menu_evnt_tbl[i].rid != -1 && done == false) { + if( kstate == menu_evnt_tbl[i].accel.mod + && menu_evnt_tbl[i].accel.ascii != 0) { + if( menu_evnt_tbl[i].accel.ascii == sascii) { + deskmenu_dispatch_item(menu_evnt_tbl[i].title, + menu_evnt_tbl[i].rid); + done = true; + break; + } + } else { + /* the accel code hides in the keycode: */ + if( menu_evnt_tbl[i].accel.keycode != 0) { + if( menu_evnt_tbl[i].accel.keycode == (nkc & 0xFF) && + kstate == menu_evnt_tbl[i].accel.mod) { + deskmenu_dispatch_item(menu_evnt_tbl[i].title, + menu_evnt_tbl[i].rid); + done = true; + break; + } + } + } + i++; + } + return((done==true) ? 1 : 0); +} + +/** +* Refresh the desk menu, reflecting netsurf current state. +*/ +void deskmenu_update(void) +{ + OBJECT * gem_menu = deskmenu_get_obj_tree(); + + menu_icheck(gem_menu, MAINMENU_M_DEBUG_RENDER, (html_redraw_debug) ? 1 : 0); + menu_icheck(gem_menu, MAINMENU_M_FG_IMAGES, + (nsoption_bool(foreground_images)) ? 1 : 0); + menu_icheck(gem_menu, MAINMENU_M_BG_IMAGES, + (nsoption_bool(background_images)) ? 1 : 0); +} + -- cgit v1.2.3