diff options
Diffstat (limited to 'frontends/atari/toolbar.c')
-rw-r--r-- | frontends/atari/toolbar.c | 1041 |
1 files changed, 1041 insertions, 0 deletions
diff --git a/frontends/atari/toolbar.c b/frontends/atari/toolbar.c new file mode 100644 index 000000000..f630332da --- /dev/null +++ b/frontends/atari/toolbar.c @@ -0,0 +1,1041 @@ +/* + * Copyright 2012 Ole Loots <ole@monochrom.net> + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <limits.h> +#include <unistd.h> +#include <string.h> +#include <stdlib.h> +#include <stdbool.h> +#include <assert.h> +#include <math.h> + +#include "utils/log.h" +#include "utils/nsoption.h" +#include "utils/nsurl.h" +#include "utils/utf8.h" +#include "desktop/browser_history.h" +#include "desktop/browser.h" +#include "desktop/mouse.h" +#include "desktop/plot_style.h" +#include "desktop/plotters.h" +#include "desktop/tree.h" +#include "desktop/hotlist.h" +#include "desktop/textarea.h" +#include "desktop/textinput.h" +#include "content/hlcache.h" + +#include "atari/clipboard.h" +#include "atari/gui.h" +#include "atari/search.h" +#include "atari/toolbar.h" +#include "atari/rootwin.h" +#include "atari/clipboard.h" +#include "atari/misc.h" +#include "atari/plot/plot.h" +#include "cflib.h" +#include "atari/res/netsurf.rsh" +#include "atari/encoding.h" + + +#define TB_BUTTON_WIDTH 32 +#define THROBBER_WIDTH 32 +#define THROBBER_MIN_INDEX 1 +#define THROBBER_MAX_INDEX 12 +#define THROBBER_INACTIVE_INDEX 13 + +enum e_toolbar_button_states { + button_on = 0, + button_off = 1 +}; +#define TOOLBAR_BUTTON_NUM_STATES 2 + +struct s_toolbar; + +struct s_tb_button { + short rsc_id; + void (*cb_click)(struct s_toolbar *tb); + hlcache_handle *icon[TOOLBAR_BUTTON_NUM_STATES]; + struct s_toolbar *owner; + enum e_toolbar_button_states state; + short index; + GRECT area; +}; + + +extern char * option_homepage_url; +extern void * h_gem_rsrc; +extern struct gui_window * input_window; +extern long atari_plot_flags; +extern int atari_plot_vdi_handle; +extern EVMULT_OUT aes_event_out; + +static OBJECT * aes_toolbar = NULL; +static OBJECT * throbber_form = NULL; +static bool init = false; +static int area_navigation_height = 0; +static int area_search_height = 0; +static int area_full_height = 0; +static float toolbar_url_scale = 1.0; + +static plot_font_style_t font_style_url = { + .family = PLOT_FONT_FAMILY_SANS_SERIF, + .size = 14*FONT_SIZE_SCALE, + .weight = 400, + .flags = FONTF_NONE, + .background = 0xffffff, + .foreground = 0x0 +}; + + +/* prototypes & order for button widgets: */ + +static struct s_tb_button tb_buttons[] = { + { + TOOLBAR_BT_BACK, + toolbar_back_click, + {0,0}, + 0, 0, 0, {0,0,0,0} + }, + { + TOOLBAR_BT_HOME, + toolbar_home_click, + {0,0}, + 0, 0, 0, {0,0,0,0} + }, + { + TOOLBAR_BT_FORWARD, + toolbar_forward_click, + {0,0}, + 0, 0, 0, {0,0,0,0} + }, + { + TOOLBAR_BT_STOP, + toolbar_stop_click, + {0,0}, + 0, 0, 0, {0,0,0,0} + }, + { + TOOLBAR_BT_RELOAD, + toolbar_reload_click, + {0,0}, + 0, 0, 0, {0,0,0,0} + }, + { 0, 0, {0,0}, 0, -1, 0, {0,0,0,0}} +}; + +struct s_toolbar_style { + int font_height_pt; +}; + +static struct s_toolbar_style toolbar_styles[] = { + /* small (18 px height) */ + {9}, + /* medium (default - 26 px height) */ + {14}, + /* large ( 49 px height ) */ + {18}, + /* custom style: */ + {18} +}; + +static const struct redraw_context toolbar_rdrw_ctx = { + .interactive = true, + .background_images = true, + .plot = &atari_plotters +}; + +static void tb_txt_request_redraw(void *data, int x, int y, int w, int h ); + +/** + * Find a button for a specific resource ID + */ +static struct s_tb_button *find_button(struct s_toolbar *tb, int rsc_id) +{ + int i = 0; + while (i < tb->btcnt) { + if (tb->buttons[i].rsc_id == rsc_id) { + return(&tb->buttons[i]); + } + i++; + } + return(NULL); +} + +/** + * Callback for textarea redraw + */ +static void tb_txt_request_redraw(void *data, int x, int y, int w, int h) +{ + + GRECT area; + struct s_toolbar * tb = (struct s_toolbar *)data; + + if (tb->attached == false) { + return; + } + + toolbar_get_grect(tb, TOOLBAR_AREA_URL, &area); + area.g_x += x; + area.g_y += y; + area.g_w = w; + area.g_h = h; + /* dbg_grect("tb_txt_request_redraw", &area); */ + window_schedule_redraw_grect(tb->owner, &area); + return; +} + +static void tb_txt_callback(void *data, struct textarea_msg *msg) +{ + switch (msg->type) { + + case TEXTAREA_MSG_DRAG_REPORT: + break; + + case TEXTAREA_MSG_REDRAW_REQUEST: + tb_txt_request_redraw(data, + msg->data.redraw.x0, msg->data.redraw.y0, + msg->data.redraw.x1 - msg->data.redraw.x0, + msg->data.redraw.y1 - msg->data.redraw.y0); + break; + + default: + break; + } +} + +static struct s_tb_button *button_init(struct s_toolbar *tb, OBJECT * tree, int index, + struct s_tb_button * instance) +{ + *instance = tb_buttons[index]; + instance->owner = tb; + + return(instance); +} + + +static short __CDECL toolbar_url_userdraw(PARMBLK *parmblock) +{ + return(0); +} + +void toolbar_init( void ) +{ + static USERBLK userblk; + + aes_toolbar = gemtk_obj_get_tree(TOOLBAR); + throbber_form = gemtk_obj_get_tree(THROBBER); + + userblk.ub_code = toolbar_url_userdraw; + userblk.ub_parm = (long) aes_toolbar[TOOLBAR_AREA_URL].ob_spec.userblk; + aes_toolbar[TOOLBAR_AREA_URL].ob_spec.userblk = &userblk; + + aes_toolbar[TOOLBAR_CB_SHOWALL].ob_state &= ~OS_SELECTED; + aes_toolbar[TOOLBAR_CB_CASESENSE].ob_state &= ~OS_SELECTED; + + /* init default values: */ + gemtk_obj_set_str_safe(aes_toolbar, TOOLBAR_TB_SRCH, (char*)""); + + area_full_height = aes_toolbar->ob_height; + area_search_height = aes_toolbar[TOOLBAR_AREA_SEARCH].ob_height; + area_navigation_height = aes_toolbar[TOOLBAR_AREA_NAVIGATION].ob_height; + + init = true; +} + + +void toolbar_exit(void) +{ + +} + + +struct s_toolbar *toolbar_create(struct s_gui_win_root *owner) +{ + int i; + struct s_toolbar *t; + + LOG("owner %p", owner); + + assert(init == true); + + t = calloc(1, sizeof(struct s_toolbar)); + + assert(t); + + /* initialize the toolbar values: */ + t->owner = owner; + t->style = 1; + t->search_visible = false; + t->visible = true; + t->reflow = true; + + /* dublicate the form template: */ + t->form = gemtk_obj_tree_copy(aes_toolbar); + + + /* count buttons and add them as components: */ + i = 0; + while(tb_buttons[i].rsc_id > 0) { + i++; + } + t->btcnt = i; + t->buttons = malloc(t->btcnt * sizeof(struct s_tb_button)); + memset(t->buttons, 0, t->btcnt * sizeof(struct s_tb_button)); + for (i=0; i < t->btcnt; i++) { + button_init(t, aes_toolbar, i, &t->buttons[i]); + } + + /* create the url widget: */ + font_style_url.size = + toolbar_styles[t->style].font_height_pt * FONT_SIZE_SCALE; + + textarea_flags ta_flags = TEXTAREA_INTERNAL_CARET; + textarea_setup ta_setup; + ta_setup.width = 300; + ta_setup.height = t->form[TOOLBAR_AREA_URL].ob_height; + ta_setup.pad_top = 0; + ta_setup.pad_right = 4; + ta_setup.pad_bottom = 0; + ta_setup.pad_left = 4; + ta_setup.border_width = 1; + ta_setup.border_col = 0x000000; + ta_setup.selected_text = 0xffffff; + ta_setup.selected_bg = 0x000000; + ta_setup.text = font_style_url; + ta_setup.text.foreground = 0x000000; + ta_setup.text.background = 0xffffff; + t->url.textarea = textarea_create(ta_flags, &ta_setup, + tb_txt_callback, t); + + /* create the throbber widget: */ + t->throbber.index = THROBBER_INACTIVE_INDEX; + t->throbber.max_index = THROBBER_MAX_INDEX; + t->throbber.running = false; + + LOG("created toolbar: %p, root: %p, textarea: %p, throbber: %p", + t, owner, t->url.textarea, &t->throbber); + return( t ); +} + + +void toolbar_destroy(struct s_toolbar *tb) +{ + free(tb->buttons); + free(tb->form); + + textarea_destroy(tb->url.textarea); + + free(tb); +} + +static int toolbar_calculate_height(struct s_toolbar *tb) +{ + int r = 0; + + if (tb->visible == false) { + return(0); + } + + r += area_navigation_height; + + if (tb->search_visible) { + r += area_search_height; + } + + return(r); +} + +static void toolbar_reflow(struct s_toolbar *tb) +{ + int i; + short offx, offy; + + // position toolbar areas: + tb->form->ob_x = tb->area.g_x; + tb->form->ob_y = tb->area.g_y; + tb->form->ob_width = tb->area.g_w; + tb->form->ob_height = toolbar_calculate_height(tb); + + // expand the "main" areas to the current width: + tb->form[TOOLBAR_AREA_NAVIGATION].ob_width = tb->area.g_w; + tb->form[TOOLBAR_AREA_SEARCH].ob_width = tb->area.g_w; + + if (tb->search_visible) { + tb->form[TOOLBAR_AREA_SEARCH].ob_state &= ~OF_HIDETREE; + } else { + tb->form[TOOLBAR_AREA_SEARCH].ob_state |= OF_HIDETREE; + + } + + // align TOOLBAR_AREA_RIGHT IBOX at right edge: + tb->form[TOOLBAR_AREA_RIGHT].ob_x = tb->area.g_w + - tb->form[TOOLBAR_AREA_RIGHT].ob_width; + + // center the URL area: + tb->form[TOOLBAR_AREA_URL].ob_width = tb->area.g_w + - (tb->form[TOOLBAR_AREA_LEFT].ob_width + + tb->form[TOOLBAR_AREA_RIGHT].ob_width); + + // position throbber image above IBOX: + objc_offset(tb->form, TOOLBAR_THROBBER_AREA, &offx, &offy); + throbber_form[tb->throbber.index].ob_x = offx; + throbber_form[tb->throbber.index].ob_y = offy; + + // align the search button: + tb->form[TOOLBAR_SEARCH_ALIGN_RIGHT].ob_x = tb->area.g_w + - tb->form[TOOLBAR_SEARCH_ALIGN_RIGHT].ob_width; + + // set button states: + for (i=0; i < tb->btcnt; i++ ) { + if (tb->buttons[i].state == button_off) { + tb->form[tb->buttons[i].rsc_id].ob_state |= OS_DISABLED; + } else if (tb->buttons[i].state == button_on) { + tb->form[tb->buttons[i].rsc_id].ob_state &= ~OS_DISABLED; + } + } + tb->reflow = false; + // TODO: iterate through all other toolbars and set reflow = true +} + +void toolbar_redraw(struct s_toolbar *tb, GRECT *clip) +{ + GRECT area, area_ro; + + if (tb->attached == false) { + return; + } + + if(tb->reflow == true) + toolbar_reflow(tb); + + //dbg_grect("toolbar redraw clip", clip); + + /* Redraw the AES objects: */ + objc_draw_grect(tb->form,0,8,clip); + objc_draw_grect(&throbber_form[tb->throbber.index], 0, 1, clip); + + toolbar_get_grect(tb, TOOLBAR_AREA_URL, &area_ro); + area = area_ro; + + if (rc_intersect(clip, &area)) { + float old_scale; + + plot_set_dimensions(area_ro.g_x, area_ro.g_y, area_ro.g_w, area_ro.g_h); + struct rect r = { + .x0 = MAX(0,area.g_x - area_ro.g_x), + .y0 = MAX(0,area.g_y - area_ro.g_y), + .x1 = MAX(0,area.g_x - area_ro.g_x) + area.g_w, + .y1 = MAX(0,area.g_y - area_ro.g_y) + area.g_h + }; + //dbg_rect("tb textarea clip: ", &r); + // TODO: let this be handled by an userdef object redraw function: + /* Redraw the url input: */ + old_scale = plot_set_scale(toolbar_url_scale); + textarea_redraw(tb->url.textarea, 0, 0, 0xffffff, 1.0, &r, + &toolbar_rdrw_ctx); + plot_set_scale(old_scale); + } +} + + +void +toolbar_update_buttons(struct s_toolbar *tb, + struct browser_window *bw, + short button) +{ + LOG("tb %p", tb); + + struct s_tb_button * bt; + bool enable = false; + GRECT area; + + assert(bw != NULL); + + if (button == TOOLBAR_BT_BACK || button <= 0 ) { + bt = find_button(tb, TOOLBAR_BT_BACK); + enable = browser_window_back_available(bw); + if (enable) { + bt->state = button_on; + } else { + bt->state = button_off; + } + } + + if (button == TOOLBAR_BT_HOME || button <= 0 ) { + + } + + if (button == TOOLBAR_BT_FORWARD || button <= 0 ) { + bt = find_button(tb, TOOLBAR_BT_FORWARD); + enable = browser_window_forward_available(bw); + if (enable) { + bt->state = button_on; + } else { + bt->state = button_off; + } + } + + if (button == TOOLBAR_BT_RELOAD || button <= 0 ) { + bt = find_button(tb, TOOLBAR_BT_RELOAD); + enable = browser_window_reload_available(bw); + if (enable) { + bt->state = button_on; + } else { + bt->state = button_off; + } + } + + if (button == TOOLBAR_BT_STOP || button <= 0) { + bt = find_button(tb, TOOLBAR_BT_STOP); + enable = browser_window_stop_available(bw); + if (enable) { + bt->state = button_on; + } else { + bt->state = button_off; + } + } + + if (tb->attached) { + if (button > 0) { + toolbar_get_grect(tb, button, &area); + window_schedule_redraw_grect(tb->owner, &area); + } else { + toolbar_get_grect(tb, TOOLBAR_AREA_LEFT, &area); + window_schedule_redraw_grect(tb->owner, &area); + + toolbar_get_grect(tb, TOOLBAR_AREA_RIGHT, &area); + window_schedule_redraw_grect(tb->owner, &area); + } + } +} + +void toolbar_set_width(struct s_toolbar *tb, short w) +{ + GRECT cur; + + toolbar_get_grect(tb, 0, &cur); + + if (w != cur.g_w) { + + tb->area.g_w = w; + + /* reflow now, just for url input calucation: */ + toolbar_reflow(tb); + /* this will request an textarea redraw: */ + textarea_set_dimensions(tb->url.textarea, + tb->form[TOOLBAR_AREA_URL].ob_width, + tb->form[TOOLBAR_AREA_URL].ob_height); + tb->reflow = true; + } +} + +void toolbar_set_origin(struct s_toolbar *tb, short x, short y) +{ + GRECT cur; + + toolbar_get_grect(tb, 0, &cur); + + if (x != cur.g_x || y != cur.g_y) { + tb->area.g_x = x; + tb->area.g_y = y; + tb->reflow = true; + } +} + +void toolbar_set_dimensions(struct s_toolbar *tb, GRECT *area) +{ + if (area->g_w != tb->area.g_w) { + + tb->area = *area; + + /* reflow now, just for url input calucation: */ + toolbar_reflow(tb); + /* this will request an textarea redraw: */ + textarea_set_dimensions(tb->url.textarea, + tb->form[TOOLBAR_AREA_URL].ob_width, + tb->form[TOOLBAR_AREA_URL].ob_height-1); + } + else { + tb->area = *area; + } + /* reflow for next redraw: */ + /* TODO: that's only required because we do not reset others toolbars reflow + state on reflow */ + tb->reflow = true; +} + + +void toolbar_set_url(struct s_toolbar *tb, const char *text) +{ + LOG("tb %p", tb); + + textarea_set_text(tb->url.textarea, text); + + if (tb->attached && tb->visible) { + GRECT area; + toolbar_get_grect(tb, TOOLBAR_AREA_URL, &area); + window_schedule_redraw_grect(tb->owner, &area); + struct gui_window * gw = window_get_active_gui_window(tb->owner); + assert(gw != NULL); + toolbar_update_buttons(tb, gw->browser->bw , 0); + } +} + +void toolbar_set_throbber_state(struct s_toolbar *tb, bool active) +{ + GRECT throbber_area; + + tb->throbber.running = active; + if (active) { + tb->throbber.index = THROBBER_MIN_INDEX; + } else { + tb->throbber.index = THROBBER_INACTIVE_INDEX; + } + + tb->reflow = true; + toolbar_get_grect(tb, TOOLBAR_THROBBER_AREA, &throbber_area); + window_schedule_redraw_grect(tb->owner, &throbber_area); +} + +void toolbar_set_visible(struct s_toolbar *tb, short area, bool visible) +{ + if (area == 0) { + if ((visible == false) && (tb->visible == true)) { + tb->visible = false; + tb->reflow = true; + } else if((visible == true) && (tb->visible == false)) { + tb->visible = false; + tb->reflow = true; + } + } else if (area == TOOLBAR_AREA_SEARCH) { + tb->search_visible = visible; + tb->reflow = true; + OBJECT *frm = toolbar_get_form(tb); + if(visible == false){ + frm[TOOLBAR_AREA_SEARCH].ob_flags |= OF_HIDETREE; + } else { + frm[TOOLBAR_AREA_SEARCH].ob_flags &= ~OF_HIDETREE; + } + } +} + +void toolbar_set_reflow(struct s_toolbar *tb, bool do_reflow) +{ + tb->reflow = do_reflow; +} + +void toolbar_set_attached(struct s_toolbar *tb, bool attached) +{ + tb->attached = attached; + +} + +void toolbar_throbber_progress(struct s_toolbar *tb) +{ + GRECT throbber_area; + + assert(tb->throbber.running == true); + + if(tb->throbber.running == false) + return; + + tb->throbber.index++; + if (tb->throbber.index > THROBBER_MAX_INDEX) { + tb->throbber.index = THROBBER_MIN_INDEX; + } + + tb->reflow = true; + toolbar_get_grect(tb, TOOLBAR_THROBBER_AREA, &throbber_area); + window_schedule_redraw_grect(tb->owner, &throbber_area); +} + +bool toolbar_text_input(struct s_toolbar *tb, char *text) +{ + bool handled = true; + + LOG("tb %p", tb); + + return(handled); +} + +bool toolbar_key_input(struct s_toolbar *tb, short nkc) +{ + + assert(tb!=NULL); + bool ret = false; + struct gui_window *gw = window_get_active_gui_window(tb->owner); + + assert( gw != NULL ); + + long ucs4; + long ik = nkc_to_input_key(nkc, &ucs4); + + if (ik == 0) { + if ((nkc&0xFF) >= 9) { + ret = textarea_keypress(tb->url.textarea, ucs4); + } + + } else if (ik == NS_KEY_CR || ik == NS_KEY_NL) { + nsurl *url; + char tmp_url[PATH_MAX]; + if ( textarea_get_text( tb->url.textarea, tmp_url, PATH_MAX) > 0 ) { + window_set_focus(tb->owner, BROWSER, gw->browser); + if (nsurl_create((const char*)&tmp_url, &url) != NSERROR_OK) { + atari_warn_user("NoMemory", 0); + } else { + browser_window_navigate(gw->browser->bw, url, NULL, + BW_NAVIGATE_HISTORY, + NULL, NULL, NULL); + nsurl_unref(url); + } + + ret = true; + } + + } else if (ik == NS_KEY_COPY_SELECTION) { + // copy whole text + char * text; + int len; + len = textarea_get_text( tb->url.textarea, NULL, 0 ); + text = malloc( len+1 ); + if (text){ + textarea_get_text( tb->url.textarea, text, len+1 ); + scrap_txt_write(text); + free( text ); + } + + } else if ( ik == NS_KEY_PASTE) { + char * clip = scrap_txt_read(); + if ( clip != NULL ){ + int clip_length = strlen( clip ); + if ( clip_length > 0 ) { + char *utf8; + nserror res; + /* Clipboard is in local encoding so + * convert to UTF8 */ + res = utf8_from_local_encoding( clip, clip_length, &utf8 ); + if ( res == NSERROR_OK ) { + toolbar_set_url(tb, utf8); + free(utf8); + ret = true; + } + } + free( clip ); + } + + } else if (ik == NS_KEY_ESCAPE) { + textarea_keypress( tb->url.textarea, NS_KEY_SELECT_ALL ); + textarea_keypress( tb->url.textarea, NS_KEY_DELETE_LEFT ); + + } else { + ret = textarea_keypress( tb->url.textarea, ik ); + + } + + return( ret ); +} + + +void toolbar_mouse_input(struct s_toolbar *tb, short obj, short button) +{ + GRECT work; + short mx, my, mb, kstat; + struct gui_window * gw; + + LOG("tb %p", tb); + + + if (obj==TOOLBAR_AREA_URL) { + graf_mkstate(&mx, &my, &mb, &kstat); + toolbar_get_grect(tb, TOOLBAR_AREA_URL, &work); + mx -= work.g_x; + my -= work.g_y; + + /* TODO: reset mouse state of browser window? */ + /* select whole text when newly focused, otherwise set caret to + end of text */ + if (!window_url_widget_has_focus(tb->owner)) { + window_set_focus(tb->owner, URL_WIDGET, (void*)&tb->url); + + } else if (mb & 1) { + /* url widget has focus and mouse button is still pressed... */ + + textarea_mouse_action(tb->url.textarea, BROWSER_MOUSE_DRAG_1, + mx, my ); + short prev_x = mx; + short prev_y = my; + do { + if (abs(prev_x-mx) > 5 || abs(prev_y-my) > 5) { + textarea_mouse_action( tb->url.textarea, + BROWSER_MOUSE_HOLDING_1, mx, my ); + prev_x = mx; + prev_y = my; + window_schedule_redraw_grect(tb->owner, &work); + window_process_redraws(tb->owner); + } + graf_mkstate( &mx, &my, &mb, &kstat ); + mx = mx - (work.g_x); + my = my - (work.g_y); + } while (mb & 1); + + textarea_mouse_action( tb->url.textarea, BROWSER_MOUSE_HOVER, mx, + my); + + } else if (button & 2) { + // TODO: open a context popup + + } else { + /* when execution reaches here, mouse input is a click or dclick */ + /* TODO: recognize click + shitoolbar_update_buttonsft key */ + if (aes_event_out.emo_mclicks == 2 ) { + textarea_mouse_action( tb->url.textarea, + BROWSER_MOUSE_DOUBLE_CLICK | BROWSER_MOUSE_CLICK_1, mx, + my); + toolbar_get_grect(tb, TOOLBAR_AREA_URL, &work); + window_schedule_redraw_grect(tb->owner, &work); + } else { + textarea_mouse_action(tb->url.textarea, + BROWSER_MOUSE_PRESS_1, mx, my ); + } + } + + } else if(obj==TOOLBAR_TB_SRCH) { + window_set_focus(tb->owner, SEARCH_INPUT, NULL); + + } else if (obj==TOOLBAR_BT_SEARCH_FWD) { + gw = tb->owner->active_gui_window; + assert(gw->search); + nsatari_search_perform(gw->search, tb->form, SEARCH_FLAG_FORWARDS); + + } else if (obj==TOOLBAR_BT_SEARCH_BACK) { + gw = tb->owner->active_gui_window; + assert(gw->search); + nsatari_search_perform(gw->search, tb->form, 0); + + } else if (obj==TOOLBAR_BT_CLOSE_SEARCH) { + tb->form[TOOLBAR_BT_CLOSE_SEARCH].ob_state &= ~OS_SELECTED; + window_close_search(tb->owner); + } else { + struct s_tb_button *bt = find_button(tb, obj); + if (bt != NULL && bt->state != button_off) { + bt->cb_click(tb); + struct gui_window * gw = window_get_active_gui_window(tb->owner); + toolbar_update_buttons(tb, gw->browser->bw, 0); + } + } +} + + +/** + * Receive a specific region of the toolbar. + * @param tb - the toolbar pointer + * @param which - the area to retrieve: 0 to receive the workarea, + all other values must be + an resource ID of the TOOLBAR tree. + * @param dst - GRECT pointer receiving the area. + */ + +void toolbar_get_grect(struct s_toolbar *tb, short which, GRECT *dst) +{ +#define LAST_TOOLBAR_AREA TOOLBAR_AREA_SEARCH + + if (tb->reflow == true) { + toolbar_reflow(tb); + } + + objc_offset(tb->form, which, &dst->g_x, &dst->g_y); + + dst->g_w = tb->form[which].ob_width; + dst->g_h = tb->form[which].ob_height; + //tb->form[which].ob_height; + + //printf("Toolbar get grect (%d): ", which); + //dbg_grect("", dst); + +#undef LAST_TOOLBAR_AREA +} + + +struct textarea *toolbar_get_textarea(struct s_toolbar *tb, + enum toolbar_textarea which) +{ + return(tb->url.textarea); +} + +char *toolbar_get_url(struct s_toolbar *tb) +{ + char * c_url = NULL; + int c_url_len = 0; + + c_url_len = textarea_get_text(tb->url.textarea, NULL, 0); + + if (c_url_len > -1) { + c_url = malloc(c_url_len+1); + textarea_get_text(tb->url.textarea, c_url, c_url_len+1); + } + + return(c_url); +} + +nsurl * toolbar_get_nsurl(struct s_toolbar * tb) +{ + nsurl * ns_url = NULL; + char * c_url; + + c_url = toolbar_get_url(tb); + if (c_url) { + nsurl_create(c_url, &ns_url); + } + + return(ns_url); +} + + +OBJECT *toolbar_get_form(struct s_toolbar *tb) +{ + return(tb->form); +} + + +/* public event handler */ +void toolbar_back_click(struct s_toolbar *tb) +{ + struct browser_window * bw; + struct gui_window * gw; + + gw = window_get_active_gui_window(tb->owner); + assert(gw != NULL); + bw = gw->browser->bw; + assert(bw != NULL); + + if( browser_window_back_available(bw) ) { + browser_window_history_back(bw, false); + } +} + +void toolbar_reload_click(struct s_toolbar *tb) +{ + struct browser_window * bw; + struct gui_window * gw; + + gw = window_get_active_gui_window(tb->owner); + assert(gw != NULL); + bw = gw->browser->bw; + assert(bw != NULL); + + browser_window_reload(bw, true); +} + +void toolbar_forward_click(struct s_toolbar *tb) +{ + struct browser_window * bw; + struct gui_window * gw; + + gw = window_get_active_gui_window(tb->owner); + assert(gw != NULL); + bw = gw->browser->bw; + assert(bw != NULL); + + if (browser_window_forward_available(bw)) { + browser_window_history_forward(bw, false); + } +} + +void toolbar_home_click(struct s_toolbar *tb) +{ + struct browser_window * bw; + struct gui_window * gw; + nsurl *url; + char * use_url = NULL; + + gw = window_get_active_gui_window(tb->owner); + assert(gw != NULL); + bw = gw->browser->bw; + assert(bw != NULL); + + use_url = nsoption_charp(homepage_url); + if (use_url == NULL || strlen(use_url) == 0){ + use_url = (char*)"about:welcome"; + } + + if (nsurl_create(use_url, &url) != NSERROR_OK) { + atari_warn_user("NoMemory", 0); + } else { + browser_window_navigate(bw, + url, + NULL, + BW_NAVIGATE_HISTORY, + NULL, + NULL, + NULL); + nsurl_unref(url); + } +} + + +void toolbar_stop_click(struct s_toolbar *tb) +{ + struct browser_window * bw; + struct gui_window * gw; + + gw = window_get_active_gui_window(tb->owner); + + assert(gw != NULL); + + bw = gw->browser->bw; + + assert(bw != NULL); + + browser_window_stop(bw); +} + +void toolbar_favorite_click(struct s_toolbar *tb) +{ + nsurl * ns_url = NULL; + char * c_url; + int c_url_len = 0; + + c_url = toolbar_get_url(tb); + c_url_len = strlen(c_url); + + nsurl_create(c_url, &ns_url); + + if (hotlist_has_url(ns_url)) { + char msg[c_url_len+100]; + snprintf(msg, c_url_len+100, "Really delete from favorites: \"%s\"", + c_url); + if (gemtk_msg_box_show(GEMTK_MSG_BOX_CONFIRM, msg)) { + hotlist_remove_url(ns_url); + } + + } else { + hotlist_add_url(ns_url); + + } + + nsurl_unref(ns_url); + free(c_url); +} + +void toolbar_crypto_click(struct s_toolbar *tb) +{ + +} |