Confine box_at_point to the document it's given. Callers are now responsible for calling whatever functionality for object boxes. Remove last bw dereference from render directory. Remove a couple of unused functions.

This commit is contained in:
Michael Drake 2012-08-21 15:27:52 +01:00
parent 7ffe9c2b5d
commit afdf72d7b5
6 changed files with 59 additions and 119 deletions

View File

@ -350,7 +350,6 @@ void box_bounds(struct box *box, struct rect *r)
* to position of returned box, if any
* \param box_y position of box, in global document coordinates, updated
* to position of returned box, if any
* \param content updated to content of object that returned box is in, if any
* \return box at given point, or 0 if none found
*
* To find all the boxes in the hierarchy at a certain point, use code like
@ -358,17 +357,15 @@ void box_bounds(struct box *box, struct rect *r)
* \code
* struct box *box = top_of_document_to_search;
* int box_x = 0, box_y = 0;
* struct content *content = document_to_search;
*
* while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
* while ((box = box_at_point(box, x, y, &box_x, &box_y))) {
* // process box
* }
* \endcode
*/
struct box *box_at_point(struct box *box, const int x, const int y,
int *box_x, int *box_y,
hlcache_handle **content)
int *box_x, int *box_y)
{
int bx = *box_x, by = *box_y;
struct box *child, *sibling;
@ -376,21 +373,7 @@ struct box *box_at_point(struct box *box, const int x, const int y,
assert(box);
/* drill into HTML objects */
if (box->object != NULL) {
struct box *layout;
if (content_get_type(box->object) == CONTENT_HTML &&
(layout = html_get_box_tree(box->object)) !=
NULL) {
*content = box->object;
box = layout;
} else {
goto siblings;
}
}
/* consider floats second, since they will often overlap other boxes */
/* consider floats first, since they will often overlap other boxes */
for (child = box->float_children; child; child = child->next_float) {
if (box_contains_point(child, x - bx, y - by, &physically)) {
*box_x = bx + child->x -
@ -401,8 +384,7 @@ struct box *box_at_point(struct box *box, const int x, const int y,
if (physically)
return child;
else
return box_at_point(child, x, y, box_x, box_y,
content);
return box_at_point(child, x, y, box_x, box_y);
}
}
@ -420,8 +402,7 @@ non_float_children:
if (physically)
return child;
else
return box_at_point(child, x, y, box_x, box_y,
content);
return box_at_point(child, x, y, box_x, box_y);
}
}
@ -435,7 +416,6 @@ non_float_children:
}
}
siblings:
/* siblings and siblings of ancestors */
while (box) {
if (box_is_float(box)) {
@ -457,8 +437,7 @@ siblings:
else
return box_at_point(sibling,
x, y,
box_x, box_y,
content);
box_x, box_y);
}
}
/* ascend to float's parent */
@ -489,8 +468,7 @@ siblings:
else
return box_at_point(sibling,
x, y,
box_x, box_y,
content);
box_x, box_y);
}
}
box = box->parent;
@ -559,66 +537,6 @@ bool box_contains_point(struct box *box, int x, int y, bool *physically)
}
/**
* Find the box containing an object at the given coordinates, if any.
*
* \param h 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(hlcache_handle *h, int x, int y)
{
struct box *box;
int box_x = 0, box_y = 0;
hlcache_handle *content = h;
struct box *object_box = 0;
box = html_get_box_tree(h);
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
if (box->style && css_computed_visibility(box->style) ==
CSS_VISIBILITY_HIDDEN)
continue;
if (box->object)
object_box = box;
}
return object_box;
}
/**
* Find the box containing an href at the given coordinates, if any.
*
* \param h content to search, must have type CONTENT_HTML
* \param x coordinates in document units
* \param y coordinates in document units
*/
struct box *box_href_at_point(hlcache_handle *h, int x, int y)
{
struct box *box;
int box_x = 0, box_y = 0;
hlcache_handle *content = h;
struct box *href_box = 0;
box = html_get_box_tree(h);
while ((box = box_at_point(box, x, y, &box_x, &box_y, &content))) {
if (box->style && css_computed_visibility(box->style) ==
CSS_VISIBILITY_HIDDEN)
continue;
if (box->href)
href_box = box;
}
return href_box;
}
/**
* Check whether box is nearer mouse coordinates than current nearest box
*

View File

@ -324,9 +324,7 @@ void box_free_box(struct box *box);
void box_bounds(struct box *box, struct rect *r);
void box_coords(struct box *box, int *x, int *y);
struct box *box_at_point(struct box *box, const int x, const int y,
int *box_x, int *box_y, struct hlcache_handle **content);
struct box *box_object_at_point(struct hlcache_handle *h, int x, int y);
struct box *box_href_at_point(struct hlcache_handle *h, int x, int y);
int *box_x, int *box_y);
struct box *box_pick_text_box(struct html_content *html,
int x, int y, int dir, int *dx, int *dy);
struct box *box_find_by_id(struct box *box, lwc_string *id);

View File

@ -1423,12 +1423,12 @@ void form_select_menu_callback(void *client_data,
* \param radio form control of type GADGET_RADIO
*/
void form_radio_set(hlcache_handle *content,
void form_radio_set(html_content *html,
struct form_control *radio)
{
struct form_control *control;
assert(content);
assert(html);
assert(radio);
if (!radio->form)
return;
@ -1447,12 +1447,12 @@ void form_radio_set(hlcache_handle *content,
if (control->selected) {
control->selected = false;
html_redraw_a_box(content, control->box);
html__redraw_a_box(html, control->box);
}
}
radio->selected = true;
html_redraw_a_box(content, radio->box);
html__redraw_a_box(html, radio->box);
}

View File

@ -33,6 +33,7 @@ struct box;
struct form_control;
struct form_option;
struct form_select_menu;
struct html_content;
/** Form submit method. */
typedef enum {
@ -175,6 +176,6 @@ void form_select_process_selection(hlcache_handle *h,
struct form_control *control, int item);
void form_submit(nsurl *page_url, struct browser_window *target,
struct form *form, struct form_control *submit_button);
void form_radio_set(struct hlcache_handle *content, struct form_control *radio);
void form_radio_set(struct html_content *html, struct form_control *radio);
#endif

View File

@ -2644,10 +2644,8 @@ html_get_contextual_content(struct content *c,
struct box *box = html->layout;
struct box *next;
int box_x = 0, box_y = 0;
hlcache_handle *containing_content = NULL;
while ((next = box_at_point(box, x, y, &box_x, &box_y,
&containing_content)) != NULL) {
while ((next = box_at_point(box, x, y, &box_x, &box_y)) != NULL) {
box = next;
if (box->style && css_computed_visibility(box->style) ==
@ -2658,6 +2656,10 @@ html_get_contextual_content(struct content *c,
browser_window_get_contextual_content(box->iframe,
x - box_x, y - box_y, data);
if (box->object)
content_get_contextual_content(box->object,
x - box_x, y - box_y, data);
if (box->object)
data->object = box->object;
@ -2709,13 +2711,11 @@ html_scroll_at_point(struct content *c, int x, int y, int scrx, int scry)
struct box *box = html->layout;
struct box *next;
int box_x = 0, box_y = 0;
hlcache_handle *containing_content = NULL;
bool handled_scroll = false;
/* TODO: invert order; visit deepest box first */
while ((next = box_at_point(box, x, y, &box_x, &box_y,
&containing_content)) != NULL) {
while ((next = box_at_point(box, x, y, &box_x, &box_y)) != NULL) {
box = next;
if (box->style && css_computed_visibility(box->style) ==
@ -2727,6 +2727,12 @@ html_scroll_at_point(struct content *c, int x, int y, int scrx, int scry)
x - box_x, y - box_y, scrx, scry) == true)
return true;
/* Pass into object */
if (box->object != NULL && content_scroll_at_point(
box->object, x - box_x, y - box_y,
scrx, scry) == true)
return true;
/* Handle box scrollbars */
if (box->scroll_y && scrollbar_scroll(box->scroll_y, scry))
handled_scroll = true;
@ -2761,11 +2767,9 @@ static bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
struct box *file_box = NULL;
struct box *text_box = NULL;
int box_x = 0, box_y = 0;
hlcache_handle *containing_content = NULL;
/* Scan box tree for boxes that can handle drop */
while ((next = box_at_point(box, x, y, &box_x, &box_y,
&containing_content)) != NULL) {
while ((next = box_at_point(box, x, y, &box_x, &box_y)) != NULL) {
box = next;
if (box->style && css_computed_visibility(box->style) ==
@ -2776,6 +2780,10 @@ static bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
return browser_window_drop_file_at_point(box->iframe,
x - box_x, y - box_y, file);
if (box->object && content_drop_file_at_point(box->object,
x - box_x, y - box_y, file) == true)
return true;
if (box->gadget) {
switch (box->gadget->type) {
case GADGET_FILE:
@ -2823,10 +2831,7 @@ static bool html_drop_file_at_point(struct content *c, int x, int y, char *file)
file_box->gadget->value = utf8_fn;
/* Redraw box. */
if (containing_content == NULL)
html__redraw_a_box(html, file_box);
else
html_redraw_a_box(containing_content, file_box);
html__redraw_a_box(html, file_box);
} else if (html->bw != NULL) {
/* File dropped on text input */

View File

@ -309,12 +309,10 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
struct box *url_box = 0;
struct box *gadget_box = 0;
struct box *text_box = 0;
hlcache_handle *h = bw->current_content;
struct box *box;
hlcache_handle *content = h;
hlcache_handle *gadget_content = h;
struct form_control *gadget = 0;
hlcache_handle *object = NULL;
hlcache_handle *html_object = NULL;
struct browser_window *iframe = NULL;
struct box *next_box;
struct box *drag_candidate = NULL;
@ -398,7 +396,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
box_x = box->margin[LEFT];
box_y = box->margin[TOP];
while ((next_box = box_at_point(box, x, y, &box_x, &box_y, &content)) !=
while ((next_box = box_at_point(box, x, y, &box_x, &box_y)) !=
NULL) {
box = next_box;
@ -406,8 +404,12 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
CSS_VISIBILITY_HIDDEN)
continue;
if (box->object)
object = box->object;
if (box->object) {
if (content_get_type(box->object) == CONTENT_HTML)
html_object = box->object;
else
object = box->object;
}
if (box->iframe)
iframe = box->iframe;
@ -428,7 +430,6 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
}
if (box->gadget) {
gadget_content = content;
gadget = box->gadget;
gadget_box = box;
gadget_box_x = box_x;
@ -516,13 +517,13 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
status = messages_get("FormCheckbox");
if (mouse & BROWSER_MOUSE_CLICK_1) {
gadget->selected = !gadget->selected;
html_redraw_a_box(gadget_content, gadget_box);
html__redraw_a_box(html, gadget_box);
}
break;
case GADGET_RADIO:
status = messages_get("FormRadio");
if (mouse & BROWSER_MOUSE_CLICK_1)
form_radio_set(gadget_content, gadget);
form_radio_set(html, gadget);
break;
case GADGET_IMAGE:
if (mouse & BROWSER_MOUSE_CLICK_1) {
@ -680,6 +681,23 @@ void html_mouse_action(struct content *c, struct browser_window *bw,
browser_window_mouse_track(iframe, mouse,
x - pos_x, y - pos_y);
}
} else if (html_object) {
int pos_x, pos_y;
float scale = browser_window_get_scale(bw);
browser_window_get_position(iframe, false, &pos_x, &pos_y);
pos_x /= scale;
pos_y /= scale;
if (mouse & BROWSER_MOUSE_CLICK_1 ||
mouse & BROWSER_MOUSE_CLICK_2) {
content_mouse_action(html_object, bw, mouse,
x - pos_x, y - pos_y);
} else {
content_mouse_track(html_object, bw, mouse,
x - pos_x, y - pos_y);
}
} else if (url) {
if (title) {
snprintf(status_buffer, sizeof status_buffer, "%s: %s",