diff options
author | James Bursa <james@netsurf-browser.org> | 2004-07-17 23:32:09 +0000 |
---|---|---|
committer | James Bursa <james@netsurf-browser.org> | 2004-07-17 23:32:09 +0000 |
commit | f23fd2a0945b4d178eff39413b68528a951b8775 (patch) | |
tree | 898de8adb998be27471e74e67ca9f9ca6de2adc9 /desktop | |
parent | a9aef8bf603fc68b230543bcfd399cb81e6687be (diff) | |
download | netsurf-f23fd2a0945b4d178eff39413b68528a951b8775.tar.gz netsurf-f23fd2a0945b4d178eff39413b68528a951b8775.tar.bz2 |
[project @ 2004-07-17 23:32:08 by bursa]
Rewrite and simplify mouse click handling.
svn path=/import/netsurf/; revision=1094
Diffstat (limited to 'desktop')
-rw-r--r-- | desktop/browser.c | 592 | ||||
-rw-r--r-- | desktop/browser.h | 33 | ||||
-rw-r--r-- | desktop/gui.h | 24 |
3 files changed, 279 insertions, 370 deletions
diff --git a/desktop/browser.c b/desktop/browser.c index 075df260b..c83fe9c9a 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -49,6 +49,8 @@ static void browser_window_set_status(struct browser_window *bw, static void browser_window_set_pointer(gui_pointer_shape shape); static void download_window_callback(fetch_msg msg, void *p, const char *data, unsigned long size); +static void browser_window_mouse_click_html(struct browser_window *bw, + browser_mouse_click click, int x, int y); static void browser_window_text_selection(struct browser_window* bw, unsigned long click_x, unsigned long click_y, int click_type); @@ -58,13 +60,9 @@ static int redraw_box_list(struct browser_window* bw, struct box* current, unsigned long x, unsigned long y, struct box_position* start, struct box_position* end, int* plot); static void browser_window_redraw_boxes(struct browser_window* bw, struct box_position* start, struct box_position* end); -static void browser_window_follow_link(struct browser_window* bw, - unsigned long click_x, unsigned long click_y, int click_type); static void clear_radio_gadgets(struct browser_window* bw, struct box* box, struct form_control* group); static void gui_redraw_gadget2(struct browser_window* bw, struct box* box, struct form_control* g, unsigned long x, unsigned long y); -static void browser_window_gadget_select(struct browser_window* bw, struct form_control* g, int item); -static int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x, unsigned long click_y); static void browser_form_submit(struct browser_window *bw, struct form *form, struct form_control *submit_button); static void browser_window_textarea_click(struct browser_window* bw, @@ -533,6 +531,204 @@ void download_window_callback(fetch_msg msg, void *p, const char *data, } +/** + * Handle mouse clicks in a browser window. + * + * \param bw browser window + * \param click type of mouse click + * \param x coordinate of mouse + * \param y coordinate of mouse + */ + +void browser_window_mouse_click(struct browser_window *bw, + browser_mouse_click click, int x, int y) +{ + if (!bw->current_content) + return; + + if (bw->current_content->type == CONTENT_HTML) + browser_window_mouse_click_html(bw, click, x, y); +} + + +/** + * Handle mouse clicks in an HTML content window. + * + * \param bw browser window + * \param click type of mouse click + * \param x coordinate of mouse + * \param y coordinate of mouse + */ + +void browser_window_mouse_click_html(struct browser_window *bw, + browser_mouse_click click, int x, int y) +{ + struct content *c = bw->current_content; + struct box *box = c->data.html.layout; + int box_x = 0, box_y = 0; + struct content *content = c; + struct content *gadget_content = c; + char *base_url = 0; + char *href = 0; + char *title = 0; + struct form_control *gadget = 0; + const char *status = 0; + char status_buffer[200]; + gui_pointer_shape pointer = GUI_POINTER_DEFAULT; + char *url; + + /* search the box tree for a link, imagemap, or form control */ + while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) { + if (box->style && + box->style->visibility == CSS_VISIBILITY_HIDDEN) + continue; + + if (box->href) { + base_url = content->data.html.base_url; + href = box->href; + } + + if (box->usemap) { + base_url = content->data.html.base_url; + href = imagemap_get(content, box->usemap, + box_x, box_y, x, y); + } + + if (box->gadget) { + gadget_content = content; + base_url = content->data.html.base_url; + gadget = box->gadget; + } + + if (box->title) + title = box->title; + + if (box->style && box->style->cursor != CSS_CURSOR_UNKNOWN) + pointer = get_pointer_shape(box->style->cursor); + } + + if (gadget) { + switch (gadget->type) { + case GADGET_SELECT: + status = messages_get("FormSelect"); + pointer = GUI_POINTER_MENU; + if (click == BROWSER_MOUSE_CLICK_1) + gui_create_form_select_menu(bw, gadget); + break; + case GADGET_CHECKBOX: + status = messages_get("FormCheckbox"); + if (click == BROWSER_MOUSE_CLICK_1) { + gadget->selected = !gadget->selected; + gui_redraw_gadget(bw, gadget); + } + break; + case GADGET_RADIO: + status = messages_get("FormRadio"); + if (click == BROWSER_MOUSE_CLICK_1) { + clear_radio_gadgets(bw, + gadget_content->data.html. + layout, gadget); + gadget->selected = true; + gui_redraw_gadget(bw, gadget); + } + break; + case GADGET_IMAGE: + if (click == BROWSER_MOUSE_CLICK_1) { + gadget->data.image.mx = x - box_x; + gadget->data.image.my = y - box_y; + } + /* drop through */ + case GADGET_SUBMIT: + if (gadget->form) { + url = url_join(gadget->form->action, base_url); + snprintf(status_buffer, sizeof status_buffer, + messages_get("FormSubmit"), + url ? url : + gadget->form->action); + status = status_buffer; + pointer = GUI_POINTER_POINT; + if (click == BROWSER_MOUSE_CLICK_1) + browser_form_submit(bw, gadget->form, + gadget); + } else { + status = messages_get("FormBadSubmit"); + } + break; + case GADGET_TEXTAREA: + status = messages_get("FormTextarea"); + pointer = GUI_POINTER_CARET; + if (click == BROWSER_MOUSE_CLICK_1) + browser_window_textarea_click(bw, + box_x, box_y, + x - box_x, y - box_y, + box); + break; + case GADGET_TEXTBOX: + case GADGET_PASSWORD: + status = messages_get("FormTextbox"); + pointer = GUI_POINTER_CARET; + if (click == BROWSER_MOUSE_CLICK_1) + browser_window_input_click(bw, + box_x, box_y, + x - box_x, y - box_y, + box); + break; + case GADGET_HIDDEN: + /* not possible: no box generated */ + break; + case GADGET_RESET: + status = messages_get("FormReset"); + break; + case GADGET_FILE: + status = messages_get("FormFile"); + break; + } + + } else if (href) { + url = url_join(href, base_url); + if (!url) + return; + + if (title) { + snprintf(status_buffer, sizeof status_buffer, "%s: %s", + title, url); + status = status_buffer; + } else + status = url; + + pointer = GUI_POINTER_POINT; + + if (click == BROWSER_MOUSE_CLICK_1 || + click == BROWSER_MOUSE_CLICK_2) { + if (fetch_can_fetch(url)) { + if (click == BROWSER_MOUSE_CLICK_1) + browser_window_go(bw, url); + else + browser_window_create(url, bw); + } else { + gui_launch_url(url); + } + } + + } else if (title) { + status = title; + + } else { + if (bw->loading_content) + status = bw->loading_content->status_message; + else + status = c->status_message; + } + + assert(status); + + browser_window_set_status(bw, status); + browser_window_set_pointer(pointer); +} + + + + void clear_radio_gadgets(struct browser_window *bw, struct box *box, struct form_control *group) { @@ -587,138 +783,8 @@ void gui_redraw_gadget(struct browser_window* bw, struct form_control* g) gui_redraw_gadget2(bw, bw->current_content->data.html.layout->children, g, 0, 0); } -void browser_window_gadget_select(struct browser_window* bw, struct form_control* g, int item) -{ - struct form_option* o; - int count; - struct box *inline_box = g->box->children->children; - int x, y; - - for (count = 0, o = g->data.select.items; - o != NULL; - count++, o = o->next) { - if (!g->data.select.multiple) - o->selected = false; - if (count == item) { - if (g->data.select.multiple) { - if (o->selected) { - o->selected = false; - g->data.select.num_selected--; - } else { - o->selected = true; - g->data.select.num_selected++; - } - } else { - o->selected = true; - } - } - if (o->selected) - g->data.select.current = o; - } - - xfree(inline_box->text); - if (g->data.select.num_selected == 0) - inline_box->text = xstrdup(messages_get("Form_None")); - else if (g->data.select.num_selected == 1) - inline_box->text = xstrdup(g->data.select.current->text); - else - inline_box->text = xstrdup(messages_get("Form_Many")); - inline_box->width = g->box->width; - inline_box->length = strlen(inline_box->text); - - box_coords(g->box, &x, &y); - gui_window_redraw(bw->window, (unsigned int)x, (unsigned int)y, - (unsigned int)(x + g->box->width), - (unsigned int)(y + g->box->height)); -} - -int browser_window_gadget_click(struct browser_window* bw, unsigned long click_x, unsigned long click_y) -{ - struct box_selection* click_boxes; - int found, plot_index; - int i; - int x, y; - - found = 0; - click_boxes = NULL; - plot_index = 0; - - assert(bw->current_content->type == CONTENT_HTML); - box_under_area(bw->current_content, - bw->current_content->data.html.layout->children, - click_x, click_y, 0, 0, &click_boxes, &found, &plot_index); - - if (found == 0) - return 0; - - for (i = found - 1; i >= 0; i--) - { - if (click_boxes[i].box->style->visibility == CSS_VISIBILITY_HIDDEN) - continue; - - if (click_boxes[i].box->gadget) - { - struct form_control* g = click_boxes[i].box->gadget; - - /* gadget clicked */ - switch (g->type) - { - case GADGET_SELECT: - gui_gadget_combo(bw, g, click_x, click_y); - break; - case GADGET_CHECKBOX: - g->selected = !g->selected; - gui_redraw_gadget(bw, g); - break; - case GADGET_RADIO: - clear_radio_gadgets(bw, click_boxes[i].content->data.html.layout->children, g); - g->selected = true; - gui_redraw_gadget(bw, g); - break; - case GADGET_SUBMIT: - if (g->form) - browser_form_submit(bw, g->form, g); - break; - case GADGET_TEXTAREA: - browser_window_textarea_click(bw, - (unsigned int)click_boxes[i].actual_x, - (unsigned int)click_boxes[i].actual_y, - (int)(click_x - click_boxes[i].actual_x), - (int)(click_y - click_boxes[i].actual_y), - click_boxes[i].box); - break; - case GADGET_TEXTBOX: - case GADGET_PASSWORD: - browser_window_input_click(bw, - (unsigned int)click_boxes[i].actual_x, - (unsigned int)click_boxes[i].actual_y, - click_x - click_boxes[i].actual_x, - click_y - click_boxes[i].actual_y, - click_boxes[i].box); - break; - case GADGET_HIDDEN: - break; - case GADGET_IMAGE: - box_coords(click_boxes[i].box, &x, &y); - g->data.image.mx = click_x - x; - g->data.image.my = click_y - y; - if (g->form) - browser_form_submit(bw, g->form, g); - break; - case GADGET_RESET: - break; - case GADGET_FILE: - break; - } - xfree(click_boxes); - return 1; - } - } - xfree(click_boxes); - return 0; -} /** @@ -1342,47 +1408,67 @@ bool browser_window_key_press(struct browser_window *bw, char key) } -int browser_window_action(struct browser_window *bw, - struct browser_action *act) +/** + * Process a selection from a form select menu. + * + * \param bw browser window with menu + * \param control form control with menu + * \param item index of item selected from the menu + */ + +void browser_window_form_select(struct browser_window *bw, + struct form_control *control, int item) { - switch (act->type) { - case act_MOUSE_AT: - browser_window_follow_link(bw, act->data.mouse.x, - act->data.mouse.y, 0); - break; - case act_MOUSE_CLICK: - return browser_window_gadget_click(bw, act->data.mouse.x, - act->data.mouse.y); - break; - case act_CLEAR_SELECTION: -// browser_window_text_selection(bw, act->data.mouse.x, -// act->data.mouse.y, 0); - break; - case act_START_NEW_SELECTION: -// browser_window_text_selection(bw, act->data.mouse.x, -// act->data.mouse.y, 1); - break; - case act_ALTER_SELECTION: -// browser_window_text_selection(bw, act->data.mouse.x, -// act->data.mouse.y, 2); - break; - case act_FOLLOW_LINK: - browser_window_follow_link(bw, act->data.mouse.x, - act->data.mouse.y, 1); - break; - case act_FOLLOW_LINK_NEW_WINDOW: - browser_window_follow_link(bw, act->data.mouse.x, - act->data.mouse.y, 2); - break; - case act_GADGET_SELECT: - browser_window_gadget_select(bw, act->data.gadget_select.g, - act->data.gadget_select.item); - default: - break; + struct form_option *o; + int count; + struct box *inline_box = control->box->children->children; + int x, y; + + for (count = 0, o = control->data.select.items; + o != NULL; + count++, o = o->next) { + if (!control->data.select.multiple) + o->selected = false; + if (count == item) { + if (control->data.select.multiple) { + if (o->selected) { + o->selected = false; + control->data.select.num_selected--; + } else { + o->selected = true; + control->data.select.num_selected++; + } + } else { + o->selected = true; + } + } + if (o->selected) + control->data.select.current = o; } - return 0; + + free(inline_box->text); + inline_box->text = 0; + if (control->data.select.num_selected == 0) + inline_box->text = strdup(messages_get("Form_None")); + else if (control->data.select.num_selected == 1) + inline_box->text = strdup(control->data.select.current->text); + else + inline_box->text = strdup(messages_get("Form_Many")); + if (!inline_box->text) { + warn_user("NoMemory", 0); + inline_box->length = 0; + } else + inline_box->length = strlen(inline_box->text); + inline_box->width = control->box->width; + + box_coords(control->box, &x, &y); + gui_window_redraw(bw->window, x, y, + x + control->box->width, y + control->box->height); } + + + void box_under_area(struct content *content, struct box *box, unsigned long x, unsigned long y, unsigned long ox, unsigned long oy, @@ -1471,170 +1557,6 @@ gui_pointer_shape get_pointer_shape(css_cursor cursor) { return pointer; } -void browser_window_follow_link(struct browser_window *bw, - unsigned long click_x, - unsigned long click_y, int click_type) -{ - struct box_selection *click_boxes; - int found, plot_index; - int i; - int done = 0; - struct css_style *style; - gui_pointer_shape pointer = GUI_POINTER_DEFAULT; - - found = 0; - click_boxes = NULL; - plot_index = 0; - - if (bw->current_content->type != CONTENT_HTML) - return; - - box_under_area(bw->current_content, - bw->current_content->data.html.layout->children, - click_x, click_y, 0, 0, &click_boxes, &found, - &plot_index); - - if (found == 0) - return; - - for (i = found - 1; i >= 0; i--) { - style = click_boxes[i].box->style; - if (style != 0 && style->visibility == CSS_VISIBILITY_HIDDEN) - continue; - if (click_boxes[i].box->href != NULL) { - char *url = - url_join((char *) click_boxes[i].box->href, - click_boxes[i].content->data.html. - base_url); - if (!url) - continue; - - if (click_type == 1) { - if (fetch_can_fetch(url)) { - browser_window_go(bw, url); - } - else { - gui_launch_url(url); - done = 1; - } - } else if (click_type == 2) { - if (fetch_can_fetch(url)) { - browser_window_create(url, bw); - } - else { - gui_launch_url(url); - done = 1; - } - } else if (click_type == 0) { - browser_window_set_status(bw, url); - pointer = GUI_POINTER_POINT; - done = 1; - } - free(url); - break; - } - if (click_boxes[i].box->usemap != NULL) { - char *href, *url; - - href = imagemap_get(click_boxes[i].content, - click_boxes[i].box->usemap, - click_boxes[i].actual_x, - click_boxes[i].actual_y, - click_x, click_y); - if (!href) - continue; - - url = url_join(href, - click_boxes[i].content->data.html. - base_url); - if (!url) - continue; - - if (click_type == 1) { - if (fetch_can_fetch(url)) { - browser_window_go(bw, url); - } - else { - gui_launch_url(url); - done = 1; - } - } else if (click_type == 2) { - if (fetch_can_fetch(url)) { - browser_window_create(url, NULL); - } - else { - gui_launch_url(url); - done = 1; - } - } else if (click_type == 0) { - browser_window_set_status(bw, url); - pointer = GUI_POINTER_POINT; - done = 1; - } - free(url); - break; - } - if (click_type == 0 && click_boxes[i].box->gadget != NULL) { - if (click_boxes[i].box->gadget->type == GADGET_TEXTBOX || - click_boxes[i].box->gadget->type == GADGET_TEXTAREA || - click_boxes[i].box->gadget->type == GADGET_PASSWORD) { - pointer = GUI_POINTER_CARET; - done = 1; - break; - } - else if (click_boxes[i].box->gadget->type == GADGET_SELECT) { - pointer = GUI_POINTER_MENU; - done = 1; - break; - } - else if (click_boxes[i].box->gadget->type == GADGET_SUBMIT || click_boxes[i].box->gadget->type == GADGET_IMAGE) { - struct form *form; - char *url, *href; - form = click_boxes[i].box->gadget->form; - if (!form) continue; - href = form->action; - if (!href) continue; - url = url_join(href, click_boxes[i].content->data.html.base_url); - if (!url) continue; - browser_window_set_status(bw, url); - free(url); - done = 1; - break; - } - } - if (click_type == 0 && click_boxes[i].box->title != NULL) { - browser_window_set_status(bw, - click_boxes[i].box-> - title); - done = 1; - break; - } - if (click_type == 0 && style != 0 && - style->cursor != CSS_CURSOR_UNKNOWN && - pointer == GUI_POINTER_DEFAULT) { - pointer = get_pointer_shape(click_boxes[i].box->style->cursor); - } - } - - if (click_type == 0 && done == 0) { - if (bw->loading_content != 0) { - browser_window_set_status(bw, - bw->loading_content-> - status_message); - } - else { - browser_window_set_status(bw, - bw->current_content-> - status_message); - } - } - - browser_window_set_pointer(pointer); - - free(click_boxes); - - return; -} void browser_window_text_selection(struct browser_window *bw, unsigned long click_x, diff --git a/desktop/browser.h b/desktop/browser.h index 1a3427107..cd6cc202c 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -53,25 +53,12 @@ struct browser_window }; -struct browser_action -{ - enum { act_UNKNOWN, - act_MOUSE_AT, act_MOUSE_CLICK, act_START_NEW_SELECTION, - act_ALTER_SELECTION, act_CLEAR_SELECTION, - act_FOLLOW_LINK, act_FOLLOW_LINK_NEW_WINDOW, - act_GADGET_SELECT - } type; - union { - struct { - unsigned long x; - unsigned long y; - } mouse; - struct { - struct form_control* g; - int item; - } gadget_select; - } data; -}; +typedef enum { + BROWSER_MOUSE_CLICK_1, + BROWSER_MOUSE_CLICK_2, + BROWSER_MOUSE_HOVER, +} browser_mouse_click; + struct box_selection { @@ -93,7 +80,11 @@ void browser_window_stop(struct browser_window *bw); void browser_window_reload(struct browser_window *bw, bool all); void browser_window_destroy(struct browser_window *bw); -int browser_window_action(struct browser_window* bw, struct browser_action* act); +void browser_window_mouse_click(struct browser_window *bw, + browser_mouse_click click, int x, int y); +bool browser_window_key_press(struct browser_window *bw, char key); +void browser_window_form_select(struct browser_window *bw, + struct form_control *control, int item); void box_under_area(struct content *content, struct box* box, unsigned long x, unsigned long y, unsigned long ox, unsigned long oy, struct box_selection** found, int* count, int* plot_index); @@ -105,8 +96,6 @@ int box_position_distance(struct box_position* x, struct box_position* y); void gui_redraw_gadget(struct browser_window* bw, struct form_control* g); -bool browser_window_key_press(struct browser_window *bw, char key); - /* In platform specific hotlist.c. */ void hotlist_visited(struct content *content); diff --git a/desktop/gui.h b/desktop/gui.h index bef7f2362..e0ad49aa0 100644 --- a/desktop/gui.h +++ b/desktop/gui.h @@ -25,6 +25,11 @@ typedef enum { GUI_POINTER_DEFAULT, GUI_POINTER_POINT, GUI_POINTER_CARET, #include "netsurf/content/content.h" #include "netsurf/desktop/browser.h" +void gui_init(int argc, char** argv); +void gui_multitask(void); +void gui_poll(bool active); +void gui_quit(void); + struct gui_window *gui_create_browser_window(struct browser_window *bw, struct browser_window *clone); void gui_window_destroy(struct gui_window *g); @@ -39,6 +44,10 @@ void gui_window_set_extent(struct gui_window *g, int width, int height); void gui_window_set_status(struct gui_window *g, const char *text); void gui_window_set_pointer(gui_pointer_shape shape); void gui_window_set_url(struct gui_window *g, const char *url); +void gui_window_start_throbber(struct gui_window *g); +void gui_window_stop_throbber(struct gui_window *g); +void gui_window_place_caret(struct gui_window *g, int x, int y, int height); +void gui_window_new_content(struct gui_window *g); struct gui_download_window *gui_download_window_create(const char *url, const char *mime_type, struct fetch *fetch, @@ -49,20 +58,9 @@ void gui_download_window_error(struct gui_download_window *dw, const char *error_msg); void gui_download_window_done(struct gui_download_window *dw); -void gui_init(int argc, char** argv); -void gui_multitask(void); -void gui_poll(bool active); -void gui_quit(void); - -void gui_window_start_throbber(struct gui_window *g); -void gui_window_stop_throbber(struct gui_window *g); - -void gui_gadget_combo(struct browser_window* bw, struct form_control* g, unsigned long mx, unsigned long my); - -void gui_window_place_caret(struct gui_window *g, int x, int y, int height); +void gui_create_form_select_menu(struct browser_window *bw, + struct form_control *control); void gui_launch_url(const char *url); -void gui_window_new_content(struct gui_window *g); - #endif |