summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Sanders <vince@netsurf-browser.org>2009-03-22 14:34:56 +0000
committerVincent Sanders <vince@netsurf-browser.org>2009-03-22 14:34:56 +0000
commit8db32fc061dd4081dce43700db86eb7f6a7856b5 (patch)
tree0234ded268f14767c9f91f359a7b2f64f57595bb
parentc9fc91c6e4ced28336b3681a64a2a9fefaef2a4a (diff)
downloadnetsurf-8db32fc061dd4081dce43700db86eb7f6a7856b5.tar.gz
netsurf-8db32fc061dd4081dce43700db86eb7f6a7856b5.tar.bz2
add vertical scrollbar to freamebuffer
svn path=/trunk/netsurf/; revision=6817
-rw-r--r--Makefile.resources2
-rw-r--r--framebuffer/fb_16bpp_plotters.c7
-rw-r--r--framebuffer/fb_frontend_sdl.c4
-rw-r--r--framebuffer/fb_gui.c87
-rw-r--r--framebuffer/fb_gui.h1
-rw-r--r--framebuffer/fb_image_data.h2
-rw-r--r--framebuffer/fb_plotters.c22
-rw-r--r--framebuffer/fb_tk.c161
-rw-r--r--framebuffer/fb_tk.h10
-rw-r--r--framebuffer/res/icons/scrolld.pngbin0 -> 375 bytes
-rw-r--r--framebuffer/res/icons/scrollu.pngbin0 -> 358 bytes
11 files changed, 259 insertions, 37 deletions
diff --git a/Makefile.resources b/Makefile.resources
index f473544f2..009c111a9 100644
--- a/Makefile.resources
+++ b/Makefile.resources
@@ -20,6 +20,8 @@ FB_IMAGE_reload := framebuffer/res/icons/reload.png
FB_IMAGE_stop_image := framebuffer/res/icons/stop.png
FB_IMAGE_scrolll := framebuffer/res/icons/scrolll.png
FB_IMAGE_scrollr := framebuffer/res/icons/scrollr.png
+FB_IMAGE_scrollu := framebuffer/res/icons/scrollu.png
+FB_IMAGE_scrolld := framebuffer/res/icons/scrolld.png
FB_IMAGE_pointer_image := framebuffer/res/pointers/default.png
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
new file mode 100644
index 000000000..6ba28da99
--- /dev/null
+++ b/framebuffer/res/icons/scrolld.png
Binary files differ
diff --git a/framebuffer/res/icons/scrollu.png b/framebuffer/res/icons/scrollu.png
new file mode 100644
index 000000000..3d605ca25
--- /dev/null
+++ b/framebuffer/res/icons/scrollu.png
Binary files differ