From e44249f6edb3781ebc6816e79791ba266a568935 Mon Sep 17 00:00:00 2001 From: James Bursa Date: Wed, 25 Aug 2004 23:56:49 +0000 Subject: [PATCH] [project @ 2004-08-25 23:56:48 by bursa] Experimental overflow: scroll code. svn path=/import/netsurf/; revision=1250 --- desktop/browser.c | 61 +++++++++++++++++++++++++++++++++++++++++---- desktop/browser.h | 7 ++++++ render/box.c | 1 + render/box.h | 3 +++ riscos/htmlredraw.c | 13 ++++++---- riscos/window.c | 5 +++- 6 files changed, 79 insertions(+), 11 deletions(-) diff --git a/desktop/browser.c b/desktop/browser.c index fac897822..8ebb81bc5 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -100,6 +100,7 @@ void browser_window_create(const char *url, struct browser_window *clone) bw->throbbing = false; bw->caret_callback = NULL; bw->frag_id = NULL; + bw->scrolling_box = NULL; if ((bw->window = gui_create_browser_window(bw, clone)) == NULL) { free(bw); return; @@ -227,6 +228,7 @@ void browser_window_callback(content_msg msg, struct content *c, bw->current_content = c; bw->loading_content = NULL; bw->caret_callback = NULL; + bw->scrolling_box = NULL; gui_window_new_content(bw->window); gui_window_set_url(bw->window, c->url); browser_window_update(bw, true); @@ -254,8 +256,11 @@ void browser_window_callback(content_msg msg, struct content *c, warn_user(data.error, 0); if (c == bw->loading_content) bw->loading_content = 0; - else if (c == bw->current_content) + else if (c == bw->current_content) { bw->current_content = 0; + bw->caret_callback = NULL; + bw->scrolling_box = NULL; + } browser_window_stop_throbber(bw); break; @@ -287,8 +292,11 @@ void browser_window_callback(content_msg msg, struct content *c, gui_401login_open(bw, c, data.auth_realm); if (c == bw->loading_content) bw->loading_content = 0; - else if (c == bw->current_content) + else if (c == bw->current_content) { bw->current_content = 0; + bw->caret_callback = NULL; + bw->scrolling_box = NULL; + } browser_window_stop_throbber(bw); break; #endif @@ -596,16 +604,52 @@ void browser_window_mouse_click_html(struct browser_window *bw, gui_pointer_shape pointer = GUI_POINTER_DEFAULT; int box_x = 0, box_y = 0; int gadget_box_x = 0, gadget_box_y = 0; + int scroll_x, scroll_y; struct box *gadget_box = 0; struct content *c = bw->current_content; - struct box *box = c->data.html.layout; + struct box *box; struct content *content = c; struct content *gadget_content = c; struct form_control *gadget = 0; url_func_result res; - /* search the box tree for a link, imagemap, or form control */ - while ((box = box_at_point(box, x, y, &box_x, &box_y, &content)) != NULL) { + if (click == BROWSER_MOUSE_DRAG) { + /* scroll box with overflow: scroll */ + box = bw->scrolling_box; + if (!box) + return; + if (x == bw->scrolling_last_x && y == bw->scrolling_last_y) + return; + + scroll_x = box->scroll_x - (x - bw->scrolling_last_x); + scroll_y = box->scroll_y - (y - bw->scrolling_last_y); + bw->scrolling_last_x = x; + bw->scrolling_last_y = y; + + if (scroll_x < box->descendant_x0) + scroll_x = box->descendant_x0; + else if (box->descendant_x1 - box->width < scroll_x) + scroll_x = box->descendant_x1 - box->width; + if (scroll_y < box->descendant_y0) + scroll_y = box->descendant_y0; + else if (box->descendant_y1 - box->height < scroll_y) + scroll_y = box->descendant_y1 - box->height; + + if (scroll_x == box->scroll_x && scroll_y == box->scroll_y) + return; + box->scroll_x = scroll_x; + box->scroll_y = scroll_y; + + browser_redraw_box(bw->current_content, bw->scrolling_box); + return; + } + + bw->scrolling_box = NULL; + /* search the box tree for a link, imagemap, form control, or + * box with overflow: scroll */ + box = c->data.html.layout; + while ((box = box_at_point(box, x, y, &box_x, &box_y, &content)) != + NULL) { if (box->style && box->style->visibility == CSS_VISIBILITY_HIDDEN) continue; @@ -635,6 +679,13 @@ void browser_window_mouse_click_html(struct browser_window *bw, if (box->style && box->style->cursor != CSS_CURSOR_UNKNOWN) pointer = get_pointer_shape(box->style->cursor); + + if (box->type == BOX_BLOCK && box->style && + box->style->overflow == CSS_OVERFLOW_SCROLL) { + bw->scrolling_box = box; + bw->scrolling_last_x = x; + bw->scrolling_last_y = y; + } } if (gadget) { diff --git a/desktop/browser.h b/desktop/browser.h index 06a7e61a2..51db1c8c6 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -53,6 +53,12 @@ struct browser_window /** Fragment identifier for current_content */ char *frag_id; + + /** Box currently being scrolled, or 0. */ + struct box *scrolling_box; + /** Mouse position last scroll movement. */ + int scrolling_last_x; + int scrolling_last_y; }; @@ -60,6 +66,7 @@ typedef enum { BROWSER_MOUSE_CLICK_1, BROWSER_MOUSE_CLICK_2, BROWSER_MOUSE_HOVER, + BROWSER_MOUSE_DRAG, /**< CLICK is continuing as a drag. */ } browser_mouse_click; diff --git a/render/box.c b/render/box.c index 64b225bce..543d795c7 100644 --- a/render/box.c +++ b/render/box.c @@ -214,6 +214,7 @@ struct box * box_create(struct css_style * style, box->descendant_x1 = box->descendant_y1 = 0; for (i = 0; i != 4; i++) box->margin[i] = box->padding[i] = box->border[i] = 0; + box->scroll_x = box->scroll_y = 0; box->min_width = 0; box->max_width = UNKNOWN_MAX_WIDTH; box->text = NULL; diff --git a/render/box.h b/render/box.h index 8014b9856..c50c7ef00 100644 --- a/render/box.h +++ b/render/box.h @@ -155,6 +155,9 @@ struct box { int padding[4]; /**< Padding: TOP, RIGHT, BOTTOM, LEFT. */ int border[4]; /**< Border width: TOP, RIGHT, BOTTOM, LEFT. */ + int scroll_x; /**< Horizontal scroll of descendants. */ + int scroll_y; /**< Vertical scroll of descendants. */ + /**< Width of box taking all line breaks (including margins etc.). */ int min_width; int max_width; /**< Width that would be taken with no line breaks. */ diff --git a/riscos/htmlredraw.c b/riscos/htmlredraw.c index 23629529f..b9e47cd00 100644 --- a/riscos/htmlredraw.c +++ b/riscos/htmlredraw.c @@ -153,6 +153,7 @@ bool html_redraw_box(struct box *box, int padding_left, padding_top, padding_width, padding_height; int x0, y0, x1, y1; int colour; + int x_scrolled, y_scrolled; os_error *error; ro_gui_redraw_box_depth++; @@ -167,6 +168,8 @@ bool html_redraw_box(struct box *box, box->padding[RIGHT]) * 2 * scale; padding_height = (box->padding[TOP] + box->height + box->padding[BOTTOM]) * 2 * scale; + x_scrolled = x - box->scroll_x * 2 * scale; + y_scrolled = y + box->scroll_y * 2 * scale; /* calculate clip rectangle for this box */ if (box->style && box->style->overflow != CSS_OVERFLOW_VISIBLE) { @@ -184,7 +187,7 @@ bool html_redraw_box(struct box *box, /* if visibility is hidden render children only */ if (box->style && box->style->visibility == CSS_VISIBILITY_HIDDEN) { for (c = box->children; c; c = c->next) - if (!html_redraw_box(c, x, y, + if (!html_redraw_box(c, x_scrolled, y_scrolled, current_background_color, x0, y0, x1, y1, scale)) return false; @@ -537,14 +540,14 @@ bool html_redraw_box(struct box *box, } else { for (c = box->children; c != 0; c = c->next) if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT) - if (!html_redraw_box(c, x, - y, current_background_color, + if (!html_redraw_box(c, x_scrolled, y_scrolled, + current_background_color, x0, y0, x1, y1, scale)) return false; for (c = box->float_children; c != 0; c = c->next_float) - if (!html_redraw_box(c, x, - y, current_background_color, + if (!html_redraw_box(c, x_scrolled, y_scrolled, + current_background_color, x0, y0, x1, y1, scale)) return false; } diff --git a/riscos/window.c b/riscos/window.c index 25fe4cbc7..aec6bd8da 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -975,7 +975,10 @@ void ro_gui_window_mouse_at(struct gui_window *g, wimp_pointer *pointer) x = window_x_units(pointer->pos.x, &state) / 2 / g->option.scale; y = -window_y_units(pointer->pos.y, &state) / 2 / g->option.scale; - browser_window_mouse_click(g->bw, BROWSER_MOUSE_HOVER, x, y); + if (pointer->buttons) + browser_window_mouse_click(g->bw, BROWSER_MOUSE_DRAG, x, y); + else + browser_window_mouse_click(g->bw, BROWSER_MOUSE_HOVER, x, y); }