From ac447fc293d791bf3155903d7755768f7a2b48ee Mon Sep 17 00:00:00 2001 From: Michael Drake Date: Mon, 9 May 2011 22:49:17 +0000 Subject: s/scroll/scrollbar/ and improve scrollbar widget comments. svn path=/trunk/netsurf/; revision=12363 --- Makefile.sources | 2 +- desktop/browser.c | 8 +- desktop/browser.h | 4 +- desktop/scroll.c | 805 -------------------------------------------- desktop/scroll.h | 89 ----- desktop/scrollbar.c | 826 ++++++++++++++++++++++++++++++++++++++++++++++ desktop/scrollbar.h | 95 ++++++ desktop/textinput.c | 67 ++-- render/box.c | 66 ++-- render/box.h | 4 +- render/form.c | 48 +-- render/html.h | 6 +- render/html_interaction.c | 86 ++--- render/html_internal.h | 2 +- render/html_redraw.c | 22 +- render/layout.c | 2 +- 16 files changed, 1082 insertions(+), 1050 deletions(-) delete mode 100644 desktop/scroll.c delete mode 100644 desktop/scroll.h create mode 100644 desktop/scrollbar.c create mode 100644 desktop/scrollbar.h diff --git a/Makefile.sources b/Makefile.sources index a221b7002..f090bde4f 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -20,7 +20,7 @@ S_UTILS := base64.c filename.c hashtable.c http.c locale.c messages.c \ S_DESKTOP := cookies.c history_global_core.c hotlist.c knockout.c \ mouse.c options.c plot_style.c print.c search.c searchweb.c \ - scroll.c sslcert.c textarea.c thumbnail.c tree.c \ + scrollbar.c sslcert.c textarea.c thumbnail.c tree.c \ tree_url_node.c version.c # S_COMMON are sources common to all builds diff --git a/desktop/browser.c b/desktop/browser.c index e538e87f3..a7126a64b 100644 --- a/desktop/browser.c +++ b/desktop/browser.c @@ -539,7 +539,7 @@ nserror browser_window_callback(hlcache_handle *c, browser_window_remove_caret(bw); - bw->scroll = NULL; + bw->scrollbar = NULL; gui_window_new_content(bw->window); @@ -618,7 +618,7 @@ nserror browser_window_callback(hlcache_handle *c, else if (c == bw->current_content) { bw->current_content = NULL; browser_window_remove_caret(bw); - bw->scroll = NULL; + bw->scrollbar = NULL; selection_init(bw->sel, NULL); } @@ -1509,8 +1509,8 @@ void browser_window_mouse_drag_end(struct browser_window *bw, return; } - if (bw->scroll != NULL) { - html_overflow_scroll_drag_end(bw->scroll, mouse, x, y); + if (bw->scrollbar != NULL) { + html_overflow_scroll_drag_end(bw->scrollbar, mouse, x, y); return; } diff --git a/desktop/browser.h b/desktop/browser.h index a9cba2ee7..b8961447e 100644 --- a/desktop/browser.h +++ b/desktop/browser.h @@ -111,7 +111,7 @@ struct browser_window { /** Scroll capturing all mouse events, updated to any active HTML * scrollbar, or NULL when no scrollbar drags active */ - struct scroll *scroll; + struct scrollbar *scrollbar; /** Current fetch is download */ bool download; @@ -184,7 +184,7 @@ struct browser_window { int status_miss; /**< Number of times status was really updated. */ }; -struct browser_scroll_data { +struct browser_scrollbar_data { struct browser_window *bw; struct box *box; }; diff --git a/desktop/scroll.c b/desktop/scroll.c deleted file mode 100644 index a5d9b24f4..000000000 --- a/desktop/scroll.c +++ /dev/null @@ -1,805 +0,0 @@ -/* - * Copyright 2004-2008 James Bursa - * Copyright 2008 Michael Drake - * Copyright 2009 Paul Blokus - * - * 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 . - */ - -/** \file - * Scroll widget (implementation). - */ - -#include -#include - -#include "desktop/mouse.h" -#include "desktop/scroll.h" -#include "desktop/plotters.h" -#include "desktop/plot_style.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/utils.h" - - -struct scroll { - bool horizontal; /* Horizontal scroll if true, vertical if false - */ - int length; /* Length of the scroll widget */ - - int scrolled_d; /* The dimension of the scrolled area */ - int scrolled_vis; /* The visible part of the scrolled area */ - - int area_scroll; /* Scroll value of the scrolled area */ - int bar_off; /* Offset of the scrollbar */ - int bar_len; /* Length of the scrollbar */ - - scroll_client_callback client_callback; /* Callback receiving scroll - events */ - void *client_data; /* User data passed to the callback */ - - bool dragging; /* Flag indicating drag at progess */ - int drag_start_coord; /* Coordinate value at drag start */ - int drag_start_bar_off; /* Scrollbar offset at drag start */ - bool reverse; /* Flag indicating that the scroll should move - * in the opposite direction than the mouse does - */ - - struct scroll *pair; /* Parpendicular scroll */ - bool pair_drag; /* Flag indicating that the current drag affects - also the pair scroll */ -}; - - -/** Overflow scrollbar colours - * - * Overflow scrollbar colours can be set by front end code to try to match - * scrollbar colours used on the desktop. - * - * If a front end doesn't set scrollbar colours, these defaults are used. - */ -colour scroll_widget_fg_colour = 0x00d9d9d9; /* light grey */ -colour scroll_widget_bg_colour = 0x006b6b6b; /* mid grey */ -colour scroll_widget_arrow_colour = 0x00444444; /* dark grey */ - - -/** - * Create a scroll. - * - * \param horizontal true for a horizontal scrollbar false for a - * vertical one - * \param length full length of the scroll widget - * \param scrolled_dimension full length of the scrolled area - * \param scrolled_visible length of the visible part of the scrolled area - * \param client_data data for the client callback - * \param client_callback client callback for scroll events - * \param scroll_pt gets updated to point at the newly created - * scroll - * \return true if the scroll has been created succesfully - * or false on memory exhaustion - */ - -bool scroll_create(bool horizontal, int length, - int scrolled_dimension, int scrolled_visible, - void *client_data, scroll_client_callback client_callback, - struct scroll **scroll_pt) -{ - struct scroll *scroll; - int well_length; - - scroll = malloc(sizeof(struct scroll)); - if (scroll == NULL) { - LOG(("malloc failed")); - warn_user("NoMemory", 0); - *scroll_pt = NULL; - return false; - } - - scroll->horizontal = horizontal; - scroll->length = length; - scroll->scrolled_d = scrolled_dimension; - scroll->scrolled_vis = scrolled_visible; - scroll->area_scroll = 0; - scroll->bar_off = 0; - scroll->reverse = false; - scroll->pair = NULL; - scroll->pair_drag = false; - - well_length = length - 2 * SCROLLBAR_WIDTH; - scroll->bar_len = (well_length * scrolled_visible) / scrolled_dimension; - - scroll->client_callback = client_callback; - scroll->client_data = client_data; - - scroll->dragging = false; - - *scroll_pt = scroll; - - return true; -} - - -/** - * Destroy a scroll. - * - * \param scroll the scroll to be destroyed - */ - -void scroll_destroy(struct scroll *scroll) -{ - if (scroll->pair != NULL) - scroll->pair->pair = NULL; - free(scroll); -} - - -/** - * Draw an outline rectangle common to a few of scroll elements. - * - * \param x0 left border of the outline - * \param y0 top border of the outline - * \param x1 right border of the outline - * \param y1 bottom border of the outline - * \param c base colour of the outline, the other colours are created by - * lightening or darkening this one - * \param inset true for inset outline, false for an outset one - * \return - */ - -static inline bool scroll_redraw_scrollbar_rectangle( - int x0, int y0, int x1, int y1, colour c, bool inset) -{ - static plot_style_t c0 = { - .stroke_type = PLOT_OP_TYPE_SOLID, - .stroke_width = 1, - }; - - static plot_style_t c1 = { - .stroke_type = PLOT_OP_TYPE_SOLID, - .stroke_width = 1, - }; - - static plot_style_t c2 = { - .stroke_type = PLOT_OP_TYPE_SOLID, - .stroke_width = 1, - }; - - if (inset) { - c0.stroke_colour = darken_colour(c); - c1.stroke_colour = lighten_colour(c); - } else { - c0.stroke_colour = lighten_colour(c); - c1.stroke_colour = darken_colour(c); - } - c2.stroke_colour = blend_colour(c0.stroke_colour, c1.stroke_colour); - - if (!plot.line(x0, y0, x1, y0, &c0)) return false; - if (!plot.line(x1, y0, x1, y1 + 1, &c1)) return false; - if (!plot.line(x1, y0, x1, y0 + 1, &c2)) return false; - if (!plot.line(x1, y1, x0, y1, &c1)) return false; - if (!plot.line(x0, y1, x0, y0, &c0)) return false; - if (!plot.line(x0, y1, x0, y1 + 1, &c2)) return false; - return true; -} - - -/** - * Redraw a part of the scroll. - * - * \param scroll the scroll to be redrawn - * \param x the X coordinate to draw the scroll at - * \param y the Y coordinate to draw the scroll at - * \param clip the clipping rectangle - * \param scale scale for the redraw - * \return true on succes false otherwise - */ - -bool scroll_redraw(struct scroll *scroll, int x, int y, - const struct rect *clip, float scale) -{ - int w = SCROLLBAR_WIDTH; - int well_length, bar_off, bar_c0, bar_c1; - int v[6]; /* array of triangle vertices */ - int x0, y0, x1, y1; - plot_style_t pstyle_scroll_widget_bg_colour = { - .fill_type = PLOT_OP_TYPE_SOLID, - .fill_colour = scroll_widget_bg_colour, - }; - plot_style_t pstyle_scroll_widget_fg_colour = { - .fill_type = PLOT_OP_TYPE_SOLID, - .fill_colour = scroll_widget_fg_colour, - }; - plot_style_t pstyle_scroll_widget_arrow_colour = { - .fill_type = PLOT_OP_TYPE_SOLID, - .fill_colour = scroll_widget_arrow_colour, - }; - - well_length = scroll->length - 2 * SCROLLBAR_WIDTH; - x0 = x; - y0 = y; - x1 = x + (scroll->horizontal ? - scroll->length : SCROLLBAR_WIDTH) - 1; - y1 = y + (scroll->horizontal ? SCROLLBAR_WIDTH : scroll->length) - 1; - bar_off = scroll->bar_off; - bar_c1 = (scroll->horizontal ? x0 : y0) + SCROLLBAR_WIDTH + - scroll->bar_off + scroll->bar_len - 1; - - if (scale != 1.0) { - w *= scale; - well_length *= scale; - x0 *= scale; - y0 *= scale; - x1 *= scale; - y1 *= scale; - bar_off *= scale; - bar_c1 *= scale; - } - - bar_c0 = (scroll->horizontal ? x0 : y0) + w + bar_off; - - if (x1 < clip->x0 || y1 < clip->y0 || clip->x1 < x0 || clip->y1 < y0) - /* scrollbar is outside the clipping rectangle, nothing to - * render */ - return true; - - - if (scroll->horizontal) { - /* scroll is horizontal */ - - /* scrollbar outline */ - if (!scroll_redraw_scrollbar_rectangle(x0, y0, x1, y1, - scroll_widget_bg_colour, true)) - return false; - /* left arrow icon border */ - if (!scroll_redraw_scrollbar_rectangle(x0 + 1, - y0 + 1, - x0 + w - 2, - y1 - 1, - scroll_widget_fg_colour, false)) - return false; - /* left arrow icon background */ - if (!plot.rectangle(x0 + 2, - y0 + 2, - x0 + w - 2, - y1 - 1, - &pstyle_scroll_widget_fg_colour)) - return false; - /* left arrow */ - v[0] = x0 + w / 4; - v[1] = y0 + w / 2; - v[2] = x0 + w * 3 / 4; - v[3] = y0 + w / 4; - v[4] = x0 + w * 3 / 4; - v[5] = y0 + w * 3 / 4; - if (!plot.polygon(v, 3, &pstyle_scroll_widget_arrow_colour)) - return false; - /* scroll well background */ - if (!plot.rectangle(x0 + w - 1, - y0 + 1, - x1 - w + 2, - y1, - &pstyle_scroll_widget_bg_colour)) - return false; - /* scroll position indicator bar */ - if (!scroll_redraw_scrollbar_rectangle(bar_c0, - y0 + 1, - bar_c1, - y1 - 1, - scroll_widget_fg_colour, false)) - return false; - if (!plot.rectangle(bar_c0 + 1, - y0 + 2, - bar_c1, - y1 - 1, - &pstyle_scroll_widget_fg_colour)) - return false; - /* right arrow icon border */ - if (!scroll_redraw_scrollbar_rectangle(x1 - w + 2, - y0 + 1, - x1 - 1, - y1 - 1, - scroll_widget_fg_colour, false)) - return false; - /* right arrow icon background */ - if (!plot.rectangle(x1 - w + 3, - y0 + 2, - x1 - 1, - y1 - 1, - &pstyle_scroll_widget_fg_colour)) - return false; - /* right arrow */ - v[0] = x1 - w / 4 + 1; - v[1] = y0 + w / 2; - v[2] = x1 - w * 3 / 4 + 1; - v[3] = y0 + w / 4; - v[4] = x1 - w * 3 / 4 + 1; - v[5] = y0 + w * 3 / 4; - if (!plot.polygon(v, 3, &pstyle_scroll_widget_arrow_colour)) - return false; - } else { - /* scroll is vertical */ - - /* outline */ - if (!scroll_redraw_scrollbar_rectangle(x0, y0, x1, y1, - scroll_widget_bg_colour, - true)) - return false; - /* top arrow background */ - if (!scroll_redraw_scrollbar_rectangle(x0 + 1, - y0 + 1, - x1 - 1, - y0 + w - 2, - scroll_widget_fg_colour, - false)) - return false; - if (!plot.rectangle(x0 + 2, - y0 + 2, - x1 - 1, - y0 + w - 2, - &pstyle_scroll_widget_fg_colour)) - return false; - /* up arrow */ - v[0] = x0 + w / 2; - v[1] = y0 + w / 4; - v[2] = x0 + w / 4; - v[3] = y0 + w * 3 / 4; - v[4] = x0 + w * 3 / 4; - v[5] = y0 + w * 3 / 4; - if (!plot.polygon(v, 3, &pstyle_scroll_widget_arrow_colour)) - return false; - /* scroll well background */ - if (!plot.rectangle(x0 + 1, - y0 + w - 1, - x1, - y1 - w + 2, - &pstyle_scroll_widget_bg_colour)) - return false; - /* scroll position indicator bar */ - if (!scroll_redraw_scrollbar_rectangle(x0 + 1, - bar_c0, - x1 - 1, - bar_c1, - scroll_widget_fg_colour, false)) - return false; - if (!plot.rectangle(x0 + 2, - bar_c0 + 1, - x1 - 1, - bar_c1, - &pstyle_scroll_widget_fg_colour)) - return false; - /* bottom arrow background */ - if (!scroll_redraw_scrollbar_rectangle(x0 + 1, - y1 - w + 2, - x1 - 1, - y1 - 1, - scroll_widget_fg_colour, false)) - return false; - if (!plot.rectangle(x0 + 2, - y1 - w + 3, - x1 - 1, - y1 - 1, - &pstyle_scroll_widget_fg_colour)) - return false; - /* down arrow */ - v[0] = x0 + w / 2; - v[1] = y1 - w / 4 + 1; - v[2] = x0 + w / 4; - v[3] = y1 - w * 3 / 4 + 1; - v[4] = x0 + w * 3 / 4; - v[5] = y1 - w * 3 / 4 + 1; - if (!plot.polygon(v, 3, &pstyle_scroll_widget_arrow_colour)) - return false; - } - - return true; -} - - -/** - * Set the value of the scroll. - * - * \param scroll the scroll to have the value set - * \param scroll_val the new value to be set - * \param bar true if the value is for the scroll indication bar - * offset, false if it is for the scrolled area one - */ - -void scroll_set(struct scroll *scroll, int scroll_val, bool bar) -{ - int well_length; - struct scroll_msg_data msg; - - if (scroll_val < 0) - scroll_val = 0; - - if (scroll->scrolled_d == scroll->scrolled_vis) - return; - - well_length = scroll->length - 2 * SCROLLBAR_WIDTH; - if (bar) { - if (scroll_val > well_length - scroll->bar_len) - scroll->bar_off = well_length - scroll->bar_len; - else - scroll->bar_off = scroll_val; - - scroll->area_scroll = ((scroll->scrolled_d - - scroll->scrolled_vis) * (scroll->bar_off)) / - (well_length - scroll->bar_len); - - } else { - if (scroll_val > scroll->scrolled_d - scroll->scrolled_vis) - scroll->area_scroll = scroll->scrolled_d - - scroll->scrolled_vis; - else - scroll->area_scroll = scroll_val; - - scroll->bar_off = (well_length * scroll->area_scroll) / - scroll->scrolled_d; - } - - msg.scroll = scroll; - msg.msg = SCROLL_MSG_MOVED; - msg.new_scroll = scroll->area_scroll; - scroll->client_callback(scroll->client_data, &msg); - - msg.msg = SCROLL_MSG_REDRAW; - msg.x0 = scroll->horizontal ? SCROLLBAR_WIDTH - 1: 0; - msg.y0 = scroll->horizontal ? 0 : SCROLLBAR_WIDTH - 1; - msg.x1 = (scroll->horizontal ? - scroll->length - SCROLLBAR_WIDTH + 1: SCROLLBAR_WIDTH); - msg.y1 = (scroll->horizontal ? - SCROLLBAR_WIDTH : scroll->length - SCROLLBAR_WIDTH + 1); - scroll->client_callback(scroll->client_data, &msg); -} - - -/** - * Get the scroll offset for the visible part of the scrolled area. - * - * \param scroll the scroll to get the value from - * \return scroll offset for the scrolled area - */ - -int scroll_get_offset(struct scroll *scroll) -{ - if (scroll == NULL) - return 0; - return scroll->area_scroll; -} - - -/** - * Set the length of the scroll and the visible or scrolled part of the scrolled - * area. - * - * \param scroll the scroll to set the values for - * \param length -1 or the new scroll length to be set - * \param scrolled_visible -1 or the new value of the visible part of the - * scrolled area to be set - * \param scrolled_dimension -1 or the new dimension of the scrolled content - */ - -void scroll_set_extents(struct scroll *scroll, int length, - int scrolled_visible, int scrolled_dimension) -{ - int well_length; - - if (length != -1) - scroll->length = length; - if (scrolled_visible != -1) - scroll->scrolled_vis = scrolled_visible; - if (scrolled_dimension != -1) - scroll->scrolled_d = scrolled_dimension; - - well_length = length - 2 * SCROLLBAR_WIDTH; - - scroll->bar_len = (well_length * scrolled_visible) / - scroll->scrolled_d; - scroll->bar_off = (well_length * scroll->area_scroll) / - scroll->scrolled_d; -} - - -/** - * Check the orientation of the scroll. - * - * \param scroll the scroll to check the orientation of - * \return true for a horizontal scroll, false for a vertical one - */ - -bool scroll_is_horizontal(struct scroll *scroll) -{ - return scroll->horizontal; -} - - -/** - * Internal procedure used for staring a drag scroll for a scrollbar. - * - * \param scroll the scroll to start the drag for - * \param x the X coordinate of the drag start - * \param y the Y coordinate of the drag start - * \param reverse whether this should be a reverse drag(used when the user - * drags the content and the scrolls have to adjust) - * \param pair whether the drag should start for the pair scroll too - */ - -static void scroll_drag_start_internal(struct scroll *scroll, int x, int y, - bool reverse, bool pair) -{ - struct scroll_msg_data msg; - - scroll->drag_start_coord = scroll->horizontal ? x : y; - scroll->drag_start_bar_off = scroll->bar_off; - - scroll->dragging = true; - scroll->reverse = reverse; - - msg.scroll = scroll; - - /* \todo - some proper numbers please! */ - if (scroll->horizontal) { - msg.x0 = -1024; - msg.x1 = 1024; - msg.y0 = 0; - msg.y1 = 0; - } else { - msg.x0 = 0; - msg.x1 = 0; - msg.y0 = -1024; - msg.y1 = 1024; - } - - if (pair && scroll->pair != NULL) { - scroll->pair_drag = true; - - scroll->pair->drag_start_coord = - scroll->pair->horizontal ? x : y; - - scroll->pair->drag_start_bar_off = scroll->pair->bar_off; - - scroll->pair->dragging = true; - scroll->pair->reverse = reverse; - - if (scroll->pair->horizontal) { - msg.x0 = -1024; - msg.x1 = 1024; - } else { - msg.y0 = -1024; - msg.y1 = 1024; - } - } - msg.msg = SCROLL_MSG_SCROLL_START; - scroll->client_callback(scroll->client_data, &msg); -} - - -/** - * Handle mouse actions other then drag ends. - * - * \param scroll the scroll which gets the mouse action - * \param mouse mouse state - * \param x X coordinate of the mouse - * \param y Y coordinate of the mouse - * \return message for the status bar or NULL on failure - */ - -const char *scroll_mouse_action(struct scroll *scroll, - browser_mouse_state mouse, int x, int y) -{ - int x0, y0, x1, y1; - int val; - const char *status; - bool h; - /* we want mouse presses and mouse drags that were not started at - * the scroll indication bar to be launching actions on the scroll area - */ - bool but1 = ((mouse & BROWSER_MOUSE_PRESS_1) || - ((mouse & BROWSER_MOUSE_HOLDING_1) && - (mouse & BROWSER_MOUSE_DRAG_ON) && - !scroll->dragging)); - bool but2 = ((mouse & BROWSER_MOUSE_PRESS_2) || - ((mouse & BROWSER_MOUSE_HOLDING_2) && - (mouse & BROWSER_MOUSE_DRAG_ON) && - !scroll->dragging)); - - h = scroll->horizontal; - - x0 = 0; - y0 = 0; - x1 = h ? scroll->length : SCROLLBAR_WIDTH; - y1 = h ? SCROLLBAR_WIDTH : scroll->length; - - if (!scroll->dragging && !(x >= x0 && x <= x1 && y >= y0 && y <= y1)) { - /* Not a drag and mouse outside scroll widget */ - return NULL; - } - - - if (h) - val = x; - else - val = y; - - if (scroll->dragging) { - val -= scroll->drag_start_coord; - if (scroll->reverse) - val = -val; - if (val != 0) - scroll_set(scroll, scroll->drag_start_bar_off + val, - true); - if (scroll->pair_drag) { - scroll_mouse_action(scroll->pair, mouse, x, y); - status = messages_get("ScrollBoth"); - } else - status = messages_get(h ? "ScrollH" : "ScrollV"); - - return status; - } - - if (val < SCROLLBAR_WIDTH) { - /* left/up arrow */ - - status = messages_get(h ? "ScrollLeft" : "ScrollUp"); - if (but1) - scroll_set(scroll, scroll->bar_off - SCROLLBAR_WIDTH, - true); - else if (but2) - scroll_set(scroll, scroll->bar_off + SCROLLBAR_WIDTH, - true); - - } else if (val < SCROLLBAR_WIDTH + scroll->bar_off) { - /* well between left/up arrow and bar */ - - status = messages_get(h ? "ScrollPLeft" : "ScrollPUp"); - - if (but1) - scroll_set(scroll, scroll->area_scroll - scroll->length, - false); - else if (but2) - scroll_set(scroll, scroll->area_scroll + scroll->length, - false); - - } else if (val > scroll->length - SCROLLBAR_WIDTH) { - /* right/down arrow */ - - status = messages_get(h ? "ScrollRight" : "ScrollDown"); - - if (but1) - scroll_set(scroll, scroll->bar_off + SCROLLBAR_WIDTH, - true); - else if (but2) - scroll_set(scroll, scroll->bar_off - SCROLLBAR_WIDTH, - true); - - } else if (val > SCROLLBAR_WIDTH + scroll->bar_off + scroll->bar_len) { - /* well between right/down arrow and bar */ - - status = messages_get(h ? "ScrollPRight" : "ScrollPDown"); - if (but1) - scroll_set(scroll, scroll->area_scroll + scroll->length, - false); - else if (but2) - scroll_set(scroll, scroll->area_scroll - scroll->length, - false); - } - else { - /* scroll indication bar */ - - status = messages_get(h ? "ScrollH" : "ScrollV"); - } - - - if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2) && - (val >= SCROLLBAR_WIDTH + scroll->bar_off - && val < SCROLLBAR_WIDTH + scroll->bar_off + - scroll->bar_len)) - /* The mouse event is a drag start and takes place at the scroll - * indication bar. - */ - scroll_drag_start_internal(scroll, x, y, false, - (mouse & BROWSER_MOUSE_DRAG_2) ? - true : false); - - return status; -} - - -/** - * Handle end of mouse drags. - * - * \param scroll the scroll for which the drag ends - * \param mouse mouse state - * \param x X coordinate of the mouse - * \param y Y coordinate of the mouse - */ - -void scroll_mouse_drag_end(struct scroll *scroll, browser_mouse_state mouse, - int x, int y) -{ - struct scroll_msg_data msg; - int val; - - assert(scroll->dragging); - - val = (scroll->horizontal ? x : y) - scroll->drag_start_coord; - if (scroll->reverse) - val = -val; - if (val != 0) - scroll_set(scroll, scroll->drag_start_bar_off + val, true); - - scroll->dragging = false; - scroll->reverse = false; - if (scroll->pair_drag) { - scroll->pair_drag = false; - - val = (scroll->pair->horizontal ? x : y) - - scroll->pair->drag_start_coord; - if (scroll->pair->reverse) - val = -val; - if (val != 0) - scroll_set(scroll->pair, - scroll->pair->drag_start_bar_off + val, - true); - - scroll->pair->dragging = false; - scroll->pair->reverse = false; - } - msg.scroll = scroll; - msg.msg = SCROLL_MSG_SCROLL_FINISHED; - scroll->client_callback(scroll->client_data, &msg); -} - - -/** - * Called when the content, which is scrolled with some scrolls, is being - * dragged so the scrolls have to adjust properly. If the content has both - * scrolls and scroll_make_pair has beed called before only the one scroll which - * will receive further mouse events has to be passed. - * - * \param scroll one of the the scrolls owned by the dragged content - * \param x X coordinate of mouse during drag start - * \param y Y coordinate of mouse during drag start - */ - -void scroll_start_content_drag(struct scroll *scroll, int x, int y) -{ - scroll_drag_start_internal(scroll, x, y, true, true); -} - - -/** - * Connect a horizontal and a vertical scroll into a pair so that they - * co-operate during 2D drags. - * - * \param horizontal_scroll the scroll used for horizontal scrolling - * \param vertical_scroll the scroll used for vertical scrolling - */ - -void scroll_make_pair(struct scroll *horizontal_scroll, - struct scroll *vertical_scroll) -{ - assert(horizontal_scroll->horizontal && !vertical_scroll->horizontal); - - horizontal_scroll->pair = vertical_scroll; - vertical_scroll->pair = horizontal_scroll; -} - - -void *scroll_get_data(struct scroll *scroll) -{ - return scroll->client_data; -} - diff --git a/desktop/scroll.h b/desktop/scroll.h deleted file mode 100644 index e34ebba6b..000000000 --- a/desktop/scroll.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2009 Paul Blokus - * - * 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 . - */ - -/** \file - * Scroll widget (interface). - */ - -#ifndef _NETSURF_DESKTOP_SCROLL_H_ -#define _NETSURF_DESKTOP_SCROLL_H_ - -#include - -#include "desktop/browser.h" - -#define SCROLLBAR_WIDTH 16 - -struct scroll; - -typedef enum { - SCROLL_MSG_REDRAW, /* the scrollbar requests a redraw */ - SCROLL_MSG_MOVED, /* the scroll value has changed */ - SCROLL_MSG_SCROLL_START, /* a scroll drag has started, all mouse - * events should be passed to - * the scrollbar regardless of the - * coordinates - */ - SCROLL_MSG_SCROLL_FINISHED, /* cancel the above */ - -} scroll_msg; - -struct scroll_msg_data { - struct scroll *scroll; - scroll_msg msg; - int new_scroll; - int x0, y0, x1, y1; -}; - -/** - * Client callback for the scroll. - * - * \param client_data user data passed at scroll creation - * \param scroll_data struct all necessary message data - */ -typedef void(*scroll_client_callback)(void *client_data, - struct scroll_msg_data *scroll_data); - -bool scroll_create(bool horizontal, int length, - int scrolled_dimension, int scrolled_visible, - void *client_data, scroll_client_callback client_callback, - struct scroll **scroll_pt); -void scroll_destroy(struct scroll *scroll); -bool scroll_redraw(struct scroll *scroll, int x, int y, - const struct rect *clip, float scale); - -void scroll_set(struct scroll *scroll, int scroll_val, bool bar); -int scroll_get_offset(struct scroll *scroll); - -void scroll_set_extents(struct scroll *scroll, int length, - int scrolled_visible, int scrolled_dimension); - -bool scroll_is_horizontal(struct scroll *scroll); - -const char *scroll_mouse_action(struct scroll *scroll, - browser_mouse_state mouse, int x, int y); -void scroll_mouse_drag_end(struct scroll *scroll, browser_mouse_state mouse, - int x, int y); -void scroll_start_content_drag(struct scroll *scroll, int x, int y); - -void scroll_make_pair(struct scroll *horizontal_scroll, - struct scroll *vertical_scroll); - -void *scroll_get_data(struct scroll *scroll); - -#endif diff --git a/desktop/scrollbar.c b/desktop/scrollbar.c new file mode 100644 index 000000000..2dfe0c9ef --- /dev/null +++ b/desktop/scrollbar.c @@ -0,0 +1,826 @@ +/* + * Copyright 2004-2008 James Bursa + * Copyright 2008 Michael Drake + * Copyright 2009 Paul Blokus + * + * 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 . + */ + +/** \file + * Scrollbar widget (implementation). + */ + +#include +#include + +#include "desktop/mouse.h" +#include "desktop/scrollbar.h" +#include "desktop/plotters.h" +#include "desktop/plot_style.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" + + +struct scrollbar { + bool horizontal; /* Horizontal scrollbar if true, else vertical + */ + int length; /* Length of the scrollbar widget */ + + int scrolled_d; /* The dimension of the scrolled area */ + int scrolled_vis; /* The visible part of the scrolled area */ + + int area_scroll; /* Scroll value of the scrolled area */ + int bar_off; /* Offset of the scrollbar */ + int bar_len; /* Length of the scrollbar */ + + scrollbar_client_callback client_callback; /* Callback receiving + * scrollbar events */ + void *client_data; /* User data passed to the callback */ + + bool dragging; /* Flag indicating drag at progess */ + int drag_start_coord; /* Coordinate value at drag start */ + int drag_start_bar_off; /* Scrollbar offset at drag start */ + bool reverse; /* Flag indicating that the scrollbar moves + * in the opposite direction to the mouse + */ + + struct scrollbar *pair; /* Parpendicular scrollbar, or NULL */ + bool pair_drag; /* Flag indicating that the current drag affects + the perpendicular scrollbar too */ +}; + + +/** Overflow scrollbar colours + * + * Overflow scrollbar colours can be set by front end code to try to match + * scrollbar colours used on the desktop. + * + * If a front end doesn't set scrollbar colours, these defaults are used. + */ +colour scrollbar_widget_fg_colour = 0x00d9d9d9; /* light grey */ +colour scrollbar_widget_bg_colour = 0x006b6b6b; /* mid grey */ +colour scrollbar_widget_arrow_colour = 0x00444444; /* dark grey */ + + +/** + * Create a scrollbar. + * + * \param horizontal true for a horizontal scrollbar false for a + * vertical one + * \param length full length of the scrollbar widget + * \param scrolled_dimension full length of the scrolled area + * \param scrolled_visible length of the visible part of the scrolled area + * \param client_data data for the client callback + * \param client_callback client callback for scrollbar events + * \param scrollbar gets updated to point at the newly created + * scrollbar + * \return true if scrollbar has been created succesfully + * or false on memory exhaustion + */ + +bool scrollbar_create(bool horizontal, int length, + int scrolled_dimension, int scrolled_visible, + void *client_data, scrollbar_client_callback client_callback, + struct scrollbar **scrollbar_pt) +{ + struct scrollbar *scrollbar; + int well_length; + + scrollbar = malloc(sizeof(struct scrollbar)); + if (scrollbar == NULL) { + LOG(("malloc failed")); + warn_user("NoMemory", 0); + *scrollbar_pt = NULL; + return false; + } + + scrollbar->horizontal = horizontal; + scrollbar->length = length; + scrollbar->scrolled_d = scrolled_dimension; + scrollbar->scrolled_vis = scrolled_visible; + scrollbar->area_scroll = 0; + scrollbar->bar_off = 0; + scrollbar->reverse = false; + scrollbar->pair = NULL; + scrollbar->pair_drag = false; + + well_length = length - 2 * SCROLLBAR_WIDTH; + scrollbar->bar_len = (well_length * scrolled_visible) / + scrolled_dimension; + + scrollbar->client_callback = client_callback; + scrollbar->client_data = client_data; + + scrollbar->dragging = false; + + *scrollbar_pt = scrollbar; + + return true; +} + + +/** + * Destroy a scrollbar. + * + * \param scrollbar the scrollbar to be destroyed + */ + +void scrollbar_destroy(struct scrollbar *scrollbar) +{ + if (scrollbar->pair != NULL) + scrollbar->pair->pair = NULL; + free(scrollbar); +} + + +/** + * Draw an outline rectangle common to a several scrollbar elements. + * + * \param x0 left border of the outline + * \param y0 top border of the outline + * \param x1 right border of the outline + * \param y1 bottom border of the outline + * \param c base colour of the outline, the other colours are created by + * lightening or darkening this one + * \param inset true for inset outline, false for an outset one + * \return + */ + +static inline bool scrollbar_redraw_scrollbar_rectangle(int x0, int y0, + int x1, int y1, colour c, bool inset) +{ + static plot_style_t c0 = { + .stroke_type = PLOT_OP_TYPE_SOLID, + .stroke_width = 1, + }; + + static plot_style_t c1 = { + .stroke_type = PLOT_OP_TYPE_SOLID, + .stroke_width = 1, + }; + + static plot_style_t c2 = { + .stroke_type = PLOT_OP_TYPE_SOLID, + .stroke_width = 1, + }; + + if (inset) { + c0.stroke_colour = darken_colour(c); + c1.stroke_colour = lighten_colour(c); + } else { + c0.stroke_colour = lighten_colour(c); + c1.stroke_colour = darken_colour(c); + } + c2.stroke_colour = blend_colour(c0.stroke_colour, c1.stroke_colour); + + /* Plot the outline */ + if (!plot.line(x0, y0, x1, y0, &c0)) return false; + if (!plot.line(x1, y0, x1, y1 + 1, &c1)) return false; + if (!plot.line(x1, y0, x1, y0 + 1, &c2)) return false; + if (!plot.line(x1, y1, x0, y1, &c1)) return false; + if (!plot.line(x0, y1, x0, y0, &c0)) return false; + if (!plot.line(x0, y1, x0, y1 + 1, &c2)) return false; + + return true; +} + + +/** + * Redraw a part of the scrollbar. + * + * \param scrollbar the scrollbar to be redrawn + * \param x the X coordinate to draw the scrollbar at + * \param y the Y coordinate to draw the scrollbar at + * \param clip the clipping rectangle + * \param scale scale for the redraw + * \return true on succes false otherwise + */ + +bool scrollbar_redraw(struct scrollbar *scrollbar, int x, int y, + const struct rect *clip, float scale) +{ + int w = SCROLLBAR_WIDTH; + int well_length, bar_off, bar_c0, bar_c1; + int v[6]; /* array of triangle vertices */ + int x0, y0, x1, y1; + + plot_style_t pstyle_scrollbar_widget_bg_colour = { + .fill_type = PLOT_OP_TYPE_SOLID, + .fill_colour = scrollbar_widget_bg_colour, + }; + plot_style_t pstyle_scrollbar_widget_fg_colour = { + .fill_type = PLOT_OP_TYPE_SOLID, + .fill_colour = scrollbar_widget_fg_colour, + }; + plot_style_t pstyle_scrollbar_widget_arrow_colour = { + .fill_type = PLOT_OP_TYPE_SOLID, + .fill_colour = scrollbar_widget_arrow_colour, + }; + + well_length = scrollbar->length - 2 * SCROLLBAR_WIDTH; + x0 = x; + y0 = y; + x1 = x + (scrollbar->horizontal ? + scrollbar->length : SCROLLBAR_WIDTH) - 1; + y1 = y + (scrollbar->horizontal ? + SCROLLBAR_WIDTH : scrollbar->length) - 1; + bar_off = scrollbar->bar_off; + bar_c1 = (scrollbar->horizontal ? x0 : y0) + SCROLLBAR_WIDTH + + scrollbar->bar_off + scrollbar->bar_len - 1; + + if (scale != 1.0) { + w *= scale; + well_length *= scale; + x0 *= scale; + y0 *= scale; + x1 *= scale; + y1 *= scale; + bar_off *= scale; + bar_c1 *= scale; + } + + bar_c0 = (scrollbar->horizontal ? x0 : y0) + w + bar_off; + + if (x1 < clip->x0 || y1 < clip->y0 || clip->x1 < x0 || clip->y1 < y0) + /* scrollbar is outside the clipping rectangle, nothing to + * render */ + return true; + + + if (scrollbar->horizontal) { + /* scrollbar is horizontal */ + + /* scrollbar outline */ + if (!scrollbar_redraw_scrollbar_rectangle(x0, y0, x1, y1, + scrollbar_widget_bg_colour, true)) + return false; + /* left arrow icon border */ + if (!scrollbar_redraw_scrollbar_rectangle(x0 + 1, + y0 + 1, + x0 + w - 2, + y1 - 1, + scrollbar_widget_fg_colour, false)) + return false; + /* left arrow icon background */ + if (!plot.rectangle(x0 + 2, + y0 + 2, + x0 + w - 2, + y1 - 1, + &pstyle_scrollbar_widget_fg_colour)) + return false; + /* left arrow */ + v[0] = x0 + w / 4; + v[1] = y0 + w / 2; + v[2] = x0 + w * 3 / 4; + v[3] = y0 + w / 4; + v[4] = x0 + w * 3 / 4; + v[5] = y0 + w * 3 / 4; + if (!plot.polygon(v, 3, &pstyle_scrollbar_widget_arrow_colour)) + return false; + /* scrollbar well background */ + if (!plot.rectangle(x0 + w - 1, + y0 + 1, + x1 - w + 2, + y1, + &pstyle_scrollbar_widget_bg_colour)) + return false; + /* scrollbar position indicator bar */ + if (!scrollbar_redraw_scrollbar_rectangle(bar_c0, + y0 + 1, + bar_c1, + y1 - 1, + scrollbar_widget_fg_colour, false)) + return false; + if (!plot.rectangle(bar_c0 + 1, + y0 + 2, + bar_c1, + y1 - 1, + &pstyle_scrollbar_widget_fg_colour)) + return false; + /* right arrow icon border */ + if (!scrollbar_redraw_scrollbar_rectangle(x1 - w + 2, + y0 + 1, + x1 - 1, + y1 - 1, + scrollbar_widget_fg_colour, false)) + return false; + /* right arrow icon background */ + if (!plot.rectangle(x1 - w + 3, + y0 + 2, + x1 - 1, + y1 - 1, + &pstyle_scrollbar_widget_fg_colour)) + return false; + /* right arrow */ + v[0] = x1 - w / 4 + 1; + v[1] = y0 + w / 2; + v[2] = x1 - w * 3 / 4 + 1; + v[3] = y0 + w / 4; + v[4] = x1 - w * 3 / 4 + 1; + v[5] = y0 + w * 3 / 4; + if (!plot.polygon(v, 3, &pstyle_scrollbar_widget_arrow_colour)) + return false; + } else { + /* scrollbar is vertical */ + + /* outline */ + if (!scrollbar_redraw_scrollbar_rectangle(x0, y0, x1, y1, + scrollbar_widget_bg_colour, + true)) + return false; + /* top arrow background */ + if (!scrollbar_redraw_scrollbar_rectangle(x0 + 1, + y0 + 1, + x1 - 1, + y0 + w - 2, + scrollbar_widget_fg_colour, + false)) + return false; + if (!plot.rectangle(x0 + 2, + y0 + 2, + x1 - 1, + y0 + w - 2, + &pstyle_scrollbar_widget_fg_colour)) + return false; + /* up arrow */ + v[0] = x0 + w / 2; + v[1] = y0 + w / 4; + v[2] = x0 + w / 4; + v[3] = y0 + w * 3 / 4; + v[4] = x0 + w * 3 / 4; + v[5] = y0 + w * 3 / 4; + if (!plot.polygon(v, 3, &pstyle_scrollbar_widget_arrow_colour)) + return false; + /* scrollbar well background */ + if (!plot.rectangle(x0 + 1, + y0 + w - 1, + x1, + y1 - w + 2, + &pstyle_scrollbar_widget_bg_colour)) + return false; + /* scrollbar position indicator bar */ + if (!scrollbar_redraw_scrollbar_rectangle(x0 + 1, + bar_c0, + x1 - 1, + bar_c1, + scrollbar_widget_fg_colour, false)) + return false; + if (!plot.rectangle(x0 + 2, + bar_c0 + 1, + x1 - 1, + bar_c1, + &pstyle_scrollbar_widget_fg_colour)) + return false; + /* bottom arrow background */ + if (!scrollbar_redraw_scrollbar_rectangle(x0 + 1, + y1 - w + 2, + x1 - 1, + y1 - 1, + scrollbar_widget_fg_colour, false)) + return false; + if (!plot.rectangle(x0 + 2, + y1 - w + 3, + x1 - 1, + y1 - 1, + &pstyle_scrollbar_widget_fg_colour)) + return false; + /* down arrow */ + v[0] = x0 + w / 2; + v[1] = y1 - w / 4 + 1; + v[2] = x0 + w / 4; + v[3] = y1 - w * 3 / 4 + 1; + v[4] = x0 + w * 3 / 4; + v[5] = y1 - w * 3 / 4 + 1; + if (!plot.polygon(v, 3, &pstyle_scrollbar_widget_arrow_colour)) + return false; + } + + return true; +} + + +/** + * Set the value of the scrollbar. + * + * \param scrollbar the scrollbar to have the value set + * \param scroll_val the new value to be set + * \param bar_pos true if the value is for the scrollbar indication bar + * offset, false if it is for the scrolled area one + */ + +void scrollbar_set(struct scrollbar *scrollbar, int scroll_val, bool bar_pos) +{ + int well_length; + struct scrollbar_msg_data msg; + + if (scroll_val < 0) + scroll_val = 0; + + if (scrollbar->scrolled_d == scrollbar->scrolled_vis) + return; + + well_length = scrollbar->length - 2 * SCROLLBAR_WIDTH; + if (bar_pos) { + if (scroll_val > well_length - scrollbar->bar_len) + scrollbar->bar_off = well_length - scrollbar->bar_len; + else + scrollbar->bar_off = scroll_val; + + scrollbar->area_scroll = ((scrollbar->scrolled_d - + scrollbar->scrolled_vis) * + (scrollbar->bar_off)) / + (well_length - scrollbar->bar_len); + + } else { + if (scroll_val > scrollbar->scrolled_d - + scrollbar->scrolled_vis) + scrollbar->area_scroll = scrollbar->scrolled_d - + scrollbar->scrolled_vis; + else + scrollbar->area_scroll = scroll_val; + + scrollbar->bar_off = (well_length * scrollbar->area_scroll) / + scrollbar->scrolled_d; + } + + msg.scrollbar = scrollbar; + msg.msg = SCROLLBAR_MSG_MOVED; + msg.new_scroll = scrollbar->area_scroll; + scrollbar->client_callback(scrollbar->client_data, &msg); + + msg.msg = SCROLLBAR_MSG_REDRAW; + msg.x0 = scrollbar->horizontal ? SCROLLBAR_WIDTH - 1 : 0; + msg.y0 = scrollbar->horizontal ? 0 : SCROLLBAR_WIDTH - 1; + msg.x1 = (scrollbar->horizontal ? + scrollbar->length - SCROLLBAR_WIDTH + 1 : + SCROLLBAR_WIDTH); + msg.y1 = (scrollbar->horizontal ? + SCROLLBAR_WIDTH : + scrollbar->length - SCROLLBAR_WIDTH + 1); + + scrollbar->client_callback(scrollbar->client_data, &msg); +} + + +/** + * Get the scroll offset for the visible part of the scrolled area. + * + * \param scrollbar the scrollbar to get the scroll offset value from + * \return scroll offset for the scrolled area + */ + +int scrollbar_get_offset(struct scrollbar *scrollbar) +{ + if (scrollbar == NULL) + return 0; + return scrollbar->area_scroll; +} + + +/** + * Set the length of the scrollbar and the visible or scrolled part of the + * scrolled area. + * + * \param scrollbar the scrollbar to set the values for + * \param length -1 or the new scrollbar length to be set + * \param scrolled_visible -1 or the new value of the visible part of the + * scrolled area to be set + * \param scrolled_dimension -1 or the new dimension of the scrolled content + */ + +void scrollbar_set_extents(struct scrollbar *scrollbar, int length, + int scrolled_visible, int scrolled_dimension) +{ + int well_length; + + if (length != -1) + scrollbar->length = length; + if (scrolled_visible != -1) + scrollbar->scrolled_vis = scrolled_visible; + if (scrolled_dimension != -1) + scrollbar->scrolled_d = scrolled_dimension; + + well_length = length - 2 * SCROLLBAR_WIDTH; + + scrollbar->bar_len = (well_length * scrolled_visible) / + scrollbar->scrolled_d; + scrollbar->bar_off = (well_length * scrollbar->area_scroll) / + scrollbar->scrolled_d; +} + + +/** + * Check the orientation of the scrollbar. + * + * \param scrollbar the scrollbar to check the orientation of + * \return true for a horizontal scrollbar, else false (vertical + */ + +bool scrollbar_is_horizontal(struct scrollbar *scrollbar) +{ + return scrollbar->horizontal; +} + + +/** + * Internal procedure used for starting a drag scroll for a scrollbar. + * + * \param scrollbar the scrollbar to start the drag for + * \param x the X coordinate of the drag start + * \param y the Y coordinate of the drag start + * \param reverse whether this should be a reverse drag (used when the + * user drags the content area, rather than the scrollbar) + * \param pair whether the drag is a '2D' scroll + */ + +static void scrollbar_drag_start_internal(struct scrollbar *scrollbar, + int x, int y, bool reverse, bool pair) +{ + struct scrollbar_msg_data msg; + + scrollbar->drag_start_coord = scrollbar->horizontal ? x : y; + scrollbar->drag_start_bar_off = scrollbar->bar_off; + + scrollbar->dragging = true; + scrollbar->reverse = reverse; + + msg.scrollbar = scrollbar; + + /* \todo - some proper numbers please! */ + if (scrollbar->horizontal) { + msg.x0 = -1024; + msg.x1 = 1024; + msg.y0 = 0; + msg.y1 = 0; + } else { + msg.x0 = 0; + msg.x1 = 0; + msg.y0 = -1024; + msg.y1 = 1024; + } + + if (pair && scrollbar->pair != NULL) { + scrollbar->pair_drag = true; + + scrollbar->pair->drag_start_coord = + scrollbar->pair->horizontal ? x : y; + + scrollbar->pair->drag_start_bar_off = scrollbar->pair->bar_off; + + scrollbar->pair->dragging = true; + scrollbar->pair->reverse = reverse; + + if (scrollbar->pair->horizontal) { + msg.x0 = -1024; + msg.x1 = 1024; + } else { + msg.y0 = -1024; + msg.y1 = 1024; + } + } + msg.msg = SCROLLBAR_MSG_SCROLL_START; + scrollbar->client_callback(scrollbar->client_data, &msg); +} + + +/** + * Handle mouse actions other then drag ends. + * + * \param scrollbar the scrollbar which gets the mouse action + * \param mouse mouse state + * \param x X coordinate of the mouse + * \param y Y coordinate of the mouse + * \return message for the status bar or NULL on failure + */ + +const char *scrollbar_mouse_action(struct scrollbar *scrollbar, + browser_mouse_state mouse, int x, int y) +{ + int x0, y0, x1, y1; + int val; + const char *status; + bool h; + + /* we want mouse presses and mouse drags that were not started at the + * scrollbar indication bar to be launching actions on the scroll area + */ + bool but1 = ((mouse & BROWSER_MOUSE_PRESS_1) || + ((mouse & BROWSER_MOUSE_HOLDING_1) && + (mouse & BROWSER_MOUSE_DRAG_ON) && + !scrollbar->dragging)); + bool but2 = ((mouse & BROWSER_MOUSE_PRESS_2) || + ((mouse & BROWSER_MOUSE_HOLDING_2) && + (mouse & BROWSER_MOUSE_DRAG_ON) && + !scrollbar->dragging)); + + h = scrollbar->horizontal; + + x0 = 0; + y0 = 0; + x1 = h ? scrollbar->length : SCROLLBAR_WIDTH; + y1 = h ? SCROLLBAR_WIDTH : scrollbar->length; + + if (!scrollbar->dragging && + !(x >= x0 && x <= x1 && y >= y0 && y <= y1)) { + /* Not a drag and mouse outside scrollbar widget */ + return NULL; + } + + + if (h) + val = x; + else + val = y; + + if (scrollbar->dragging) { + val -= scrollbar->drag_start_coord; + if (scrollbar->reverse) + val = -val; + if (val != 0) + scrollbar_set(scrollbar, + scrollbar->drag_start_bar_off + val, + true); + if (scrollbar->pair_drag) { + scrollbar_mouse_action(scrollbar->pair, mouse, x, y); + status = messages_get("ScrollBoth"); + } else + status = messages_get(h ? "ScrollH" : "ScrollV"); + + return status; + } + + if (val < SCROLLBAR_WIDTH) { + /* left/up arrow */ + + status = messages_get(h ? "ScrollLeft" : "ScrollUp"); + if (but1) + scrollbar_set(scrollbar, + scrollbar->bar_off - SCROLLBAR_WIDTH, + true); + else if (but2) + scrollbar_set(scrollbar, + scrollbar->bar_off + SCROLLBAR_WIDTH, + true); + + } else if (val < SCROLLBAR_WIDTH + scrollbar->bar_off) { + /* well between left/up arrow and bar */ + + status = messages_get(h ? "ScrollPLeft" : "ScrollPUp"); + + if (but1) + scrollbar_set(scrollbar, + scrollbar->area_scroll - scrollbar->length, + false); + else if (but2) + scrollbar_set(scrollbar, + scrollbar->area_scroll + scrollbar->length, + false); + + } else if (val > scrollbar->length - SCROLLBAR_WIDTH) { + /* right/down arrow */ + + status = messages_get(h ? "ScrollRight" : "ScrollDown"); + + if (but1) + scrollbar_set(scrollbar, + scrollbar->bar_off + SCROLLBAR_WIDTH, + true); + else if (but2) + scrollbar_set(scrollbar, + scrollbar->bar_off - SCROLLBAR_WIDTH, + true); + + } else if (val > SCROLLBAR_WIDTH + scrollbar->bar_off + scrollbar->bar_len) { + /* well between right/down arrow and bar */ + + status = messages_get(h ? "ScrollPRight" : "ScrollPDown"); + if (but1) + scrollbar_set(scrollbar, + scrollbar->area_scroll + scrollbar->length, + false); + else if (but2) + scrollbar_set(scrollbar, + scrollbar->area_scroll - scrollbar->length, + false); + } + else { + /* scrollbar position indication bar */ + + status = messages_get(h ? "ScrollH" : "ScrollV"); + } + + + if (mouse & (BROWSER_MOUSE_DRAG_1 | BROWSER_MOUSE_DRAG_2) && + (val >= SCROLLBAR_WIDTH + scrollbar->bar_off + && val < SCROLLBAR_WIDTH + scrollbar->bar_off + + scrollbar->bar_len)) + /* The mouse event is a drag start on the scrollbar position + * indication bar. */ + scrollbar_drag_start_internal(scrollbar, x, y, false, + (mouse & BROWSER_MOUSE_DRAG_2) ? true : false); + + return status; +} + + +/** + * Handle end of mouse drags. + * + * \param scrollbar the scrollbar for which the drag ends + * \param mouse mouse state + * \param x X coordinate of the mouse + * \param y Y coordinate of the mouse + */ + +void scrollbar_mouse_drag_end(struct scrollbar *scrollbar, + browser_mouse_state mouse, int x, int y) +{ + struct scrollbar_msg_data msg; + int val; + + assert(scrollbar->dragging); + + val = (scrollbar->horizontal ? x : y) - scrollbar->drag_start_coord; + if (scrollbar->reverse) + val = -val; + if (val != 0) + scrollbar_set(scrollbar, scrollbar->drag_start_bar_off + val, + true); + + scrollbar->dragging = false; + scrollbar->reverse = false; + if (scrollbar->pair_drag) { + scrollbar->pair_drag = false; + + val = (scrollbar->pair->horizontal ? x : y) - + scrollbar->pair->drag_start_coord; + if (scrollbar->pair->reverse) + val = -val; + if (val != 0) + scrollbar_set(scrollbar->pair, + scrollbar->pair->drag_start_bar_off + val, + true); + + scrollbar->pair->dragging = false; + scrollbar->pair->reverse = false; + } + msg.scrollbar = scrollbar; + msg.msg = SCROLLBAR_MSG_SCROLL_FINISHED; + scrollbar->client_callback(scrollbar->client_data, &msg); +} + + +/** + * Called when the content is being dragged to the scrollbars have to adjust. + * If the content has both scrollbars, and scrollbar_make_pair has beed called + * before, only the one scroll which will receive further mouse events has to be + * passed. + * + * \param scrollbar one of the the scrollbars owned by the dragged content + * \param x X coordinate of mouse during drag start + * \param y Y coordinate of mouse during drag start + */ + +void scrollbar_start_content_drag(struct scrollbar *scrollbar, int x, int y) +{ + scrollbar_drag_start_internal(scrollbar, x, y, true, true); +} + + +/** + * Connect a horizontal and a vertical scrollbar into a pair so that they + * co-operate during 2D drags. + * + * \param horizontal_scrollbar the scrollbar used for horizontal scrolling + * \param vertical_scrollbar the scrollbar used for vertical scrolling + */ + +void scrollbar_make_pair(struct scrollbar *horizontal_scrollbar, + struct scrollbar *vertical_scrollbar) +{ + assert(horizontal_scrollbar->horizontal && + !vertical_scrollbar->horizontal); + + horizontal_scrollbar->pair = vertical_scrollbar; + vertical_scrollbar->pair = horizontal_scrollbar; +} + + +void *scrollbar_get_data(struct scrollbar *scrollbar) +{ + return scrollbar->client_data; +} + diff --git a/desktop/scrollbar.h b/desktop/scrollbar.h new file mode 100644 index 000000000..d211339b8 --- /dev/null +++ b/desktop/scrollbar.h @@ -0,0 +1,95 @@ +/* + * Copyright 2009 Paul Blokus + * + * 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 . + */ + +/** \file + * Scrollbar widget (interface). + */ + +#ifndef _NETSURF_DESKTOP_SCROLLBAR_H_ +#define _NETSURF_DESKTOP_SCROLLBAR_H_ + +#include + +#include "desktop/browser.h" + +#define SCROLLBAR_WIDTH 16 + +struct scrollbar; + +typedef enum { + SCROLLBAR_MSG_REDRAW, /* the scrollbar requests a redraw */ + SCROLLBAR_MSG_MOVED, /* the scroll value has changed */ + SCROLLBAR_MSG_SCROLL_START, /* a scrollbar drag has started, all + * mouse events should be passed to + * the scrollbar regardless of the + * coordinates + */ + SCROLLBAR_MSG_SCROLL_FINISHED, /* cancel the above */ + +} scrollbar_msg; + +struct scrollbar_msg_data { + struct scrollbar *scrollbar; + scrollbar_msg msg; + int new_scroll; + int x0, y0, x1, y1; +}; + +/** + * Client callback for the scrollbar. + * + * \param client_data user data passed at scroll creation + * \param scrollbar_data struct all necessary message data + */ +typedef void(*scrollbar_client_callback)(void *client_data, + struct scrollbar_msg_data *scrollbar_data); + + +bool scrollbar_create(bool horizontal, int length, + int scrolled_dimension, int scrolled_visible, + void *client_data, scrollbar_client_callback client_callback, + struct scrollbar **scrollbar); + +void scrollbar_destroy(struct scrollbar *scrollbar); + +bool scrollbar_redraw(struct scrollbar *scrollbar, int x, int y, + const struct rect *clip, float scale); + +void scrollbar_set(struct scrollbar *scrollbar, int scrollbar_val, bool bar); + +int scrollbar_get_offset(struct scrollbar *scrollbar); + +void scrollbar_set_extents(struct scrollbar *scrollbar, int length, + int scrolled_visible, int scrolled_dimension); + +bool scrollbar_is_horizontal(struct scrollbar *scrollbar); + +const char *scrollbar_mouse_action(struct scrollbar *scrollbar, + browser_mouse_state mouse, int x, int y); + +void scrollbar_mouse_drag_end(struct scrollbar *scrollbar, + browser_mouse_state mouse, int x, int y); + +void scrollbar_start_content_drag(struct scrollbar *scrollbar, int x, int y); + +void scrollbar_make_pair(struct scrollbar *horizontal_scrollbar, + struct scrollbar *vertical_scrollbar); + +void *scrollbar_get_data(struct scrollbar *scrollbar); + +#endif diff --git a/desktop/textinput.c b/desktop/textinput.c index 708038d9a..0a33e545c 100644 --- a/desktop/textinput.c +++ b/desktop/textinput.c @@ -31,7 +31,7 @@ #include "desktop/browser.h" #include "desktop/gui.h" #include "desktop/mouse.h" -#include "desktop/scroll.h" +#include "desktop/scrollbar.h" #include "desktop/selection.h" #include "desktop/textinput.h" #include "render/box.h" @@ -287,11 +287,11 @@ void browser_window_textarea_click(struct browser_window *bw, textarea->gadget->caret_box_offset = char_offset; textarea->gadget->caret_pixel_offset = pixel_offset; - box_x += scroll_get_offset(textarea->scroll_x); - box_y += scroll_get_offset(textarea->scroll_y); + box_x += scrollbar_get_offset(textarea->scroll_x); + box_y += scrollbar_get_offset(textarea->scroll_y); scrolled = ensure_caret_visible(bw, textarea); - box_x -= scroll_get_offset(textarea->scroll_x); - box_y -= scroll_get_offset(textarea->scroll_y); + box_x -= scrollbar_get_offset(textarea->scroll_x); + box_y -= scrollbar_get_offset(textarea->scroll_y); browser_window_place_caret(bw, box_x + inline_container->x + text_box->x + @@ -342,8 +342,8 @@ bool browser_window_textarea_callback(struct browser_window *bw, #endif box_coords(textarea, &box_x, &box_y); - box_x -= scroll_get_offset(textarea->scroll_x); - box_y -= scroll_get_offset(textarea->scroll_y); + box_x -= scrollbar_get_offset(textarea->scroll_x); + box_y -= scrollbar_get_offset(textarea->scroll_y); if (!(key <= 0x001F || (0x007F <= key && key <= 0x009F))) { /* normal character insertion */ @@ -767,8 +767,9 @@ bool browser_window_textarea_callback(struct browser_window *bw, assert(char_offset <= text_box->length); /* Scroll back to the left */ if (textarea->scroll_x != NULL) { - box_x += scroll_get_offset(textarea->scroll_x); - scroll_set(textarea->scroll_x, 0, false); + box_x += scrollbar_get_offset( + textarea->scroll_x); + scrollbar_set(textarea->scroll_x, 0, false); } } else { assert(!text_box->next || @@ -790,11 +791,11 @@ bool browser_window_textarea_callback(struct browser_window *bw, textarea->gadget->caret_box_offset = char_offset; textarea->gadget->caret_pixel_offset = pixel_offset; - box_x += scroll_get_offset(textarea->scroll_x); - box_y += scroll_get_offset(textarea->scroll_y); + box_x += scrollbar_get_offset(textarea->scroll_x); + box_y += scrollbar_get_offset(textarea->scroll_y); scrolled = ensure_caret_visible(bw, textarea); - box_x -= scroll_get_offset(textarea->scroll_x); - box_y -= scroll_get_offset(textarea->scroll_y); + box_x -= scrollbar_get_offset(textarea->scroll_x); + box_y -= scrollbar_get_offset(textarea->scroll_y); browser_window_place_caret(bw, box_x + inline_container->x + text_box->x + @@ -1414,11 +1415,11 @@ bool browser_window_textarea_paste_text(struct browser_window *bw, textarea->gadget->caret_pixel_offset = pixel_offset; box_coords(textarea, &box_x, &box_y); - box_x += scroll_get_offset(textarea->scroll_x); - box_y += scroll_get_offset(textarea->scroll_y); + box_x += scrollbar_get_offset(textarea->scroll_x); + box_y += scrollbar_get_offset(textarea->scroll_y); ensure_caret_visible(bw, textarea); - box_x -= scroll_get_offset(textarea->scroll_x); - box_y -= scroll_get_offset(textarea->scroll_y); + box_x -= scrollbar_get_offset(textarea->scroll_x); + box_y -= scrollbar_get_offset(textarea->scroll_y); browser_window_place_caret(bw, box_x + inline_container->x + text_box->x + @@ -1534,8 +1535,8 @@ void browser_window_textarea_move_caret(struct browser_window *bw, void *p) font_plot_style_from_css(text_box->style, &fstyle); box_coords(textarea, &box_x, &box_y); - box_x -= scroll_get_offset(textarea->scroll_x); - box_y -= scroll_get_offset(textarea->scroll_y); + box_x -= scrollbar_get_offset(textarea->scroll_x); + box_y -= scrollbar_get_offset(textarea->scroll_y); nsfont.font_width(&fstyle, text_box->text, char_offset, &pixel_offset); @@ -2233,8 +2234,8 @@ bool ensure_caret_visible(struct browser_window *bw, struct box *textarea) assert(textarea->gadget); - scrollx = scroll_get_offset(textarea->scroll_x); - scrolly = scroll_get_offset(textarea->scroll_y); + scrollx = scrollbar_get_offset(textarea->scroll_x); + scrolly = scrollbar_get_offset(textarea->scroll_y); /* Calculate the caret coordinates */ cx = textarea->gadget->caret_pixel_offset + @@ -2244,37 +2245,37 @@ bool ensure_caret_visible(struct browser_window *bw, struct box *textarea) /* Ensure they are visible */ if (textarea->scroll_x == NULL) { scrollx = 0; - } else if (cx - scroll_get_offset(textarea->scroll_x) < 0) { + } else if (cx - scrollbar_get_offset(textarea->scroll_x) < 0) { scrollx = cx; - } else if (cx > scroll_get_offset(textarea->scroll_x) + + } else if (cx > scrollbar_get_offset(textarea->scroll_x) + textarea->width) { scrollx = cx - textarea->width; } if (textarea->scroll_y == NULL) { scrolly = 0; - } else if (cy - scroll_get_offset(textarea->scroll_y) < 0) { + } else if (cy - scrollbar_get_offset(textarea->scroll_y) < 0) { scrolly = cy; } else if (cy + textarea->gadget->caret_text_box->height > - scroll_get_offset(textarea->scroll_y) + + scrollbar_get_offset(textarea->scroll_y) + textarea->height) { scrolly = (cy + textarea->gadget->caret_text_box->height) - textarea->height; } - if ((scrollx == scroll_get_offset(textarea->scroll_x)) && - (scrolly == scroll_get_offset(textarea->scroll_y))) + if ((scrollx == scrollbar_get_offset(textarea->scroll_x)) && + (scrolly == scrollbar_get_offset(textarea->scroll_y))) return false; if (textarea->scroll_x != NULL) { - bw->scroll = textarea->scroll_x; - scroll_set(textarea->scroll_x, scrollx, false); - bw->scroll = NULL; + bw->scrollbar = textarea->scroll_x; + scrollbar_set(textarea->scroll_x, scrollx, false); + bw->scrollbar = NULL; } if (textarea->scroll_y != NULL) { - bw->scroll = textarea->scroll_x; - scroll_set(textarea->scroll_y, scrolly, false); - bw->scroll = NULL; + bw->scrollbar = textarea->scroll_x; + scrollbar_set(textarea->scroll_y, scrolly, false); + bw->scrollbar = NULL; } return true; diff --git a/render/box.c b/render/box.c index 537ea3674..67877147e 100644 --- a/render/box.c +++ b/render/box.c @@ -31,7 +31,7 @@ #include "content/hlcache.h" #include "css/css.h" #include "css/dump.h" -#include "desktop/scroll.h" +#include "desktop/scrollbar.h" #include "desktop/options.h" #include "render/box.h" #include "render/form.h" @@ -277,9 +277,9 @@ void box_free_box(struct box *box) if (box->gadget) form_free_control(box->gadget); if (box->scroll_x != NULL) - scroll_destroy(box->scroll_x); + scrollbar_destroy(box->scroll_x); if (box->scroll_y != NULL) - scroll_destroy(box->scroll_y); + scrollbar_destroy(box->scroll_y); if (box->styles != NULL) css_select_results_destroy(box->styles); } @@ -307,8 +307,8 @@ void box_coords(struct box *box, int *x, int *y) } while (!box->float_children); } else box = box->parent; - *x += box->x - scroll_get_offset(box->scroll_x); - *y += box->y - scroll_get_offset(box->scroll_y); + *x += box->x - scrollbar_get_offset(box->scroll_x); + *y += box->y - scrollbar_get_offset(box->scroll_y); } } @@ -388,9 +388,9 @@ struct box *box_at_point(struct box *box, const int x, const int y, 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 - - scroll_get_offset(child->scroll_x); + scrollbar_get_offset(child->scroll_x); *box_y = by + child->y - - scroll_get_offset(child->scroll_y); + scrollbar_get_offset(child->scroll_y); if (physically) return child; @@ -407,9 +407,9 @@ non_float_children: continue; if (box_contains_point(child, x - bx, y - by, &physically)) { *box_x = bx + child->x - - scroll_get_offset(child->scroll_x); + scrollbar_get_offset(child->scroll_x); *box_y = by + child->y - - scroll_get_offset(child->scroll_y); + scrollbar_get_offset(child->scroll_y); if (physically) return child; @@ -433,17 +433,17 @@ siblings: /* siblings and siblings of ancestors */ while (box) { if (box_is_float(box)) { - bx -= box->x - scroll_get_offset(box->scroll_x); - by -= box->y - scroll_get_offset(box->scroll_y); + bx -= box->x - scrollbar_get_offset(box->scroll_x); + by -= box->y - scrollbar_get_offset(box->scroll_y); for (sibling = box->next_float; sibling; sibling = sibling->next_float) { if (box_contains_point(sibling, x - bx, y - by, &physically)) { *box_x = bx + sibling->x - - scroll_get_offset( + scrollbar_get_offset( sibling->scroll_x); *box_y = by + sibling->y - - scroll_get_offset( + scrollbar_get_offset( sibling->scroll_y); if (physically) @@ -463,8 +463,8 @@ siblings: goto non_float_children; } else { - bx -= box->x - scroll_get_offset(box->scroll_x); - by -= box->y - scroll_get_offset(box->scroll_y); + bx -= box->x - scrollbar_get_offset(box->scroll_x); + by -= box->y - scrollbar_get_offset(box->scroll_y); for (sibling = box->next; sibling; sibling = sibling->next) { if (box_is_float(sibling)) @@ -472,10 +472,10 @@ siblings: if (box_contains_point(sibling, x - bx, y - by, &physically)) { *box_x = bx + sibling->x - - scroll_get_offset( + scrollbar_get_offset( sibling->scroll_x); *box_y = by + sibling->y - - scroll_get_offset( + scrollbar_get_offset( sibling->scroll_y); if (physically) @@ -735,14 +735,14 @@ bool box_nearest_text_box(struct box *box, int bx, int by, if (child->type == BOX_FLOAT_LEFT || child->type == BOX_FLOAT_RIGHT) { c_bx = fx + child->x - - scroll_get_offset(child->scroll_x); + scrollbar_get_offset(child->scroll_x); c_by = fy + child->y - - scroll_get_offset(child->scroll_y); + scrollbar_get_offset(child->scroll_y); } else { c_bx = bx + child->x - - scroll_get_offset(child->scroll_x); + scrollbar_get_offset(child->scroll_x); c_by = by + child->y - - scroll_get_offset(child->scroll_y); + scrollbar_get_offset(child->scroll_y); } if (child->float_children) { c_fx = c_bx; @@ -1004,22 +1004,22 @@ void box_dump(FILE *stream, struct box *box, unsigned int depth) bool box_handle_scrollbars(struct browser_window *bw, struct box *box, bool bottom, bool right) { - struct browser_scroll_data *data; + struct browser_scrollbar_data *data; int padding_width, padding_height; padding_width = box->width + box->padding[RIGHT] + box->padding[LEFT]; padding_height = box->height + box->padding[TOP] + box->padding[BOTTOM]; if (!bottom && box->scroll_x != NULL) { - data = scroll_get_data(box->scroll_x); - scroll_destroy(box->scroll_x); + data = scrollbar_get_data(box->scroll_x); + scrollbar_destroy(box->scroll_x); free(data); box->scroll_x = NULL; } if (!right && box->scroll_y != NULL) { - data = scroll_get_data(box->scroll_y); - scroll_destroy(box->scroll_y); + data = scrollbar_get_data(box->scroll_y); + scrollbar_destroy(box->scroll_y); free(data); box->scroll_y = NULL; } @@ -1029,7 +1029,7 @@ bool box_handle_scrollbars(struct browser_window *bw, struct box *box, if (right) { if (box->scroll_y == NULL) { - data = malloc(sizeof(struct browser_scroll_data)); + data = malloc(sizeof(struct browser_scrollbar_data)); if (data == NULL) { LOG(("malloc failed")); warn_user("NoMemory", 0); @@ -1037,7 +1037,7 @@ bool box_handle_scrollbars(struct browser_window *bw, struct box *box, } data->bw = bw; data->box = box; - if (!scroll_create(false, + if (!scrollbar_create(false, padding_height, box->descendant_y1 - box->padding[TOP], box->height, @@ -1046,14 +1046,14 @@ bool box_handle_scrollbars(struct browser_window *bw, struct box *box, &(box->scroll_y))) return false; } else - scroll_set_extents(box->scroll_y, + scrollbar_set_extents(box->scroll_y, padding_height, box->height, box->descendant_y1 - box->padding[TOP]); } if (bottom) { if (box->scroll_x == NULL) { - data = malloc(sizeof(struct browser_scroll_data)); + data = malloc(sizeof(struct browser_scrollbar_data)); if (data == NULL) { LOG(("malloc failed")); warn_user("NoMemory", 0); @@ -1061,7 +1061,7 @@ bool box_handle_scrollbars(struct browser_window *bw, struct box *box, } data->bw = bw; data->box = box; - if (!scroll_create(true, + if (!scrollbar_create(true, padding_width - (right ? SCROLLBAR_WIDTH : 0), box->descendant_x1 - box->padding[LEFT], @@ -1071,7 +1071,7 @@ bool box_handle_scrollbars(struct browser_window *bw, struct box *box, &box->scroll_x)) return false; } else - scroll_set_extents(box->scroll_x, + scrollbar_set_extents(box->scroll_x, padding_width - (right ? SCROLLBAR_WIDTH : 0), box->width, @@ -1080,7 +1080,7 @@ bool box_handle_scrollbars(struct browser_window *bw, struct box *box, } if (right && bottom) - scroll_make_pair(box->scroll_x, box->scroll_y); + scrollbar_make_pair(box->scroll_x, box->scroll_y); return true; } diff --git a/render/box.h b/render/box.h index b5092728f..936c57337 100644 --- a/render/box.h +++ b/render/box.h @@ -191,8 +191,8 @@ struct box { int padding[4]; /**< Padding: TOP, RIGHT, BOTTOM, LEFT. */ struct box_border border[4]; /**< Border: TOP, RIGHT, BOTTOM, LEFT. */ - struct scroll *scroll_x; /**< Horizontal scroll. */ - struct scroll *scroll_y; /**< Vertical scroll. */ + struct scrollbar *scroll_x; /**< Horizontal scroll. */ + struct scrollbar *scroll_y; /**< Vertical scroll. */ /** Width of box taking all line breaks (including margins etc). Must * be non-negative. */ diff --git a/render/form.c b/render/form.c index 955c208e8..6a50581d1 100644 --- a/render/form.c +++ b/render/form.c @@ -41,7 +41,7 @@ #include "desktop/knockout.h" #include "desktop/plot_style.h" #include "desktop/plotters.h" -#include "desktop/scroll.h" +#include "desktop/scrollbar.h" #include "render/box.h" #include "render/font.h" #include "render/form.h" @@ -62,7 +62,7 @@ struct form_select_menu { int line_height; int width, height; - struct scroll *scroll; + struct scrollbar *scrollbar; int f_size; bool scroll_capture; select_menu_redraw_callback callback; @@ -90,7 +90,7 @@ static char *form_encode_item(const char *item, const char *charset, static void form_select_menu_clicked(struct form_control *control, int x, int y); static void form_select_menu_scroll_callback(void *client_data, - struct scroll_msg_data *scroll_data); + struct scrollbar_msg_data *scrollbar_data); /** * Create a struct form. @@ -932,13 +932,13 @@ bool form_open_select_menu(void *client_data, } menu->client_data = client_data; menu->callback = callback; - if (!scroll_create(false, + if (!scrollbar_create(false, menu->height, total_height, menu->height, control, form_select_menu_scroll_callback, - &(menu->scroll))) { + &(menu->scrollbar))) { free(menu); return false; } @@ -960,8 +960,8 @@ bool form_open_select_menu(void *client_data, */ void form_free_select_menu(struct form_control *control) { - if (control->data.select.menu->scroll != NULL) - scroll_destroy(control->data.select.menu->scroll); + if (control->data.select.menu->scrollbar != NULL) + scrollbar_destroy(control->data.select.menu->scrollbar); free(control->data.select.menu); control->data.select.menu = NULL; } @@ -1006,7 +1006,7 @@ bool form_redraw_select_menu(struct form_control *control, int x, int y, line_height_with_spacing = line_height + line_height * SELECT_LINE_SPACING; - scroll = scroll_get_offset(menu->scroll); + scroll = scrollbar_get_offset(menu->scrollbar); if (scale != 1.0) { x *= scale; @@ -1090,7 +1090,7 @@ bool form_redraw_select_menu(struct form_control *control, int x, int y, option = option->next; } - if (!scroll_redraw(menu->scroll, + if (!scrollbar_redraw(menu->scrollbar, x_cp + menu->width - SCROLLBAR_WIDTH, y_cp, clip, scale)) @@ -1148,7 +1148,7 @@ void form_select_menu_clicked(struct form_control *control, int x, int y) int item_bottom_y; int scroll, i; - scroll = scroll_get_offset(menu->scroll); + scroll = scrollbar_get_offset(menu->scrollbar); line_height = menu->line_height; line_height_with_spacing = line_height + @@ -1200,7 +1200,7 @@ const char *form_select_mouse_action(struct form_control *control, * event is taking place on the scrollbar widget area */ x -= scrollbar_x; - return scroll_mouse_action(menu->scroll, + return scrollbar_mouse_action(menu->scrollbar, mouse, x, y); } @@ -1255,7 +1255,7 @@ void form_select_mouse_drag_end(struct form_control *control, if (menu->scroll_capture) { x -= menu->width - SCROLLBAR_WIDTH; - scroll_mouse_drag_end(menu->scroll, mouse, x, y); + scrollbar_mouse_drag_end(menu->scrollbar, mouse, x, y); return; } @@ -1274,33 +1274,33 @@ void form_select_mouse_drag_end(struct form_control *control, * Callback for the select menus scroll */ void form_select_menu_scroll_callback(void *client_data, - struct scroll_msg_data *scroll_data) + struct scrollbar_msg_data *scrollbar_data) { struct form_control *control = client_data; struct form_select_menu *menu = control->data.select.menu; - switch (scroll_data->msg) { - case SCROLL_MSG_REDRAW: + switch (scrollbar_data->msg) { + case SCROLLBAR_MSG_REDRAW: menu->callback(menu->client_data, menu->width - - SCROLLBAR_WIDTH + scroll_data->x0, - scroll_data->y0, - scroll_data->x1 - scroll_data->x0, - scroll_data->y1 - scroll_data->y0); + SCROLLBAR_WIDTH + scrollbar_data->x0, + scrollbar_data->y0, + scrollbar_data->x1 - scrollbar_data->x0, + scrollbar_data->y1 - scrollbar_data->y0); break; - case SCROLL_MSG_MOVED: + case SCROLLBAR_MSG_MOVED: menu->callback(menu->client_data, 0, 0, menu->width - SCROLLBAR_WIDTH, menu->height); break; - case SCROLL_MSG_SCROLL_START: + case SCROLLBAR_MSG_SCROLL_START: menu->scroll_capture = true; gui_window_box_scroll_start(menu->bw->window, - scroll_data->x0, scroll_data->y0, - scroll_data->x1, scroll_data->y1); + scrollbar_data->x0, scrollbar_data->y0, + scrollbar_data->x1, scrollbar_data->y1); break; - case SCROLL_MSG_SCROLL_FINISHED: + case SCROLLBAR_MSG_SCROLL_FINISHED: menu->scroll_capture = false; break; default: diff --git a/render/html.h b/render/html.h index a321f5d48..9f4f3f698 100644 --- a/render/html.h +++ b/render/html.h @@ -42,8 +42,8 @@ struct http_parameter; struct imagemap; struct object_params; struct plotters; -struct scroll; -struct scroll_msg_data; +struct scrollbar; +struct scrollbar_msg_data; /** * Container for stylesheets used by an HTML document @@ -141,7 +141,7 @@ void html_fini(void); void html_redraw_a_box(struct hlcache_handle *h, struct box *box); -void html_overflow_scroll_drag_end(struct scroll *scroll, +void html_overflow_scroll_drag_end(struct scrollbar *scrollbar, browser_mouse_state mouse, int x, int y); size_t html_selection_drag_end(struct hlcache_handle *h, browser_mouse_state mouse, int x, int y, int dir); diff --git a/render/html_interaction.c b/render/html_interaction.c index 6670a1a90..ffef09ea6 100644 --- a/render/html_interaction.c +++ b/render/html_interaction.c @@ -31,7 +31,7 @@ #include "desktop/frames.h" #include "desktop/mouse.h" #include "desktop/options.h" -#include "desktop/scroll.h" +#include "desktop/scrollbar.h" #include "desktop/selection.h" #include "desktop/textinput.h" #include "render/box.h" @@ -137,7 +137,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw, hlcache_handle *object = NULL; struct box *next_box; struct box *drag_candidate = NULL; - struct scroll *scroll = NULL; + struct scrollbar *scrollbar = NULL; plot_font_style_t fstyle; int scroll_mouse_x = 0, scroll_mouse_y = 0; int padding_left, padding_right, padding_top, padding_bottom; @@ -164,24 +164,25 @@ void html_mouse_action(struct content *c, struct browser_window *bw, } return; } - - if (bw->scroll != NULL) { - struct browser_scroll_data *data = scroll_get_data(bw->scroll); + + if (bw->scrollbar != NULL) { + struct browser_scrollbar_data *data = + scrollbar_get_data(bw->scrollbar); box = data->box; box_coords(box, &box_x, &box_y); - if (scroll_is_horizontal(bw->scroll)) { + if (scrollbar_is_horizontal(bw->scrollbar)) { scroll_mouse_x = x - box_x ; scroll_mouse_y = y - (box_y + box->padding[TOP] + box->height + box->padding[BOTTOM] - SCROLLBAR_WIDTH); - status = scroll_mouse_action(bw->scroll, mouse, + status = scrollbar_mouse_action(bw->scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } else { scroll_mouse_x = x - (box_x + box->padding[LEFT] + box->width + box->padding[RIGHT] - SCROLLBAR_WIDTH); scroll_mouse_y = y - box_y; - status = scroll_mouse_action(bw->scroll, mouse, + status = scrollbar_mouse_action(bw->scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } @@ -251,10 +252,12 @@ void html_mouse_action(struct content *c, struct browser_window *bw, drag_candidate = box; if (box->scroll_y != NULL || box->scroll_x != NULL) { - padding_left = box_x + scroll_get_offset(box->scroll_x); + padding_left = box_x + + scrollbar_get_offset(box->scroll_x); padding_right = padding_left + box->padding[LEFT] + box->width + box->padding[RIGHT]; - padding_top = box_y + scroll_get_offset(box->scroll_y); + padding_top = box_y + + scrollbar_get_offset(box->scroll_y); padding_bottom = padding_top + box->padding[TOP] + box->height + box->padding[BOTTOM]; @@ -266,7 +269,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw, SCROLLBAR_WIDTH) { /* mouse above vertical box scroll */ - scroll = box->scroll_y; + scrollbar = box->scroll_y; scroll_mouse_x = x - (padding_right - SCROLLBAR_WIDTH); scroll_mouse_y = y - padding_top; @@ -277,7 +280,7 @@ void html_mouse_action(struct content *c, struct browser_window *bw, SCROLLBAR_WIDTH) { /* mouse above horizontal box scroll */ - scroll = box->scroll_x; + scrollbar = box->scroll_x; scroll_mouse_x = x - padding_left; scroll_mouse_y = y - (padding_bottom - SCROLLBAR_WIDTH); @@ -295,8 +298,8 @@ void html_mouse_action(struct content *c, struct browser_window *bw, /* use of box_x, box_y, or content below this point is probably a * mistake; they will refer to the last box returned by box_at_point */ - if (scroll) { - status = scroll_mouse_action(scroll, mouse, + if (scrollbar) { + status = scrollbar_mouse_action(scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); pointer = GUI_POINTER_DEFAULT; } else if (gadget) { @@ -731,48 +734,49 @@ gui_pointer_shape get_pointer_shape(struct browser_window *bw, struct box *box, * Callback for in-page scrolls. */ void html_overflow_scroll_callback(void *client_data, - struct scroll_msg_data *scroll_data) + struct scrollbar_msg_data *scrollbar_data) { - struct browser_scroll_data *data = client_data; + struct browser_scrollbar_data *data = client_data; struct browser_window *bw = data->bw; struct box *box = data->box; int x, y, box_x, box_y, diff_x, diff_y; - switch(scroll_data->msg) { - case SCROLL_MSG_REDRAW: + switch(scrollbar_data->msg) { + case SCROLLBAR_MSG_REDRAW: diff_x = box->padding[LEFT] + box->width + box->padding[RIGHT] - SCROLLBAR_WIDTH; diff_y = box->padding[TOP] + box->height + box->padding[BOTTOM] - SCROLLBAR_WIDTH; box_coords(box, &box_x, &box_y); - if (scroll_is_horizontal(scroll_data->scroll)) { - x = box_x + scroll_get_offset(box->scroll_x); - y = box_y + scroll_get_offset(box->scroll_y) + + if (scrollbar_is_horizontal( + scrollbar_data->scrollbar)) { + x = box_x + scrollbar_get_offset(box->scroll_x); + y = box_y + scrollbar_get_offset(box->scroll_y) + diff_y; } else { - x = box_x + scroll_get_offset(box->scroll_x) + + x = box_x + scrollbar_get_offset(box->scroll_x) + diff_x; - y = box_y + scroll_get_offset(box->scroll_y); + y = box_y + scrollbar_get_offset(box->scroll_y); } browser_window_redraw_rect(bw, - x + scroll_data->x0, - y + scroll_data->y0, - scroll_data->x1 - scroll_data->x0, - scroll_data->y1 - scroll_data->y0); + x + scrollbar_data->x0, + y + scrollbar_data->y0, + scrollbar_data->x1 - scrollbar_data->x0, + scrollbar_data->y1 - scrollbar_data->y0); break; - case SCROLL_MSG_MOVED: + case SCROLLBAR_MSG_MOVED: html_redraw_a_box(bw->current_content, box); break; - case SCROLL_MSG_SCROLL_START: - bw->scroll = scroll_data->scroll; + case SCROLLBAR_MSG_SCROLL_START: + bw->scrollbar = scrollbar_data->scrollbar; gui_window_box_scroll_start(bw->window, - scroll_data->x0, scroll_data->y0, - scroll_data->x1, scroll_data->y1); + scrollbar_data->x0, scrollbar_data->y0, + scrollbar_data->x1, scrollbar_data->y1); break; - case SCROLL_MSG_SCROLL_FINISHED: - bw->scroll = NULL; + case SCROLLBAR_MSG_SCROLL_FINISHED: + bw->scrollbar = NULL; browser_window_set_pointer(bw->window, GUI_POINTER_DEFAULT); @@ -789,29 +793,29 @@ void html_overflow_scroll_callback(void *client_data, * \param x coordinate of mouse * \param y coordinate of mouse */ -void html_overflow_scroll_drag_end(struct scroll *scroll, +void html_overflow_scroll_drag_end(struct scrollbar *scrollbar, browser_mouse_state mouse, int x, int y) { int scroll_mouse_x, scroll_mouse_y, box_x, box_y; - struct browser_scroll_data *data = scroll_get_data(scroll); + struct browser_scrollbar_data *data = scrollbar_get_data(scrollbar); struct box *box; box = data->box; box_coords(box, &box_x, &box_y); - if (scroll_is_horizontal(scroll)) { + if (scrollbar_is_horizontal(scrollbar)) { scroll_mouse_x = x - box_x; scroll_mouse_y = y - (box_y + box->padding[TOP] + box->height + box->padding[BOTTOM] - SCROLLBAR_WIDTH); - scroll_mouse_drag_end(scroll, mouse, + scrollbar_mouse_drag_end(scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } else { scroll_mouse_x = x - (box_x + box->padding[LEFT] + box->width + box->padding[RIGHT] - SCROLLBAR_WIDTH); scroll_mouse_y = y - box_y; - scroll_mouse_drag_end(scroll, mouse, + scrollbar_mouse_drag_end(scrollbar, mouse, scroll_mouse_x, scroll_mouse_y); } } @@ -868,7 +872,7 @@ void html_box_drag_start(struct box *box, int x, int y) scroll_mouse_y = y - (box_y + box->padding[TOP] + box->height + box->padding[BOTTOM] - SCROLLBAR_WIDTH); - scroll_start_content_drag(box->scroll_x, + scrollbar_start_content_drag(box->scroll_x, scroll_mouse_x, scroll_mouse_y); } else if (box->scroll_y != NULL) { scroll_mouse_x = x - (box_x + box->padding[LEFT] + @@ -876,7 +880,7 @@ void html_box_drag_start(struct box *box, int x, int y) SCROLLBAR_WIDTH); scroll_mouse_y = y - box_y; - scroll_start_content_drag(box->scroll_y, + scrollbar_start_content_drag(box->scroll_y, scroll_mouse_x, scroll_mouse_y); } } diff --git a/render/html_internal.h b/render/html_internal.h index dd04edb77..cbb323844 100644 --- a/render/html_internal.h +++ b/render/html_internal.h @@ -106,7 +106,7 @@ void html_mouse_track(struct content *c, struct browser_window *bw, void html_mouse_action(struct content *c, struct browser_window *bw, browser_mouse_state mouse, int x, int y); void html_overflow_scroll_callback(void *client_data, - struct scroll_msg_data *scroll_data); + struct scrollbar_msg_data *scrollbar_data); #endif diff --git a/render/html_redraw.c b/render/html_redraw.c index 2d1a78559..df8fd8d41 100644 --- a/render/html_redraw.c +++ b/render/html_redraw.c @@ -42,7 +42,7 @@ #include "desktop/options.h" #include "desktop/print.h" #include "desktop/search.h" -#include "desktop/scroll.h" +#include "desktop/scrollbar.h" #include "image/bitmap.h" #include "render/box.h" #include "render/font.h" @@ -650,8 +650,8 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent, return false; if (box->object && width != 0 && height != 0) { - x_scrolled = x - scroll_get_offset(box->scroll_x) * scale; - y_scrolled = y - scroll_get_offset(box->scroll_y) * scale; + x_scrolled = x - scrollbar_get_offset(box->scroll_x) * scale; + y_scrolled = y - scrollbar_get_offset(box->scroll_y) * scale; if (!content_redraw(box->object, x_scrolled + padding_left, y_scrolled + padding_top, @@ -693,9 +693,9 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent, if (box->list_marker) if (!html_redraw_box(box->list_marker, x_parent + box->x - - scroll_get_offset(box->scroll_x), + scrollbar_get_offset(box->scroll_x), y_parent + box->y - - scroll_get_offset(box->scroll_y), + scrollbar_get_offset(box->scroll_y), clip, scale, current_background_color)) return false; @@ -716,13 +716,13 @@ bool html_redraw_box(struct box *box, int x_parent, int y_parent, return false; if (box->scroll_x != NULL) - scroll_redraw(box->scroll_x, + scrollbar_redraw(box->scroll_x, x_parent + box->x, y_parent + box->y + box->padding[TOP] + box->height + box->padding[BOTTOM] - SCROLLBAR_WIDTH, clip, scale); if (box->scroll_y != NULL) - scroll_redraw(box->scroll_y, + scrollbar_redraw(box->scroll_y, x_parent + box->x + box->padding[LEFT] + box->width + box->padding[RIGHT] - SCROLLBAR_WIDTH, @@ -761,18 +761,18 @@ bool html_redraw_box_children(struct box *box, int x_parent, int y_parent, if (c->type != BOX_FLOAT_LEFT && c->type != BOX_FLOAT_RIGHT) if (!html_redraw_box(c, x_parent + box->x - - scroll_get_offset(box->scroll_x), + scrollbar_get_offset(box->scroll_x), y_parent + box->y - - scroll_get_offset(box->scroll_y), + scrollbar_get_offset(box->scroll_y), clip, scale, current_background_color)) return false; } for (c = box->float_children; c; c = c->next_float) if (!html_redraw_box(c, x_parent + box->x - - scroll_get_offset(box->scroll_x), + scrollbar_get_offset(box->scroll_x), y_parent + box->y - - scroll_get_offset(box->scroll_y), + scrollbar_get_offset(box->scroll_y), clip, scale, current_background_color)) return false; diff --git a/render/layout.c b/render/layout.c index b46930b21..a347b1632 100644 --- a/render/layout.c +++ b/render/layout.c @@ -45,7 +45,7 @@ #include "content/content_protected.h" #include "desktop/gui.h" #include "desktop/options.h" -#include "desktop/scroll.h" +#include "desktop/scrollbar.h" #include "render/box.h" #include "render/font.h" #include "render/form.h" -- cgit v1.2.3