diff options
author | Vincent Sanders <vince@netsurf-browser.org> | 2009-03-22 14:34:56 +0000 |
---|---|---|
committer | Vincent Sanders <vince@netsurf-browser.org> | 2009-03-22 14:34:56 +0000 |
commit | 8db32fc061dd4081dce43700db86eb7f6a7856b5 (patch) | |
tree | 0234ded268f14767c9f91f359a7b2f64f57595bb /framebuffer | |
parent | c9fc91c6e4ced28336b3681a64a2a9fefaef2a4a (diff) | |
download | netsurf-8db32fc061dd4081dce43700db86eb7f6a7856b5.tar.gz netsurf-8db32fc061dd4081dce43700db86eb7f6a7856b5.tar.bz2 |
add vertical scrollbar to freamebuffer
svn path=/trunk/netsurf/; revision=6817
Diffstat (limited to 'framebuffer')
-rw-r--r-- | framebuffer/fb_16bpp_plotters.c | 7 | ||||
-rw-r--r-- | framebuffer/fb_frontend_sdl.c | 4 | ||||
-rw-r--r-- | framebuffer/fb_gui.c | 87 | ||||
-rw-r--r-- | framebuffer/fb_gui.h | 1 | ||||
-rw-r--r-- | framebuffer/fb_image_data.h | 2 | ||||
-rw-r--r-- | framebuffer/fb_plotters.c | 22 | ||||
-rw-r--r-- | framebuffer/fb_tk.c | 161 | ||||
-rw-r--r-- | framebuffer/fb_tk.h | 10 | ||||
-rw-r--r-- | framebuffer/res/icons/scrolld.png | bin | 0 -> 375 bytes | |||
-rw-r--r-- | framebuffer/res/icons/scrollu.png | bin | 0 -> 358 bytes |
10 files changed, 257 insertions, 37 deletions
diff --git a/framebuffer/fb_16bpp_plotters.c b/framebuffer/fb_16bpp_plotters.c index 369683fde..8de86d802 100644 --- a/framebuffer/fb_16bpp_plotters.c +++ b/framebuffer/fb_16bpp_plotters.c @@ -453,8 +453,6 @@ static bool fb_16bpp_bitmap(int x, int y, int width, int height, int x0,y0,x1,y1; int xoff, yoff; /* x and y offset into image */ - /* LOG(("x %d, y %d, width %d, height %d, bitmap %p, content %p", - x,y,width,height,bitmap,content));*/ /* TODO here we should scale the image from bitmap->width to width, for * now simply crop. @@ -476,12 +474,17 @@ static bool fb_16bpp_bitmap(int x, int y, int width, int height, if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) return true; + + LOG(("%d, %d %d, %d bitmap %p, content %p", + x0,y0,x1,y1,bitmap,content)); + if (height > (y1 - y0)) height = (y1 - y0); if (width > (x1 - x0)) width = (x1 - x0); + xoff = x0 - x; yoff = (y0 - y) * bitmap->width; height = height * bitmap->width + yoff; diff --git a/framebuffer/fb_frontend_sdl.c b/framebuffer/fb_frontend_sdl.c index 7c83653ba..fc7ff3add 100644 --- a/framebuffer/fb_frontend_sdl.c +++ b/framebuffer/fb_frontend_sdl.c @@ -231,12 +231,12 @@ fb_os_redraw(struct bbox_s *box) /*LOG(("%d,%d-%d,%d %d,%d", box->x0, box->y0, box->x1, box->y1 , box->x1 - box->x0, box->y1 - box->y0));*/ - + /* if ((box->y1 - box->y0) < 0) { LOG(("WTF happened")); return; } - + */ SDL_UpdateRect(sdl_screen, box->x0, box->y0, diff --git a/framebuffer/fb_gui.c b/framebuffer/fb_gui.c index f256adfc6..e7db6c8d2 100644 --- a/framebuffer/fb_gui.c +++ b/framebuffer/fb_gui.c @@ -197,6 +197,7 @@ static void fb_pan(fbtk_widget_t *widget, fb_plotters_move_block(x + bwidget->panx, y, width - bwidget->panx, height, x, y); + bwidget->scrollx += bwidget->panx; fb_queue_redraw(widget, width - bwidget->panx, 0, width, height); } @@ -233,6 +234,7 @@ static void fb_redraw(fbtk_widget_t *widget, bwidget->redraw_box.x0 += x; bwidget->redraw_box.x1 += x; + /* redraw bounding box is relative to window */ content_redraw(c, x - bwidget->scrollx, y - bwidget->scrolly, @@ -241,6 +243,7 @@ static void fb_redraw(fbtk_widget_t *widget, bwidget->redraw_box.x1, bwidget->redraw_box.y1, bw->scale, 0xFFFFFF); + fb_os_redraw(&bwidget->redraw_box); bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX; @@ -261,6 +264,8 @@ fb_browser_window_redraw(fbtk_widget_t *widget, void *pw) fb_pan(widget, bwidget, gw->bw); pos = (bwidget->scrollx * 100) / gw->bw->current_content->width;; fbtk_set_scroll_pos(gw->hscroll, pos); + pos = (bwidget->scrolly * 100) / gw->bw->current_content->height; + fbtk_set_scroll_pos(gw->vscroll, pos); } @@ -529,6 +534,20 @@ fb_scrollr_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, vo } static int +fb_scrollu_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) +{ + fbtk_input(widget, KEY_UP); + return 0; +} + +static int +fb_scrolld_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) +{ + fbtk_input(widget, KEY_DOWN); + return 0; +} + +static int fb_url_enter(void *pw, char *text) { struct browser_window *bw = pw; @@ -573,6 +592,7 @@ gui_create_browser_window(struct browser_window *bw, fbtk_widget_t *widget; int top = 0; int bot = 0; + int right = 0; gw = calloc(1, sizeof(struct gui_window)); @@ -590,8 +610,8 @@ gui_create_browser_window(struct browser_window *bw, gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0); top = 30; - bot = -50; - + bot = 20; + right = 18; LOG(("Normal window")); /* fill toolbar background */ @@ -637,25 +657,64 @@ gui_create_browser_window(struct browser_window *bw, * scrollbar */ gw->status = fbtk_create_text(gw->window, - 0 , fbtk_get_height(gw->window) - 20, - fbtk_get_width(gw->window) - 200, 20, + 0 , + fbtk_get_height(gw->window) - bot, + fbtk_get_width(gw->window) - 200 - right, + bot, FB_FRAME_COLOUR, FB_COLOUR_BLACK, false); fbtk_set_handler_move(gw->status, set_ptr_default_move, bw); - - fbtk_create_button(gw->window, fbtk_get_width(gw->window) - 200, fbtk_get_height(gw->window) - 20, FB_FRAME_COLOUR, &scrolll, fb_scrolll_click, bw); - fbtk_create_button(gw->window, fbtk_get_width(gw->window) - 20, fbtk_get_height(gw->window) - 20, FB_FRAME_COLOUR, &scrollr, fb_scrollr_click, bw); + /* horizontal scrollbar */ + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - 200 - right, + fbtk_get_height(gw->window) - bot, + FB_FRAME_COLOUR, + &scrolll, + fb_scrolll_click, + bw); + + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - 20 - right, + fbtk_get_height(gw->window) - bot, + FB_FRAME_COLOUR, + &scrollr, + fb_scrollr_click, + bw); gw->hscroll = fbtk_create_hscroll(gw->window, - fbtk_get_width(gw->window) - 180, - fbtk_get_height(gw->window) - 20, + fbtk_get_width(gw->window) - 160 - 20 - right, + fbtk_get_height(gw->window) - bot, 160, - 20, + bot, FB_SCROLL_COLOUR, FB_FRAME_COLOUR); - + /* create vertical */ + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - right, + top, + FB_FRAME_COLOUR, + &scrollu, + fb_scrollu_click, + bw); + + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - right, + fbtk_get_height(gw->window) - bot - 20, + FB_FRAME_COLOUR, + &scrolld, + fb_scrolld_click, + bw); + + gw->vscroll = fbtk_create_vscroll(gw->window, + fbtk_get_width(gw->window) - right, + top + 20, + right, + fbtk_get_height(gw->window) - top - bot - 40 , + FB_SCROLL_COLOUR, + FB_FRAME_COLOUR); + break; case BROWSER_WINDOW_FRAME: @@ -671,7 +730,7 @@ gui_create_browser_window(struct browser_window *bw, browser_widget = calloc(1, sizeof(struct browser_widget_s)); - gw->browser = fbtk_create_user(gw->window, 0, top, 0, bot, browser_widget); + gw->browser = fbtk_create_user(gw->window, 0, top, -right, - (bot + top), browser_widget); fbtk_set_handler_click(gw->browser, fb_browser_window_click, bw); fbtk_set_handler_input(gw->browser, fb_browser_window_input, gw); @@ -796,6 +855,10 @@ void gui_window_update_extent(struct gui_window *g) pct = (fbtk_get_width(g->browser) * 100) / g->bw->current_content->width; fbtk_set_scroll(g->hscroll, pct); + + pct = (fbtk_get_height(g->browser) * 100) / g->bw->current_content->height; + fbtk_set_scroll(g->vscroll, pct); + } void gui_window_set_status(struct gui_window *g, const char *text) diff --git a/framebuffer/fb_gui.h b/framebuffer/fb_gui.h index e064ede56..f9b40f7c8 100644 --- a/framebuffer/fb_gui.h +++ b/framebuffer/fb_gui.h @@ -46,6 +46,7 @@ struct gui_window { struct fbtk_widget_s *status; struct fbtk_widget_s *throbber; struct fbtk_widget_s *hscroll; + struct fbtk_widget_s *vscroll; struct fbtk_widget_s *browser; int throbber_index; }; diff --git a/framebuffer/fb_image_data.h b/framebuffer/fb_image_data.h index 9f6c3a0ee..a353d65a7 100644 --- a/framebuffer/fb_image_data.h +++ b/framebuffer/fb_image_data.h @@ -27,6 +27,8 @@ extern struct bitmap reload; extern struct bitmap stop_image; extern struct bitmap scrolll; extern struct bitmap scrollr; +extern struct bitmap scrollu; +extern struct bitmap scrolld; extern struct bitmap pointer_image; extern struct bitmap hand_image; diff --git a/framebuffer/fb_plotters.c b/framebuffer/fb_plotters.c index dc3172a21..46ef82a95 100644 --- a/framebuffer/fb_plotters.c +++ b/framebuffer/fb_plotters.c @@ -61,7 +61,8 @@ enum { /* clip a rectangle to another rectangle */ bool fb_plotters_clip_rect(const bbox_t * restrict clip, - int * restrict x0, int * restrict y0, int * restrict x1, int * restrict y1) + int * restrict x0, int * restrict y0, + int * restrict x1, int * restrict y1) { char region1; char region2; @@ -459,11 +460,20 @@ bool fb_plotters_move_block(int srcx, int srcy, int width, int height, int dstx, /* take shortcut and use memmove */ memmove(dstptr, srcptr, (width * height * framebuffer->bpp) / 8); } else { - - for (hloop = height; hloop > 0; hloop--) { - memmove(dstptr, srcptr, (width * framebuffer->bpp) / 8); - srcptr += framebuffer->linelen; - dstptr += framebuffer->linelen; + if (srcy > dsty) { + for (hloop = height; hloop > 0; hloop--) { + memmove(dstptr, srcptr, (width * framebuffer->bpp) / 8); + srcptr += framebuffer->linelen; + dstptr += framebuffer->linelen; + } + } else { + srcptr += height * framebuffer->linelen; + dstptr += height * framebuffer->linelen; + for (hloop = height; hloop > 0; hloop--) { + srcptr -= framebuffer->linelen; + dstptr -= framebuffer->linelen; + memmove(dstptr, srcptr, (width * framebuffer->bpp) / 8); + } } } /* callback to the os specific routine in case it needs to do something diff --git a/framebuffer/fb_tk.c b/framebuffer/fb_tk.c index e2e9a80a1..3b8f4b8d7 100644 --- a/framebuffer/fb_tk.c +++ b/framebuffer/fb_tk.c @@ -43,6 +43,7 @@ enum fbtk_widgettype_e { FB_WIDGET_TYPE_FILL, FB_WIDGET_TYPE_TEXT, FB_WIDGET_TYPE_HSCROLL, + FB_WIDGET_TYPE_VSCROLL, FB_WIDGET_TYPE_USER, }; @@ -127,6 +128,61 @@ struct fbtk_widget_list_s { fbtk_widget_t *widget; } ; +enum { + POINT_LEFTOF_REGION = 1, + POINT_RIGHTOF_REGION = 2, + POINT_ABOVE_REGION = 4, + POINT_BELOW_REGION = 8, +}; + +#define REGION(x,y,cx1,cx2,cy1,cy2) \ + (( (y) > (cy2) ? POINT_BELOW_REGION : 0) | \ + ( (y) < (cy1) ? POINT_ABOVE_REGION : 0) | \ + ( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) | \ + ( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) ) + +#define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t; } while(0) + +/* clip a rectangle to another rectangle */ +bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box) +{ + uint8_t region1; + uint8_t region2; + + if (box->x1 < box->x0) SWAP(box->x0, box->x1); + if (box->y1 < box->y0) SWAP(box->y0, box->y1); + + region1 = REGION(box->x0, box->y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); + region2 = REGION(box->x1, box->y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); + + /* area lies entirely outside the clipping rectangle */ + if ((region1 | region2) && (region1 & region2)) + return false; + + if (box->x0 < clip->x0) + box->x0 = clip->x0; + if (box->x0 > clip->x1) + box->x0 = clip->x1; + + if (box->x1 < clip->x0) + box->x1 = clip->x0; + if (box->x1 > clip->x1) + box->x1 = clip->x1; + + if (box->y0 < clip->y0) + box->y0 = clip->y0; + if (box->y0 > clip->y1) + box->y0 = clip->y1; + + if (box->y1 < clip->y0) + box->y1 = clip->y0; + if (box->y1 > clip->y1) + box->y1 = clip->y1; + + return true; +} + + /* creates a new widget of a given type */ static fbtk_widget_t * new_widget(enum fbtk_widgettype_e type) @@ -244,17 +300,19 @@ fbtk_redraw_widget(fbtk_widget_t *widget) /* set the clipping rectangle to the widget area */ saved_plot_ctx = fb_plot_ctx; - fb_plot_ctx.x0 = widget->x; - fb_plot_ctx.y0 = widget->y; - fb_plot_ctx.x1 = widget->x + widget->width; - fb_plot_ctx.y1 = widget->y + widget->height; + fb_plot_ctx.x0 = fbtk_get_x(widget); + fb_plot_ctx.y0 = fbtk_get_y(widget); + fb_plot_ctx.x1 = fb_plot_ctx.x0 + widget->width; + fb_plot_ctx.y1 = fb_plot_ctx.y0 + widget->height; - /* do our drawing according to type */ - widget->redraw(widget, widget->redrawpw); + if (fbtk_clip_rect(&saved_plot_ctx, &fb_plot_ctx )) { + /* do our drawing according to type */ + widget->redraw(widget, widget->redrawpw); - widget->redraw_required = false; - //LOG(("OS redrawing %d,%d %d,%d", fb_plot_ctx.x0, fb_plot_ctx.y0, fb_plot_ctx.x1, fb_plot_ctx.y1)); - fb_os_redraw(&fb_plot_ctx); + widget->redraw_required = false; + //LOG(("OS redrawing %d,%d %d,%d", fb_plot_ctx.x0, fb_plot_ctx.y0, fb_plot_ctx.x1, fb_plot_ctx.y1)); + fb_os_redraw(&fb_plot_ctx); + } /* restore clipping rectangle */ fb_plot_ctx = saved_plot_ctx; @@ -313,6 +371,42 @@ fb_redraw_hscroll(fbtk_widget_t *widget, void *pw) } static int +fb_redraw_vscroll(fbtk_widget_t *widget, void *pw) +{ + int vscroll; + int vpos; + + plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, + fb_plot_ctx.x1, fb_plot_ctx.y1, + widget->bg); + + plot.fill(fb_plot_ctx.x0 + 1, + fb_plot_ctx.y0 + 3, + fb_plot_ctx.x1 - 1, + fb_plot_ctx.y1 - 3, + widget->fg); + + plot.rectangle(fb_plot_ctx.x0, + fb_plot_ctx.y0 + 2, + fb_plot_ctx.x1 - fb_plot_ctx.x0 - 1, + fb_plot_ctx.y1 - fb_plot_ctx.y0 - 5, + 1, 0xFF000000, false, false); + + vscroll = ((widget->height - 4) * widget->u.scroll.pct) / 100 ; + vpos = ((widget->height - 4) * widget->u.scroll.pos) / 100 ; + + LOG(("scroll %d",vscroll)); + + plot.fill(fb_plot_ctx.x0 + 3, + fb_plot_ctx.y0 + 5 + vpos, + fb_plot_ctx.x0 + widget->width - 3, + fb_plot_ctx.y0 + vscroll + vpos - 5, + widget->bg); + + return 0; +} + +static int fb_redraw_bitmap(fbtk_widget_t *widget, void *pw) { /* clear background */ @@ -324,7 +418,8 @@ fb_redraw_bitmap(fbtk_widget_t *widget, void *pw) } /* plot the image */ - plot.bitmap(widget->x, widget->y, widget->width, widget->height, + plot.bitmap(fb_plot_ctx.x0, fb_plot_ctx.y0, + widget->width, widget->height, widget->u.bitmap.bitmap, 0, NULL); return 0; } @@ -600,23 +695,30 @@ fbtk_set_text(fbtk_widget_t *widget, const char *text) void fbtk_set_scroll(fbtk_widget_t *widget, int pct) { - if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_HSCROLL)) + 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); + widget->u.scroll.pct = pct; + fbtk_request_redraw(widget); + } } void fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos) { - if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_HSCROLL)) + 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); + } } void @@ -741,6 +843,8 @@ fbtk_redraw(fbtk_widget_t *widget) { fbtk_widget_t *root; fbtk_widget_t *window; + bbox_t saved_plot_ctx; + /* ensure we have the root widget */ root = get_root_widget(widget); @@ -748,9 +852,17 @@ fbtk_redraw(fbtk_widget_t *widget) if (!root->redraw_required) return 0; + /* set the clipping rectangle to the widget area */ + saved_plot_ctx = fb_plot_ctx; + /* get the root window */ window = root->u.root.rootw; + fb_plot_ctx.x0 = window->x; + fb_plot_ctx.y0 = window->y; + fb_plot_ctx.x1 = window->x + window->width; + fb_plot_ctx.y1 = window->y + window->height; + fb_cursor_clear(root->u.root.fb); if (window->redraw != NULL) @@ -758,6 +870,8 @@ fbtk_redraw(fbtk_widget_t *widget) root->redraw_required = false; + fb_plot_ctx = saved_plot_ctx; + fb_cursor_plot(root->u.root.fb); return 1; @@ -880,6 +994,23 @@ fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, } fbtk_widget_t * +fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_VSCROLL); + + neww->x = x; + neww->y = y; + neww->width = width; + neww->height = height; + neww->fg = fg; + neww->bg = bg; + + neww->redraw = fb_redraw_vscroll; + + return add_widget_to_window(window, neww); +} + +fbtk_widget_t * fbtk_create_button(fbtk_widget_t *window, int x, int y, colour c, diff --git a/framebuffer/fb_tk.h b/framebuffer/fb_tk.h index a3b744b4f..965157b97 100644 --- a/framebuffer/fb_tk.h +++ b/framebuffer/fb_tk.h @@ -88,6 +88,16 @@ fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, col fbtk_widget_t * fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg); +/** Create a vertical scroll widget + * + * Create a vertical scroll widget. + * + * @param window The window to add the filled area widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t * +fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg); + /** Create a user widget. * * Create a widget which is to be handled entirely by the calling application. diff --git a/framebuffer/res/icons/scrolld.png b/framebuffer/res/icons/scrolld.png Binary files differnew file mode 100644 index 000000000..6ba28da99 --- /dev/null +++ b/framebuffer/res/icons/scrolld.png diff --git a/framebuffer/res/icons/scrollu.png b/framebuffer/res/icons/scrollu.png Binary files differnew file mode 100644 index 000000000..3d605ca25 --- /dev/null +++ b/framebuffer/res/icons/scrollu.png |