diff options
author | Vincent Sanders <vince@netsurf-browser.org> | 2010-04-22 23:50:58 +0000 |
---|---|---|
committer | Vincent Sanders <vince@netsurf-browser.org> | 2010-04-22 23:50:58 +0000 |
commit | fe151c135d3ffe3dff155d51f4f2680024ae8382 (patch) | |
tree | a5c32b09b597ecec2bf7a483d65ae33a3f4e890f /framebuffer/fbtk_widget_scroll.c | |
parent | 695af237a9fd679ccd4467ffb9798966a431bb9d (diff) | |
download | netsurf-fe151c135d3ffe3dff155d51f4f2680024ae8382.tar.gz netsurf-fe151c135d3ffe3dff155d51f4f2680024ae8382.tar.bz2 |
First steps towards rationalising fbtk, split teh scrollbar widgets out
svn path=/trunk/netsurf/; revision=10466
Diffstat (limited to 'framebuffer/fbtk_widget_scroll.c')
-rw-r--r-- | framebuffer/fbtk_widget_scroll.c | 356 |
1 files changed, 356 insertions, 0 deletions
diff --git a/framebuffer/fbtk_widget_scroll.c b/framebuffer/fbtk_widget_scroll.c new file mode 100644 index 000000000..d9360c0e5 --- /dev/null +++ b/framebuffer/fbtk_widget_scroll.c @@ -0,0 +1,356 @@ +/* + * Copyright 2008 Vincent Sanders <vince@simtec.co.uk> + * + * Framebuffer windowing toolkit scrollbar widgets + * + * 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 <http://www.gnu.org/licenses/>. + */ + +#include <stdbool.h> + +#include <libnsfb.h> +#include <libnsfb_plot.h> +#include <libnsfb_event.h> + +#include "utils/log.h" +#include "desktop/browser.h" + +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/fbtk_widget.h" +#include "framebuffer/bitmap.h" +#include "framebuffer/image_data.h" + +/** Vertical scroll widget */ + +static int +vscroll_redraw(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + int vscroll; + int vpos; + + nsfb_bbox_t bbox; + nsfb_bbox_t rect; + + fbtk_get_bbox(widget, &bbox); + + nsfb_claim(root->u.root.fb, &bbox); + + rect = bbox; + + /* background */ + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + rect.x0 = bbox.x0 + 2; + rect.y0 = bbox.y0 + 1; + rect.x1 = bbox.x1 - 3; + rect.y1 = bbox.y1 - 2; + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg); + + /* scroll well */ + nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false); + + /* scroll well outline */ + vscroll = ((widget->height - 4) * widget->u.scroll.pct) / 100 ; + vpos = ((widget->height - 4) * widget->u.scroll.pos) / 100 ; + + LOG(("scroll %d",vscroll)); + + rect.x0 = bbox.x0 + 5; + rect.y0 = bbox.y0 + 3 + vpos; + rect.x1 = bbox.x0 + widget->width - 5; + rect.y1 = bbox.y0 + vscroll + vpos; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + nsfb_update(root->u.root.fb, &bbox); + + return 0; +} + +static int +vscrollu_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + fbtk_widget_t *scrollw = pw; + fbtk_callback_info cbi; + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + cbi.type = FBTK_CBIT_SCROLLY; + cbi.context = scrollw->callback_context; + cbi.y = -1; + + return (scrollw->callback)(scrollw, &cbi); +} + +static int +vscrolld_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + fbtk_widget_t *scrollw = pw; + fbtk_callback_info cbi; + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + cbi.type = FBTK_CBIT_SCROLLY; + cbi.context = scrollw->callback_context; + cbi.y = 1; + + return (scrollw->callback)(scrollw, &cbi); +} + +static int +vscrollarea_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + fbtk_widget_t *scrollw = pw; + fbtk_callback_info cbi; + int vscroll; + int vpos; + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + vscroll = ((widget->height - 4) * widget->u.scroll.pct) / 100 ; + vpos = ((widget->height - 4) * widget->u.scroll.pos) / 100 ; + + cbi.type = FBTK_CBIT_SCROLLY; + cbi.context = scrollw->callback_context; + if (y < vpos) { + /* above bar */ + cbi.y = -1; + return (scrollw->callback)(scrollw, &cbi); + } else if (y > (vpos+vscroll)) { + /* below bar */ + cbi.y = 1; + return (scrollw->callback)(scrollw, &cbi); + } + return 0; +} + +fbtk_widget_t * +fbtk_create_vscroll(fbtk_widget_t *window, + int x, int y, + int width, int height, + colour fg, + colour bg, + fbtk_callback callback, + void *context) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_VSCROLL); + + neww->x = x; + neww->y = y + scrollu.height; + neww->width = width; + neww->height = height - scrollu.height - scrolld.height; + neww->fg = fg; + neww->bg = bg; + + neww->redraw = vscroll_redraw; + + neww->click = vscrollarea_click; + neww->clickpw = neww; + + neww->callback = callback; + neww->callback_context = context; + + neww->u.scroll.btnul = fbtk_create_button(window, x + (width - scrollu.width) / 2, y, fg, &scrollu, vscrollu_click, neww); + + neww->u.scroll.btndr = fbtk_create_button(window, x + (width - scrolld.width) / 2, y + height - scrolld.height, fg, &scrolld, vscrolld_click, neww); + + return add_widget_to_window(window, neww); +} + +/* Horizontal scroll widget */ + +static int +hscroll_redraw(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + int hscroll; + int hpos; + nsfb_bbox_t bbox; + nsfb_bbox_t rect; + + fbtk_get_bbox(widget, &bbox); + + nsfb_claim(root->u.root.fb, &bbox); + + rect = bbox; + + /* background */ + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + /* scroll well */ + rect.x0 = bbox.x0 + 1; + rect.y0 = bbox.y0 + 2; + rect.x1 = bbox.x1 - 2; + rect.y1 = bbox.y1 - 3; + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg); + + /* scroll well outline */ + nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF999999, false, false); + + hscroll = ((widget->width - 4) * widget->u.scroll.pct) / 100 ; + hpos = ((widget->width - 4) * widget->u.scroll.pos) / 100 ; + + LOG(("hscroll %d",hscroll)); + + rect.x0 = bbox.x0 + 3 + hpos; + rect.y0 = bbox.y0 + 5; + rect.x1 = bbox.x0 + hscroll + hpos; + rect.y1 = bbox.y0 + widget->height - 5; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + nsfb_update(root->u.root.fb, &bbox); + + return 0; +} + +static int +hscrolll_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + fbtk_widget_t *scrollw = pw; + fbtk_callback_info cbi; + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + cbi.type = FBTK_CBIT_SCROLLX; + cbi.context = scrollw->callback_context; + cbi.x = -1; + + return (scrollw->callback)(scrollw, &cbi); +} + +static int +hscrollr_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + fbtk_widget_t *scrollw = pw; + fbtk_callback_info cbi; + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + cbi.type = FBTK_CBIT_SCROLLX; + cbi.context = scrollw->callback_context; + cbi.x = 1; + + return (scrollw->callback)(scrollw, &cbi); +} + +static int +hscrollarea_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + fbtk_widget_t *scrollw = pw; + fbtk_callback_info cbi; + int hscroll; + int hpos; + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + hscroll = ((widget->width - 4) * widget->u.scroll.pct) / 100 ; + hpos = ((widget->width - 4) * widget->u.scroll.pos) / 100 ; + + cbi.type = FBTK_CBIT_SCROLLX; + cbi.context = scrollw->callback_context; + if (x < hpos) { + /* above bar */ + cbi.x = -1; + return (scrollw->callback)(scrollw, &cbi); + } else if (x > (hpos + hscroll)) { + /* below bar */ + cbi.x = 1; + return (scrollw->callback)(scrollw, &cbi); + } + return 0; +} + +fbtk_widget_t * +fbtk_create_hscroll(fbtk_widget_t *window, + int x, int y, + int width, int height, + colour fg, + colour bg, + fbtk_callback callback, + void *context) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_HSCROLL); + + neww->x = x + scrolll.width; + neww->y = y; + neww->width = width - scrolll.width - scrollr.width; + neww->height = height; + neww->fg = fg; + neww->bg = bg; + + neww->redraw = hscroll_redraw; + + neww->click = hscrollarea_click; + neww->clickpw = neww; + + neww->callback = callback; + neww->callback_context = context; + + neww->u.scroll.btnul = fbtk_create_button(window, x, y + ((height - scrolll.height) / 2), fg, &scrolll, hscrolll_click, neww); + + neww->u.scroll.btndr = fbtk_create_button(window, x + width - scrollr.width, y + ((height - scrolll.height) / 2), fg, &scrollr, hscrollr_click, neww); + + return add_widget_to_window(window, neww); +} + + +void +fbtk_set_scroll(fbtk_widget_t *widget, int pct) +{ + if (widget == NULL) + return; + + if ((widget->type == FB_WIDGET_TYPE_HSCROLL) || + (widget->type == FB_WIDGET_TYPE_VSCROLL)) { + + widget->u.scroll.pct = pct; + fbtk_request_redraw(widget); + } +} + +void +fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos) +{ + if (widget == NULL) + return; + + if ((widget->type == FB_WIDGET_TYPE_HSCROLL) || + (widget->type == FB_WIDGET_TYPE_VSCROLL)) { + + widget->u.scroll.pos = pos; + + fbtk_request_redraw(widget); + } +} + |