From 58e2d033ece8c60f495ddba9a93ecab793a7a50f Mon Sep 17 00:00:00 2001 From: James Bursa Date: Sun, 18 Jul 2004 17:38:01 +0000 Subject: [project @ 2004-07-18 17:38:01 by bursa] Improve form control interaction code. Replace box_under_area() with simpler box_at_point(). Detect objects for menu once on menu opening. Remove obsolete text selection code. svn path=/import/netsurf/; revision=1096 --- desktop/browser.c | 528 +++++++------------------------------------------ desktop/browser.h | 30 +-- render/box.c | 30 +++ render/box.h | 1 + render/html.h | 19 +- riscos/download.c | 2 + riscos/gui.c | 2 +- riscos/hotlist.c | 2 +- riscos/htmlredraw.c | 61 ------ riscos/menus.c | 135 ++++++------- riscos/textselection.c | 6 +- riscos/window.c | 71 ++++--- 12 files changed, 214 insertions(+), 673 deletions(-) diff --git a/desktop/browser.c b/desktop/browser.c index 8ff33228c..b01567f7b 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -51,18 +51,9 @@ 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); -static void browser_window_clear_text_selection(struct browser_window* bw); -static void browser_window_change_text_selection(struct browser_window* bw, struct box_position* new_start, struct box_position* new_end); -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 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_radio_set(struct content *content, + struct form_control *radio); +static void browser_redraw_box(struct content *c, struct box *box); 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, @@ -455,6 +446,7 @@ void browser_window_set_status(struct browser_window *bw, const char *text) gui_window_set_status(bw->window, text); } + /** * Change the shape of the mouse pointer * @@ -563,20 +555,20 @@ void browser_window_mouse_click(struct browser_window *bw, 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; - struct box *gadget_box = 0; - const char *status = 0; + char *url; char status_buffer[200]; + const char *status = 0; gui_pointer_shape pointer = GUI_POINTER_DEFAULT; - char *url; + int box_x = 0, box_y = 0; + struct box *gadget_box = 0; + struct content *c = bw->current_content; + struct box *box = c->data.html.layout; + struct content *content = c; + struct content *gadget_content = c; + struct form_control *gadget = 0; /* search the box tree for a link, imagemap, or form control */ while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) { @@ -621,18 +613,13 @@ void browser_window_mouse_click_html(struct browser_window *bw, status = messages_get("FormCheckbox"); if (click == BROWSER_MOUSE_CLICK_1) { gadget->selected = !gadget->selected; - gui_redraw_gadget(bw, gadget); + browser_redraw_box(gadget_content, gadget_box); } 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); - } + if (click == BROWSER_MOUSE_CLICK_1) + browser_radio_set(gadget_content, gadget); break; case GADGET_IMAGE: if (click == BROWSER_MOUSE_CLICK_1) { @@ -729,64 +716,71 @@ void browser_window_mouse_click_html(struct browser_window *bw, } +/** + * Set a radio form control and clear the others in the group. + * + * \param content content containing the form, of type CONTENT_TYPE + * \param radio form control of type GADGET_RADIO + */ - -void clear_radio_gadgets(struct browser_window *bw, struct box *box, - struct form_control *group) +void browser_radio_set(struct content *content, + struct form_control *radio) { - struct box *c; - if (box == NULL) + struct form_control *control; + + if (radio->selected) return; - if (box->gadget != 0) { - if (box->gadget->type == GADGET_RADIO - && box->gadget->name != 0 && box->gadget != group) { - if (strcmp(box->gadget->name, group->name) == 0) { - if (box->gadget->selected) { - box->gadget->selected = false; - gui_redraw_gadget(bw, box->gadget); - } - } + + for (control = radio->form->controls; control; + control = control->next) { + if (control->type != GADGET_RADIO) + continue; + if (control == radio) + continue; + if (strcmp(control->name, radio->name) != 0) + continue; + + if (control->selected) { + control->selected = false; + browser_redraw_box(content, control->box); } } - for (c = box->children; c != 0; c = c->next) - if (c->type != BOX_FLOAT_LEFT - && c->type != BOX_FLOAT_RIGHT) - clear_radio_gadgets(bw, c, group); - for (c = box->float_children; c != 0; c = c->next_float) - clear_radio_gadgets(bw, c, group); + radio->selected = true; + browser_redraw_box(content, radio->box); } -void gui_redraw_gadget2(struct browser_window *bw, struct box *box, - struct form_control *g, unsigned long x, - unsigned long y) -{ - struct box *c; - if (box->gadget == g) { - gui_window_redraw(bw->window, x + box->x, y + box->y, - x + box->x + box->width, - y + box->y + box->height); - } +/** + * Redraw a box. + * + * \param c content containing the box, of type CONTENT_HTML + * \param box box to redraw + */ - for (c = box->children; c != 0; c = c->next) - if (c->type != BOX_FLOAT_LEFT - && c->type != BOX_FLOAT_RIGHT) - gui_redraw_gadget2(bw, c, g, box->x + x, - box->y + y); +void browser_redraw_box(struct content *c, struct box *box) +{ + int x, y; + union content_msg_data data; - for (c = box->float_children; c != 0; c = c->next_float) - gui_redraw_gadget2(bw, c, g, box->x + x, box->y + y); -} + box_coords(box, &x, &y); -void gui_redraw_gadget(struct browser_window* bw, struct form_control* g) -{ - assert(bw->current_content->type == CONTENT_HTML); - gui_redraw_gadget2(bw, bw->current_content->data.html.layout->children, g, 0, 0); -} + data.redraw.x = x; + data.redraw.y = y; + data.redraw.width = x + box->width; + data.redraw.height = y + box->height; + + data.redraw.full_redraw = true; + data.redraw.object = c; + data.redraw.object_x = 0; + data.redraw.object_y = 0; + data.redraw.object_width = c->width; + data.redraw.object_height = c->height; + content_broadcast(c, CONTENT_MSG_REDRAW, data); +} /** @@ -1469,55 +1463,6 @@ void browser_window_form_select(struct browser_window *bw, } - - -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) -{ - struct box *c; - - if (box == NULL) - return; - - *plot_index = *plot_index + 1; - - if (x >= box->x + ox && x <= box->x + ox + box->width && - y >= box->y + oy && y <= box->y + oy + box->height) { - *found = - xrealloc(*found, - sizeof(struct box_selection) * (*count + 1)); - (*found)[*count].content = content; - (*found)[*count].box = box; - (*found)[*count].actual_x = box->x + ox; - (*found)[*count].actual_y = box->y + oy; - (*found)[*count].plot_index = *plot_index; - *count = *count + 1; - } - - /* consider embedded HTML pages */ - if (box->object != 0 && box->object->type == CONTENT_HTML && - box->object->data.html.layout != 0) - box_under_area(box->object, box->object->data.html.layout, - x, y, box->x + ox, box->y +oy, - found, count, plot_index); - - for (c = box->children; c != 0; c = c->next) - if (c->type != BOX_FLOAT_LEFT - && c->type != BOX_FLOAT_RIGHT) - box_under_area(content, c, x, y, - box->x + ox, box->y + oy, - found, count, plot_index); - - for (c = box->float_children; c != 0; c = c->next_float) - box_under_area(content, c, x, y, box->x + ox, box->y + oy, - found, count, plot_index); - - return; -} - gui_pointer_shape get_pointer_shape(css_cursor cursor) { gui_pointer_shape pointer; @@ -1560,347 +1505,6 @@ gui_pointer_shape get_pointer_shape(css_cursor cursor) { } -void browser_window_text_selection(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; - - if (click_type == 0 /* click_CLEAR_SELECTION */ ) { - browser_window_clear_text_selection(bw); - return; - } - - 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; - - for (i = found - 1; i >= 0; i--) { - if (click_boxes[i].box->type == BOX_INLINE) { - struct box_position new_pos; - struct box_position *start; - struct box_position *end; - int click_char_offset, click_pixel_offset; - - /* shortcuts */ - start = - &(bw->current_content->data.html. - text_selection.start); - end = - &(bw->current_content->data.html. - text_selection.end); - - if (click_boxes[i].box->text - && click_boxes[i].box->font) { - nsfont_position_in_string(click_boxes[i].box->font, - click_boxes[i].box->text, - click_boxes[i].box->length, - click_x - click_boxes[i].actual_x, - &click_char_offset, - &click_pixel_offset); - } else { - click_char_offset = 0; - click_pixel_offset = 0; - } - - new_pos.box = click_boxes[i].box; - new_pos.actual_box_x = click_boxes[i].actual_x; - new_pos.actual_box_y = click_boxes[i].actual_y; - new_pos.plot_index = click_boxes[i].plot_index; - new_pos.char_offset = click_char_offset; - new_pos.pixel_offset = click_pixel_offset; - - if (click_type == 1 /* click_START_SELECTION */ ) { - /* update both start and end */ - browser_window_clear_text_selection(bw); - click_boxes[i].content->data.html. - text_selection.altering = - alter_UNKNOWN; - click_boxes[i].content->data.html. - text_selection.selected = 1; - memcpy(start, &new_pos, - sizeof(struct box_position)); - memcpy(end, &new_pos, - sizeof(struct box_position)); - i = -1; - } else if (click_boxes[i].content->data.html. - text_selection.selected == 1 - && click_type == - 2 /* click_ALTER_SELECTION */ ) { - /* alter selection */ - - if (click_boxes[i].content->data.html. - text_selection.altering != - alter_UNKNOWN) { - if (click_boxes[i].content->data.html. - text_selection.altering == - alter_START) { - if (box_position_gt - (&new_pos, end)) { - click_boxes[i].content->data.html.text_selection.altering = alter_END; - browser_window_change_text_selection - (bw, end, - &new_pos); - } else - browser_window_change_text_selection - (bw, &new_pos, - end); - } else { - if (box_position_lt - (&new_pos, start)) { - click_boxes[i].content->data.html.text_selection.altering = alter_START; - browser_window_change_text_selection - (bw, &new_pos, - start); - } else - browser_window_change_text_selection - (bw, start, - &new_pos); - } - i = -1; - } else { - /* work out whether the start or end is being dragged */ - - int click_start_distance = 0; - int click_end_distance = 0; - - int inside_block = 0; - int before_start = 0; - int after_end = 0; - - if (box_position_lt - (&new_pos, start)) - before_start = 1; - - if (box_position_gt(&new_pos, end)) - after_end = 1; - - if (!box_position_lt - (&new_pos, start) - && !box_position_gt(&new_pos, - end)) - inside_block = 1; - - if (inside_block == 1) { - click_start_distance = - box_position_distance - (start, &new_pos); - click_end_distance = - box_position_distance - (end, &new_pos); - } - - if (before_start == 1 - || (after_end == 0 - && inside_block == 1 - && click_start_distance < - click_end_distance)) { - /* alter the start position */ - click_boxes[i].content->data. - html.text_selection. - altering = alter_START; - browser_window_change_text_selection - (bw, &new_pos, end); - i = -1; - } else if (after_end == 1 - || (before_start == 0 - && inside_block == 1 - && - click_start_distance - >= - click_end_distance)) - { - /* alter the end position */ - click_boxes[i].content->data. - html.text_selection. - altering = alter_END; - browser_window_change_text_selection - (bw, start, &new_pos); - i = -1; - } - } - } - } - } - - free(click_boxes); - - return; -} - -void browser_window_clear_text_selection(struct browser_window *bw) -{ - struct box_position *old_start; - struct box_position *old_end; - - assert(bw->current_content->type == CONTENT_HTML); - old_start = &(bw->current_content->data.html.text_selection.start); - old_end = &(bw->current_content->data.html.text_selection.end); - - if (bw->current_content->data.html.text_selection.selected == 1) { - bw->current_content->data.html.text_selection.selected = 0; - browser_window_redraw_boxes(bw, old_start, old_end); - } - - bw->current_content->data.html.text_selection.altering = - alter_UNKNOWN; -} - -void browser_window_change_text_selection(struct browser_window *bw, - struct box_position *new_start, - struct box_position *new_end) -{ - struct box_position start; - struct box_position end; - - assert(bw->current_content->type == CONTENT_HTML); - memcpy(&start, - &(bw->current_content->data.html.text_selection.start), - sizeof(struct box_position)); - memcpy(&end, &(bw->current_content->data.html.text_selection.end), - sizeof(struct box_position)); - - if (!box_position_eq(new_start, &start)) { - if (box_position_lt(new_start, &start)) - browser_window_redraw_boxes(bw, new_start, &start); - else - browser_window_redraw_boxes(bw, &start, new_start); - memcpy(&start, new_start, sizeof(struct box_position)); - } - - if (!box_position_eq(new_end, &end)) { - if (box_position_lt(new_end, &end)) - browser_window_redraw_boxes(bw, new_end, &end); - else - browser_window_redraw_boxes(bw, &end, new_end); - memcpy(&end, new_end, sizeof(struct box_position)); - } - - memcpy(&(bw->current_content->data.html.text_selection.start), - &start, sizeof(struct box_position)); - memcpy(&(bw->current_content->data.html.text_selection.end), &end, - sizeof(struct box_position)); - - bw->current_content->data.html.text_selection.selected = 1; -} - - -int box_position_lt(struct box_position *x, struct box_position *y) -{ - return (x->plot_index < y->plot_index || - (x->plot_index == y->plot_index - && x->char_offset < y->char_offset)); -} - -int box_position_gt(struct box_position *x, struct box_position *y) -{ - return (x->plot_index > y->plot_index || - (x->plot_index == y->plot_index - && x->char_offset > y->char_offset)); -} - -int box_position_eq(struct box_position *x, struct box_position *y) -{ - return (x->plot_index == y->plot_index - && x->char_offset == y->char_offset); -} - -int box_position_distance(struct box_position *x, struct box_position *y) -{ - int dx = (y->actual_box_x + y->pixel_offset) - - (x->actual_box_x + x->pixel_offset); - int dy = (y->actual_box_y + y->box->height / 2) - - (x->actual_box_y + x->box->height / 2); - return dx * dx + dy * dy; -} - -unsigned long redraw_min_x = LONG_MAX; -unsigned long redraw_min_y = LONG_MAX; -unsigned long redraw_max_x = 0; -unsigned long redraw_max_y = 0; - -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) -{ - - struct box *c; - - if (current == start->box) - *plot = 1; - - if (*plot >= 1 && current->type == BOX_INLINE) { - unsigned long minx = x + current->x; - unsigned long miny = y + current->y; - unsigned long maxx = x + current->x + current->width; - unsigned long maxy = y + current->y + current->height; - - if (minx < redraw_min_x) - redraw_min_x = minx; - if (miny < redraw_min_y) - redraw_min_y = miny; - if (maxx > redraw_max_x) - redraw_max_x = maxx; - if (maxy > redraw_max_y) - redraw_max_y = maxy; - - *plot = 2; - } - - if (current == end->box) - return 1; - - for (c = current->children; c != 0; c = c->next) - if (c->type != BOX_FLOAT_LEFT - && c->type != BOX_FLOAT_RIGHT) - if (redraw_box_list - (bw, c, x + current->x, y + current->y, start, - end, plot) == 1) - return 1; - - for (c = current->float_children; c != 0; c = c->next_float) - if (redraw_box_list(bw, c, x + current->x, y + current->y, - start, end, plot) == 1) - return 1; - - return 0; -} - -void browser_window_redraw_boxes(struct browser_window *bw, - struct box_position *start, - struct box_position *end) -{ - int plot = 0; - - assert(bw->current_content->type == CONTENT_HTML); - if (box_position_eq(start, end)) - return; - - redraw_min_x = LONG_MAX; - redraw_min_y = LONG_MAX; - redraw_max_x = 0; - redraw_max_y = 0; - - redraw_box_list(bw, bw->current_content->data.html.layout, - 0, 0, start, end, &plot); - - if (plot == 2) - gui_window_redraw(bw->window, redraw_min_x, redraw_min_y, - redraw_max_x, redraw_max_y); -} - /** * Collect controls and submit a form. */ diff --git a/desktop/browser.h b/desktop/browser.h index cd6cc202c..2442ace85 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -15,10 +15,10 @@ #include #include -#include "netsurf/utils/config.h" -#include "netsurf/content/content.h" struct box; +struct content; +struct form_control; struct form_successful_control; struct gui_window; struct history; @@ -60,16 +60,6 @@ typedef enum { } browser_mouse_click; -struct box_selection -{ - struct content *content; - struct box* box; - int actual_x; - int actual_y; - int plot_index; -}; - - void browser_window_create(const char *url, struct browser_window *clone); void browser_window_go(struct browser_window *bw, const char *url); void browser_window_go_post(struct browser_window *bw, const char *url, @@ -86,16 +76,6 @@ 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); - -int box_position_lt(struct box_position* x, struct box_position* y); -int box_position_gt(struct box_position* x, struct box_position* y); -int box_position_eq(struct box_position* x, struct box_position* y); -int box_position_distance(struct box_position* x, struct box_position* y); - -void gui_redraw_gadget(struct browser_window* bw, struct form_control* g); - /* In platform specific hotlist.c. */ void hotlist_visited(struct content *content); @@ -109,10 +89,4 @@ void history_forward(struct browser_window *bw, struct history *history); bool history_back_available(struct history *history); bool history_forward_available(struct history *history); -/* In platform specific about.c. */ -struct content *about_create(const char *url, - void (*callback)(content_msg msg, struct content *c, void *p1, - void *p2, const char *error), - void *p1, void *p2, unsigned long width, unsigned long height); - #endif diff --git a/render/box.c b/render/box.c index ef3b60283..145c3a18b 100644 --- a/render/box.c +++ b/render/box.c @@ -2785,3 +2785,33 @@ struct box *box_at_point(struct box *box, int x, int y, return 0; } + + +/** + * Find the box containing an object at the given coordinates, if any. + * + * \param c content to search, must have type CONTENT_HTML + * \param x coordinates in document units + * \param y coordinates in document units + */ + +struct box *box_object_at_point(struct content *c, int x, int y) +{ + struct box *box = c->data.html.layout; + int box_x = 0, box_y = 0; + struct content *content = c; + struct box *object_box = 0; + + assert(c->type == CONTENT_HTML); + + 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->object) + object_box = box; + } + + return object_box; +} diff --git a/render/box.h b/render/box.h index d97406352..58328884b 100644 --- a/render/box.h +++ b/render/box.h @@ -251,5 +251,6 @@ void box_coords(struct box *box, int *x, int *y); struct box *box_at_point(struct box *box, int x, int y, int *box_x, int *box_y, struct content **content); +struct box *box_object_at_point(struct content *c, int x, int y); #endif diff --git a/render/html.h b/render/html.h index 6d9ad8b80..4dc1ca2a4 100644 --- a/render/html.h +++ b/render/html.h @@ -26,21 +26,13 @@ struct content; struct object_params; struct imagemap; -struct box_position { - struct box *box; - int actual_box_x; - int actual_box_y; - int plot_index; - int pixel_offset; - int char_offset; -}; - /** Data specific to CONTENT_HTML. */ struct content_html_data { htmlParserCtxt *parser; /**< HTML parser context. */ xmlChar *encoding; /**< Encoding of source. */ - bool getenc; /**< Need to get the encoding from the document, as server is broken. */ + bool getenc; /**< Need to get the encoding from the document, as it + * wasn't specified in the Content-Type header. */ char *base_url; /**< Base URL (may be a copy of content->url). */ @@ -54,13 +46,6 @@ struct content_html_data { struct content **stylesheet_content; struct css_style *style; /**< Base style. */ - struct { - struct box_position start; - struct box_position end; - enum { alter_UNKNOWN, alter_START, alter_END } altering; - int selected; /* 0 = unselected, 1 = selected */ - } text_selection; - struct font_set *fonts; /**< Set of fonts. */ /** Number of entries in object. */ diff --git a/riscos/download.c b/riscos/download.c index 591ddce14..2a6d8d583 100644 --- a/riscos/download.c +++ b/riscos/download.c @@ -217,6 +217,8 @@ struct gui_download_window *gui_download_window_create(const char *url, dw->prev = 0; dw->next = download_window_list; + if (download_window_list) + download_window_list->prev = dw; download_window_list = dw; ro_gui_download_update_status(dw); diff --git a/riscos/gui.c b/riscos/gui.c index f3a05f9ae..8cde110ee 100644 --- a/riscos/gui.c +++ b/riscos/gui.c @@ -783,7 +783,7 @@ void ro_gui_icon_bar_click(wimp_pointer *pointer) { int key_down = 0; if (pointer->buttons == wimp_CLICK_MENU) { - ro_gui_create_menu(iconbar_menu, pointer->pos.x - 64, + ro_gui_create_menu(iconbar_menu, pointer->pos.x, 96 + iconbar_menu_height, NULL); } else if (pointer->buttons == wimp_CLICK_SELECT) { char url[80]; diff --git a/riscos/hotlist.c b/riscos/hotlist.c index 0024336f0..c902628c3 100644 --- a/riscos/hotlist.c +++ b/riscos/hotlist.c @@ -1452,7 +1452,7 @@ void ro_gui_hotlist_click(wimp_pointer *pointer) { /* Create a menu if we should */ if (buttons == wimp_CLICK_MENU) { - ro_gui_create_menu(hotlist_menu, pointer->pos.x - 64, + ro_gui_create_menu(hotlist_menu, pointer->pos.x, pointer->pos.y, NULL); menu_open = true; return; diff --git a/riscos/htmlredraw.c b/riscos/htmlredraw.c index 9a285fb3c..1b2ef4ec7 100644 --- a/riscos/htmlredraw.c +++ b/riscos/htmlredraw.c @@ -310,52 +310,6 @@ void html_redraw_box(struct content *content, struct box * box, } else if (box->text && box->font) { - if (content->data.html.text_selection.selected == 1) { - struct box_position *start; - struct box_position *end; - - start = &(content->data.html.text_selection.start); - end = &(content->data.html.text_selection.end); - - if (start->box == box) { - if (end->box == box) { - colourtrans_set_gcol(os_COLOUR_VERY_LIGHT_GREY, colourtrans_USE_ECFS, 0, 0); - os_plot(os_MOVE_TO, - x + start->pixel_offset * 2, - y - height); - os_plot(os_PLOT_RECTANGLE | os_PLOT_TO, - x + end->pixel_offset * 2 - 2, - y - 2); - } else { - colourtrans_set_gcol(os_COLOUR_VERY_LIGHT_GREY, colourtrans_USE_ECFS, 0, 0); - os_plot(os_MOVE_TO, - x + start->pixel_offset * 2, - y - height); - os_plot(os_PLOT_RECTANGLE | os_PLOT_TO, - x + width - 2, - y - 2); - *select_on = true; - } - } else if (*select_on) { - if (end->box != box) { - colourtrans_set_gcol(os_COLOUR_VERY_LIGHT_GREY, colourtrans_USE_ECFS, 0, 0); - os_plot(os_MOVE_TO, x, - y - height); - os_plot(os_PLOT_RECTANGLE | os_PLOT_TO, - x + width - 2, - y - 2); - } else { - colourtrans_set_gcol(os_COLOUR_VERY_LIGHT_GREY, colourtrans_USE_ECFS, 0, 0); - os_plot(os_MOVE_TO, x, - y - height); - os_plot(os_PLOT_RECTANGLE | os_PLOT_TO, - x + end->pixel_offset * 2 - 2, - y - 2); - *select_on = false; - } - } - } - colourtrans_set_font_colours(box->font->handle, current_background_color << 8, box->style->color << 8, 14, 0, 0, 0); @@ -429,21 +383,6 @@ void html_redraw_box(struct content *content, struct box * box, if (box->type == BOX_BLOCK || box->type == BOX_INLINE_BLOCK || box->type == BOX_TABLE_CELL || box->object) html_redraw_clip(clip_x0, clip_y0, clip_x1, clip_y1); - -/* } else { - if (content->data.html.text_selection.selected == 1) { - struct box_position *start; - struct box_position *end; - - start = &(content->data.html.text_selection.start); - end = &(content->data.html.text_selection.end); - - if (start->box == box && end->box != box) - *select_on = true; - else if (*select_on && end->box == box) - *select_on = false; - } - }*/ } diff --git a/riscos/menus.c b/riscos/menus.c index 5039d973a..9bb3bb5b1 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -48,7 +48,6 @@ static void ro_gui_menu_prepare_window(void); static void ro_gui_menu_prepare_toolbars(void); static void ro_gui_menu_prepare_help(int forced); static void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning); -static struct box *ro_gui_menu_find_object_box(void); static void ro_gui_menu_object_reload(void); static void ro_gui_menu_browser_warning(wimp_message_menu_warning *warning); static void ro_gui_menu_hotlist_warning(wimp_message_menu_warning *warning); @@ -58,6 +57,9 @@ struct gui_window *current_gui; wimp_menu *current_menu; static int current_menu_x, current_menu_y; +/** Box for object under menu, or 0 if no object. */ +static struct box *gui_menu_object_box = 0; + /** Menu of options for form select controls. */ static wimp_menu *gui_form_select_menu = 0; /** Form control which gui_form_select_menu is for. */ @@ -477,21 +479,55 @@ void translate_menu(wimp_menu *menu) void ro_gui_create_menu(wimp_menu *menu, int x, int y, struct gui_window *g) { + int doc_x, doc_y; + wimp_window_state state; + os_error *error; + current_menu = menu; current_menu_x = x; current_menu_y = y; current_gui = g; + if (menu == browser_menu) { - if (!hotlist_window) browser_utilities_menu->entries[0].icon_flags |= wimp_ICON_SHADED; - if (ro_gui_menu_find_object_box()) + assert(g); + + state.w = g->window; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; + } + + doc_x = window_x_units(x, &state) / 2 / g->option.scale; + doc_y = -window_y_units(y, &state) / 2 / g->option.scale; + + gui_menu_object_box = 0; + if (g->bw->current_content && + g->bw->current_content->type == CONTENT_HTML) { + gui_menu_object_box = box_object_at_point( + g->bw->current_content, doc_x, doc_y); + } + + if (!hotlist_window) + browser_utilities_menu->entries[0].icon_flags |= + wimp_ICON_SHADED; + if (gui_menu_object_box) menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; else menu->entries[1].icon_flags |= wimp_ICON_SHADED; - } - if (menu == hotlist_menu) { + + } else if (menu == hotlist_menu) { ro_gui_menu_prepare_hotlist(); } - wimp_create_menu(menu, x, y); + + error = xwimp_create_menu(menu, x - 64, y); + if (error) { + LOG(("xwimp_create_menu: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("MenuError", error->errmess); + } } @@ -508,7 +544,8 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) icon_state.i = i; wimp_get_window_state(&state); wimp_get_icon_state(&icon_state); - ro_gui_create_menu(menu, state.visible.x0 + icon_state.icon.extent.x1, + ro_gui_create_menu(menu, + state.visible.x0 + icon_state.icon.extent.x1 + 64, state.visible.y1 + icon_state.icon.extent.y1, 0); } @@ -630,6 +667,8 @@ void ro_gui_menu_selection(wimp_selection *selection) } break; case MENU_OBJECT: + if (!gui_menu_object_box) + break; switch (selection->items[1]) { case 0: /* Info */ break; @@ -914,7 +953,7 @@ void ro_gui_menu_browser_warning(wimp_message_menu_warning *warning) /** \todo this is really dumb, the object should be the one * that the user clicked menu over, not the one that happens to * be under the menu now */ - box = ro_gui_menu_find_object_box(); + box = gui_menu_object_box; if (!box) break; @@ -1377,34 +1416,25 @@ void ro_gui_menu_prepare_pageinfo(void) ro_gui_set_icon_string(dialog_pageinfo, ICON_PAGEINFO_TYPE, mime); } + void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning) { - struct content *c = current_gui->bw->current_content; - struct box *box; - os_error *error; char icon_buf[20] = "file_xxx"; - const char *icon = icon_buf; const char *url = "-"; const char *target = "-"; const char *mime = "-"; + os_error *error; - box = ro_gui_menu_find_object_box(); - if (box) { - sprintf(icon_buf, "file_%x", ro_content_filetype(box->object)); - if (box->object->url) url = box->object->url; - if (box->href) target = box->href; - if (box->object->mime_type) mime = box->object->mime_type; - } - else if (c->type == CONTENT_JPEG || c->type == CONTENT_PNG || - c->type == CONTENT_JNG || c->type == CONTENT_MNG || - c->type == CONTENT_GIF || c->type == CONTENT_SPRITE || - c->type == CONTENT_DRAW) { - sprintf(icon_buf, "file_%x", ro_content_filetype(c)); - if (c->url) url = c->url; - if (c->mime_type) mime = c->mime_type; - } + sprintf(icon_buf, "file_%x", + ro_content_filetype(gui_menu_object_box->object)); + if (gui_menu_object_box->object->url) + url = gui_menu_object_box->object->url; + if (gui_menu_object_box->href) + target = gui_menu_object_box->href; + if (gui_menu_object_box->object->mime_type) + mime = gui_menu_object_box->object->mime_type; - ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON, icon); + ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_ICON, icon_buf); ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_URL, url); ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TARGET, target); ro_gui_set_icon_string(dialog_objinfo, ICON_OBJINFO_TYPE, mime); @@ -1412,56 +1442,17 @@ void ro_gui_menu_objectinfo(wimp_message_menu_warning *warning) error = xwimp_create_sub_menu((wimp_menu *) dialog_objinfo, warning->pos.x, warning->pos.y); if (error) { - LOG(("0x%x: %s\n", error->errnum, error->errmess)); + LOG(("xwimp_create_sub_menu: 0x%x: %s", + error->errnum, error->errmess)); warn_user("MenuError", error->errmess); } } -struct box *ro_gui_menu_find_object_box(void) -{ - struct content *c = current_gui->bw->current_content; - struct box_selection *boxes = NULL; - struct box *box = NULL; - int found = 0, plot_index = 0, i, x, y; - wimp_window_state state; - - state.w = current_gui->window; - wimp_get_window_state(&state); - - /* The menu is initially created 64 units to the left - * of the mouse position. Therefore, we negate the offset here - */ - x = window_x_units(current_menu_x+64, &state) / 2 / current_gui->option.scale; - y = -window_y_units(current_menu_y, &state) / 2 / current_gui->option.scale; - - if (c->type == CONTENT_HTML) { - - box_under_area(c, c->data.html.layout->children, - x, y, 0, 0, &boxes, &found, &plot_index); - - if (found > 0) { - for (i=found-1;i>=0;i--) { - if (boxes[i].box->object != 0) { - box = boxes[i].box; - break; - } - } - } - - free(boxes); - } - - return box; -} void ro_gui_menu_object_reload(void) { - struct box *box = ro_gui_menu_find_object_box(); - - if (box) { - box->object->fresh = false; - browser_window_reload(current_gui->bw, false); - } + gui_menu_object_box->object->fresh = false; + browser_window_reload(current_gui->bw, false); } @@ -1551,5 +1542,5 @@ void gui_create_form_select_menu(struct browser_window *bw, current_gui = bw->window; gui_form_select_control = control; ro_gui_create_menu(gui_form_select_menu, - pointer.pos.x - 64, pointer.pos.y, bw->window); + pointer.pos.x, pointer.pos.y, bw->window); } diff --git a/riscos/textselection.c b/riscos/textselection.c index 7129fd2ac..b2b69baff 100644 --- a/riscos/textselection.c +++ b/riscos/textselection.c @@ -50,13 +50,13 @@ void ro_gui_selection_drag_end(wimp_dragged *drag) msg.type = act_ALTER_SELECTION; browser_window_action(current_gui->bw, &msg);*/ - if (box_position_eq(&(current_gui->bw->current_content->data.html.text_selection.start), - &(current_gui->bw->current_content->data.html.text_selection.end))) +/* if (box_position_eq(&(current_gui->bw->current_content->data.html.text_selection.start), */ +/* &(current_gui->bw->current_content->data.html.text_selection.end))) */ { /* msg.type = act_CLEAR_SELECTION; browser_window_action(current_gui->bw, &msg);*/ } - current_gui->bw->current_content->data.html.text_selection.altering = alter_UNKNOWN; +/* current_gui->bw->current_content->data.html.text_selection.altering = alter_UNKNOWN; */ } diff --git a/riscos/window.c b/riscos/window.c index 01de4839d..45fcb5cf8 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -189,6 +189,8 @@ struct gui_window *gui_create_browser_window(struct browser_window *bw, g->prev = 0; g->next = window_list; + if (window_list) + window_list->prev = g; window_list = g; window_count++; @@ -1059,7 +1061,7 @@ void ro_gui_window_click(struct gui_window *g, wimp_pointer *pointer) } if (pointer->buttons == wimp_CLICK_MENU) - ro_gui_create_menu(browser_menu, pointer->pos.x - 64, + ro_gui_create_menu(browser_menu, pointer->pos.x, pointer->pos.y, g); else if (pointer->buttons == wimp_CLICK_SELECT) browser_window_mouse_click(g->bw, BROWSER_MOUSE_CLICK_1, x, y); @@ -1416,13 +1418,14 @@ int window_y_units(int y, wimp_window_state *state) { bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message) { - struct browser_window *bw = g->bw; - struct box_selection *click_boxes = 0; + int box_x = 0, box_y = 0; int x, y; - int i; - int found = 0; - int plot_index = 0; + struct box *box; + struct box *file_box = 0; + struct browser_window *bw = g->bw; + struct content *content; wimp_window_state state; + os_error *error; /* HTML content only. */ if (!bw->current_content || bw->current_content->type != CONTENT_HTML) @@ -1434,41 +1437,53 @@ bool ro_gui_window_dataload(struct gui_window *g, wimp_message *message) /* Search for a file input at the drop point. */ state.w = message->data.data_xfer.w; - wimp_get_window_state(&state); - x = window_x_units(message->data.data_xfer.pos.x, &state) / 2; - y = -window_y_units(message->data.data_xfer.pos.y, &state) / 2; - - box_under_area(bw->current_content, - bw->current_content->data.html.layout->children, - x, y, 0, 0, &click_boxes, &found, &plot_index); - if (found == 0) + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s\n", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); return false; - for (i = 0; i != found; i++) { - if (click_boxes[i].box->gadget && - click_boxes[i].box->gadget->type == - GADGET_FILE) - break; } - if (i == found) { - free(click_boxes); - return false; + + x = window_x_units(message->data.data_xfer.pos.x, &state) / 2 / + g->option.scale; + y = -window_y_units(message->data.data_xfer.pos.y, &state) / 2 / + g->option.scale; + + content = bw->current_content; + box = content->data.html.layout; + 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->gadget && box->gadget->type == GADGET_FILE) + file_box = box; } + if (!file_box) + return false; + /* Found: update form input. */ - free(click_boxes[i].box->gadget->value); - click_boxes[i].box->gadget->value = + free(file_box->gadget->value); + file_box->gadget->value = strdup(message->data.data_xfer.file_name); /* Redraw box. */ - box_coords(click_boxes[i].box, &x, &y); + box_coords(file_box, &x, &y); gui_window_redraw(bw->window, x, y, - x + click_boxes[i].box->width, - y + click_boxes[i].box->height); + x + file_box->width, + y + file_box->height); /* send DataLoadAck */ message->action = message_DATA_LOAD_ACK; message->your_ref = message->my_ref; - wimp_send_message(wimp_USER_MESSAGE, message, message->sender); + error = xwimp_send_message(wimp_USER_MESSAGE, message, message->sender); + if (error) { + LOG(("xwimp_send_message: 0x%x: %s\n", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + } return true; } -- cgit v1.2.3