1
0
Эх сурвалжийг харах

add scrollbar widget.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@832 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 14 жил өмнө
parent
commit
8510a938dd

+ 77 - 0
components/rtgui/include/rtgui/widgets/scrollbar.h

@@ -0,0 +1,77 @@
+#ifndef __RTGUI_SCROLLBAR_H__
+#define __RTGUI_SCROLLBAR_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/widget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Gets the type of a scrollbar */
+#define RTGUI_SCROLLBAR_TYPE       (rtgui_scrollbar_type_get())
+/** Casts the object to an rtgui_scrollbar */
+#define RTGUI_SCROLLBAR(obj)       (RTGUI_OBJECT_CAST((obj), RTGUI_SCROLLBAR_TYPE, rtgui_scrollbar_t))
+/** Checks if the object is an rtgui_scrollbar */
+#define RTGUI_IS_SCROLLBAR(obj)    (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_SCROLLBAR_TYPE))
+
+#define RTGUI_DEFAULT_SB_WIDTH				100
+#define RTGUI_DEFAULT_SB_HEIGHT				16
+
+/* scrollbar status/positions*/
+#define SBS_UNKNOWN         0x0000
+#define SBS_LEFTARROW       0x0001
+#define SBS_RIGHTARROW      0x0002
+#define SBS_LEFTSPACE       0x0004
+#define SBS_RIGHTSPACE      0x0008
+#define SBS_HORZTHUMB       0x0010
+#define SBS_UPARROW         0x0020
+#define SBS_DOWNARROW       0x0040
+#define SBS_UPSPACE         0x0080
+#define SBS_DOWNSPACE       0x0100
+#define SBS_VERTTHUMB       0x0200
+
+struct rtgui_scrollbar
+{
+	/* inherit from widget */
+	struct rtgui_widget parent;
+
+	rt_uint8_t orient;
+	rt_uint8_t status;
+
+	/* page_step = width of scrollbar */
+	/* thumb size = line_step * page_step / (page_step - (button width * 2)) */
+	rt_int16_t line_step, page_step;
+
+	rt_int16_t thumb_position, thumb_size;
+
+	/* position 1:1 width of scrollbar */
+	rt_int16_t min_position, max_position;
+
+	rt_int16_t bar_width;
+
+	rt_bool_t (*on_scroll) (struct rtgui_widget* widget, struct rtgui_event* event);
+};
+typedef struct rtgui_scrollbar rtgui_scrollbar_t;
+
+rtgui_type_t *rtgui_scrollbar_type_get(void);
+
+struct rtgui_scrollbar* rtgui_scrollbar_create(int orient, rtgui_rect_t* r);
+void rtgui_scrollbar_destroy(struct rtgui_scrollbar* bar);
+
+void rtgui_scrollbar_set_range(struct rtgui_scrollbar* bar, int min, int max);
+rt_int16_t rtgui_scrollbar_get_value(struct rtgui_scrollbar* bar);
+void rtgui_scrollbar_set_value(struct rtgui_scrollbar* bar, rt_int16_t position);
+
+void rtgui_scrollbar_set_onscroll(struct rtgui_scrollbar* bar, rtgui_event_handler_ptr handler);
+void rtgui_scrollbar_set_orientation(struct rtgui_scrollbar* bar, int orientation);
+void rtgui_scrollbar_set_page_step(struct rtgui_scrollbar* bar, int step);
+void rtgui_scrollbar_set_line_step(struct rtgui_scrollbar* bar, int step);
+
+rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 520 - 0
components/rtgui/widgets/scrollbar.c

@@ -0,0 +1,520 @@
+#include <rtgui/dc.h>
+#include <rtgui/widgets/scrollbar.h>
+
+static void _rtgui_scrollbar_constructor(rtgui_scrollbar_t *bar)
+{
+	struct rtgui_rect rect = {0, 0, RTGUI_DEFAULT_SB_WIDTH, RTGUI_DEFAULT_SB_HEIGHT};
+
+	/* set event handler */
+	rtgui_widget_set_event_handler(RTGUI_WIDGET(bar), rtgui_scrollbar_event_handler);
+
+	rtgui_scrollbar_set_range(bar, 0, 100);
+	rtgui_scrollbar_set_page_step(bar, 20);
+	rtgui_scrollbar_set_line_step(bar, 10);
+
+	bar->thumb_position = 0;
+	bar->thumb_size = 16;
+	bar->on_scroll = RT_NULL;
+
+	bar->orient = RTGUI_HORIZONTAL;
+	bar->bar_width = RTGUI_DEFAULT_SB_HEIGHT;
+	rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
+
+	/* set gc */
+	RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+rt_inline rt_uint32_t _rtgui_scrollbar_get_length(rtgui_scrollbar_t *bar)
+{
+	struct rtgui_rect rect;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
+
+	if (bar->orient & RTGUI_VERTICAL)
+		return rect.y2 - 2 * (rect.x2 - rect.x1);
+
+	return rect.x2 - 2 * (rect.y2 - rect.y1);
+}
+
+rt_inline rt_uint32_t _rtgui_scrollbar_get_thumb_position(rtgui_scrollbar_t* bar)
+{
+	rt_uint32_t thumb_position;
+
+	/* calculate thumb position */
+	thumb_position = (rtgui_scrollbar_get_value(bar) - bar->min_position) * _rtgui_scrollbar_get_length(bar) / 
+		(bar->max_position - bar->min_position);
+
+	return thumb_position;
+}
+
+rt_inline void _rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *rect)
+{
+	struct rtgui_rect scrollbar_rect;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &scrollbar_rect);
+	if (bar->orient & RTGUI_VERTICAL)
+	{
+		rt_uint32_t btn_width = scrollbar_rect.x2 - scrollbar_rect.x1;
+
+		/* vertical scroll bar */
+		rect->x1 = scrollbar_rect.x1;
+		rect->x2 = scrollbar_rect.x2;
+		rect->y1 = scrollbar_rect.y1 + btn_width + _rtgui_scrollbar_get_thumb_position(bar);
+		rect->y2 = rect->y1 + btn_width;
+	}
+	else
+	{
+		rt_uint32_t btn_height = scrollbar_rect.y2 - scrollbar_rect.y1;
+
+		/* horizontal scroll bar */
+		rect->x1 = scrollbar_rect.x1 + btn_height + _rtgui_scrollbar_get_thumb_position(bar);
+		rect->x2 = rect->x1 + btn_height;
+
+		rect->y1 = scrollbar_rect.y1;
+		rect->y2 = scrollbar_rect.y2;
+	}
+}
+
+rtgui_type_t *rtgui_scrollbar_type_get(void)
+{
+	static rtgui_type_t *scrollbar_type = RT_NULL;
+
+	if (!scrollbar_type)
+	{
+		scrollbar_type = rtgui_type_create("scrollbar", RTGUI_WIDGET_TYPE,
+			sizeof(rtgui_scrollbar_t), RTGUI_CONSTRUCTOR(_rtgui_scrollbar_constructor), RT_NULL);
+	}
+
+	return scrollbar_type;
+}
+
+static void _rtgui_scrollbar_ondraw(struct rtgui_scrollbar* bar);
+static void _rtgui_scrollbar_on_mouseclick(struct rtgui_widget * widget, struct rtgui_event * event);
+
+rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_widget * widget,
+	struct rtgui_event * event)
+{
+	struct rtgui_scrollbar* bar = (struct rtgui_scrollbar*)widget;
+
+	switch (event->type)
+	{
+    	case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+    		if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+    		else
+#endif
+    		{
+    			_rtgui_scrollbar_ondraw(bar);
+    		}
+
+    		break;
+
+        case RTGUI_EVENT_MOUSE_BUTTON:
+			if (RTGUI_WIDGET_IS_ENABLE(widget))
+			{
+#ifndef RTGUI_USING_SMALL_SIZE
+				if (widget->on_mouseclick != RT_NULL)
+				{
+					widget->on_mouseclick(widget, event);
+				}
+				else
+#endif
+				{
+					_rtgui_scrollbar_on_mouseclick(widget, event);
+				}
+			}
+
+            break;
+
+        default:
+            break;
+	}
+
+	return RT_FALSE;
+}
+
+static void _rtgui_scrollbar_on_mouseclick(struct rtgui_widget * widget, struct rtgui_event * event)
+{
+	rtgui_rect_t btn_rect, bar_rect;
+	rt_uint32_t thumb_size, thumb_position;
+    struct rtgui_scrollbar* bar = (struct rtgui_scrollbar*)widget;
+    struct rtgui_event_mouse* mouse = (struct rtgui_event_mouse*)event;
+
+	/* get the thumb size and position */
+	thumb_size = bar->thumb_size * (bar->max_position - bar->min_position) / _rtgui_scrollbar_get_length(bar);
+	thumb_position = _rtgui_scrollbar_get_thumb_position(bar);
+
+    if (bar->orient == RTGUI_VERTICAL)
+    {
+		/* get up arrow button rect */
+		btn_rect.x1 = widget->extent.x1;
+		btn_rect.x2 = widget->extent.x2;
+		btn_rect.y1 = widget->extent.y1;
+		btn_rect.y2 = widget->extent.y1 + (widget->extent.x2 - widget->extent.x1);
+        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_UPARROW;
+
+				/* line step */
+				bar->thumb_position -= bar->line_step;
+				if (bar->thumb_position < bar->min_position) bar->thumb_position = bar->min_position;
+            }
+            else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+			{
+                bar->status = 0;
+			}
+			goto __exit;
+        }
+
+		/* get bar rect */
+		bar_rect.x1 = widget->extent.x1;
+		bar_rect.x2 = widget->extent.x2;
+		bar_rect.y1 = widget->extent.y1 + (widget->extent.x2 - widget->extent.x1);
+		bar_rect.y2 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
+        if (rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+			if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+				/* page step */
+				if (mouse->y < bar_rect.y1 + thumb_position)
+				{
+					bar->thumb_position -= bar->page_step;
+					if (bar->thumb_position < bar->min_position)					
+						bar->thumb_position = bar->min_position;
+				}
+				else if (mouse->y > thumb_position + bar->thumb_size)
+				{
+					bar->thumb_position += bar->page_step;
+					if (bar->thumb_position > bar->max_position - thumb_size)
+						bar->thumb_position = bar->max_position - thumb_size;
+				}
+            }
+			goto __exit;
+        }
+
+		/* get down arrow button rect */
+        btn_rect.y1 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
+        btn_rect.y2 = widget->extent.y2;
+        bar_rect.y1 = widget->extent.y1 + ((widget->extent.y2 - widget->extent.y1)/2);
+        bar_rect.y2 = widget->extent.y2 - (widget->extent.x2 - widget->extent.x1);
+        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_DOWNARROW;
+
+				/* line step */
+				bar->thumb_position += bar->line_step;
+				if (bar->thumb_position > bar->max_position - thumb_size)
+					bar->thumb_position = bar->max_position - thumb_size;
+            }
+            else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+                bar->status = 0;
+        }
+    }
+    else
+    {
+		/* get left arrow button rect */
+		btn_rect.x1 = widget->extent.x1;
+		btn_rect.x2 = widget->extent.x1 + (widget->extent.y2 - widget->extent.y1);
+		btn_rect.y1 = widget->extent.y1;
+		btn_rect.y2 = widget->extent.y2;
+        if (rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_LEFTARROW;
+
+				/* line step */
+				bar->thumb_position -= bar->line_step;
+				if (bar->thumb_position < bar->min_position) bar->thumb_position = bar->min_position;
+            }
+             else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+                bar->status = 0;
+			goto __exit;
+       }
+
+		/* get bar rect */
+		bar_rect.x1 = widget->extent.x1 + (widget->extent.y2 - widget->extent.y1);
+		bar_rect.x2 = widget->extent.x2 - (widget->extent.x2 - widget->extent.x1);
+		bar_rect.y1 = widget->extent.y1;
+		bar_rect.y2 = widget->extent.y2;
+        if (rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+				/* page step */
+				if (mouse->x <  bar_rect.x1 + thumb_position)
+				{
+					bar->thumb_position -= bar->page_step;
+					if (bar->thumb_position < bar->min_position)					
+						bar->thumb_position = bar->min_position;
+				}
+				else if (mouse->x > thumb_position + bar->thumb_size)
+				{
+					bar->thumb_position += bar->page_step;
+					if (bar->thumb_position > bar->max_position - thumb_size)
+						bar->thumb_position = bar->max_position - thumb_size;
+				}
+            }
+			goto __exit;
+        }
+
+		/* get right arrow button rect */
+        btn_rect.x1 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
+        btn_rect.x2 = widget->extent.x2;
+        bar_rect.x1 = widget->extent.x1 + ((widget->extent.x2 - widget->extent.x1)/2);
+        bar_rect.x2 = widget->extent.x2 - (widget->extent.y2 - widget->extent.y1);
+        if (rtgui_rect_contains_point(&btn_rect,
+                            mouse->x, mouse->y) == RT_EOK)
+        {
+            if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+				(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+            {
+                bar->status |= SBS_RIGHTARROW;
+
+				/* line step */
+				bar->thumb_position += bar->line_step;
+				if (bar->thumb_position > bar->max_position - bar->line_step)
+					bar->thumb_position = bar->max_position - bar->line_step;
+            }
+             else if (mouse->button & RTGUI_MOUSE_BUTTON_UP)
+                bar->status = 0;
+        }
+    }
+
+__exit:
+    _rtgui_scrollbar_ondraw(bar);
+	if ((mouse->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN)) ==
+		(RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_DOWN))
+	{
+		if (bar->on_scroll != RT_NULL) bar->on_scroll(widget, RT_NULL);
+	}
+}
+
+static void _rtgui_scrollbar_ondraw(struct rtgui_scrollbar* bar)
+{
+	/* draw scroll bar */
+	struct rtgui_dc* dc;
+	struct rtgui_rect rect;
+	int vx[4], vy[4];
+
+	/* begin drawing */
+	dc = rtgui_dc_begin_drawing(&(bar->parent));
+	if (dc == RT_NULL) return;
+
+	rtgui_widget_get_rect(RTGUI_WIDGET(bar), &rect);
+
+	/* draw background */
+	RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(236, 236, 229);
+	rtgui_dc_fill_rect(dc, &rect);
+
+    if (bar->orient == RTGUI_VERTICAL)
+    {
+        rtgui_rect_t btn_rect, thum_rect;
+
+		btn_rect = rect;
+		btn_rect.y2 = btn_rect.y1 + rect.x2 - rect.x1;
+		
+		/* draw up button */
+		if (bar->status & SBS_UPARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
+		else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
+
+		/* draw arrow */
+		if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
+			RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(201, 201, 194);
+		vx[0] = 0; vy[0] = 0;
+		vx[1] = rtgui_rect_width(rect); vy[1] = 0;
+		vx[2] = vx[1] / 2; vy[2] = 8;
+		vx[3] = 0; vy[3] = 0;
+		rtgui_dc_fill_polygon(dc, vx, vy, 4);
+		// rtgui_dc_draw_arrow(dc, &btn_rect, RTGUI_ARRAW_UP);
+
+		/* draw thumb */
+		if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
+		{
+			_rtgui_scrollbar_get_thumb_rect(bar, &thum_rect);
+			rtgui_dc_draw_border(dc, &thum_rect, RTGUI_BORDER_RAISE);
+		}
+
+		/* draw down button */
+        btn_rect.y1 = rect.y2 - (rect.x2 - rect.x1);
+        btn_rect.y2 = rect.y2;
+
+		if (bar->status & SBS_DOWNARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
+		else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
+
+		if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
+			RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(201, 201, 194);
+
+		vx[0] = 0; vy[0] = rtgui_rect_height(rect);
+		vx[1] = rtgui_rect_width(rect); vy[1] = rtgui_rect_height(rect);
+		vx[2] = vx[1] / 2; vy[2] = rtgui_rect_height(rect) - 8;
+		vx[0] = 0; vy[0] = rtgui_rect_height(rect);
+		rtgui_dc_fill_polygon(dc, vx, vy, 4);
+		// rtgui_dc_draw_arrow(dc, &btn_rect, RTGUI_ARRAW_DOWN);
+    }
+    else
+    {
+        rtgui_rect_t btn_rect, thum_rect;
+
+        btn_rect.x1 = rect.x1;
+        btn_rect.x2 = rect.y2;
+        btn_rect.y1 = rect.y1;
+        btn_rect.y2 = rect.y2;
+
+		/* draw left button */
+		if (bar->status & SBS_LEFTARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
+		else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
+
+		if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
+			RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(201, 201, 194);
+
+		vx[0] = 0; vy[0] = 0;
+		vx[1] = 0; vy[1] = rtgui_rect_height(rect);
+		vx[2] = 8; vy[2] = rtgui_rect_height(rect)/2;
+		vx[3] = 0; vy[3] = 0;
+		rtgui_dc_fill_polygon(dc, vx, vy, 4);
+		// rtgui_dc_draw_arrow(dc, &btn_rect, RTGUI_ARRAW_LEFT);
+
+		/* draw thumb */
+		if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
+		{
+			_rtgui_scrollbar_get_thumb_rect(bar, &thum_rect);
+			rtgui_dc_draw_border(dc, &thum_rect, RTGUI_BORDER_RAISE);
+		}
+
+        btn_rect.x1 = rect.x2 - rect.y2;
+        btn_rect.x2 = rect.x2;
+
+		/* draw right button */
+		if (bar->status & SBS_RIGHTARROW) rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_SUNKEN);
+		else rtgui_dc_draw_border(dc, &btn_rect, RTGUI_BORDER_RAISE);
+
+		if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar)))
+			RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(bar)) = RTGUI_RGB(201, 201, 194);
+		vx[0] = rtgui_rect_width(rect); vy[0] = 0;
+		vx[1] = rtgui_rect_width(rect) - 8; vy[1] = rtgui_rect_height(rect)/2;
+		vx[2] = rtgui_rect_width(rect); vy[2] = rtgui_rect_height(rect);
+		vx[0] = rtgui_rect_width(rect); vy[0] = 0;
+		rtgui_dc_fill_polygon(dc, vx, vy, 4);
+		// rtgui_dc_draw_arrow(dc, &btn_rect, RTGUI_ARRAW_RIGHT);
+    }
+
+	/* end drawing */
+	rtgui_dc_end_drawing(dc);
+	return;
+}
+
+struct rtgui_scrollbar* rtgui_scrollbar_create(int orient, rtgui_rect_t* r)
+{
+    struct rtgui_scrollbar* bar;
+
+    bar = (struct rtgui_scrollbar*) rtgui_widget_create (RTGUI_SCROLLBAR_TYPE);
+    if (bar != RT_NULL)
+    {
+		if (r != RT_NULL)
+			rtgui_widget_set_rect(RTGUI_WIDGET(bar), r);
+
+		bar->orient = orient;
+    }
+
+    return bar;
+}
+
+void rtgui_scrollbar_destroy(struct rtgui_scrollbar* bar)
+{
+	rtgui_widget_destroy(RTGUI_WIDGET(bar));
+}
+
+void rtgui_scrollbar_set_orientation(rtgui_scrollbar_t* bar, int orientation)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->orient = orientation;
+	bar->bar_width = RTGUI_DEFAULT_SB_HEIGHT;
+#ifndef RTGUI_USING_SMALL_SIZE
+	if (bar->orient == RTGUI_HORIZONTAL)
+	{
+		/* horizontal */
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_WIDTH);
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_HEIGHT);
+	}
+	else 
+	{
+		/* vertical */
+		rtgui_widget_set_miniwidth(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_HEIGHT);
+		rtgui_widget_set_miniheight(RTGUI_WIDGET(bar), RTGUI_DEFAULT_SB_WIDTH);
+	}
+#endif
+}
+
+void rtgui_scrollbar_set_range(struct rtgui_scrollbar* bar, int min, int max)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	if (min >= max )
+	{
+		RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar));
+		return;
+	}
+
+	bar->min_position = (rt_int16_t)min;
+	bar->max_position = (rt_int16_t)max;
+}
+
+void rtgui_scrollbar_set_page_step(struct rtgui_scrollbar* bar, int step)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->page_step = step;
+		
+	/* disable or enable scrollbar */
+	if (bar->page_step > (bar->max_position - bar->min_position))
+	{
+		/* disable bar */
+		RTGUI_WIDGET_DISABLE(RTGUI_WIDGET(bar));
+	}
+	else
+	{
+		/* enable bar */
+		RTGUI_WIDGET_ENABLE(RTGUI_WIDGET(bar));
+	}
+}
+
+void rtgui_scrollbar_set_line_step(struct rtgui_scrollbar* bar, int step)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->line_step = step;
+}
+
+rt_int16_t rtgui_scrollbar_get_value(struct rtgui_scrollbar* bar)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	return bar->thumb_position;
+}
+
+void rtgui_scrollbar_set_value(struct rtgui_scrollbar* bar, rt_int16_t position)
+{
+	RT_ASSERT(bar != RT_NULL);
+
+	bar->thumb_position = position;
+	rtgui_widget_update(RTGUI_WIDGET(bar));
+}
+
+void rtgui_scrollbar_set_onscroll(struct rtgui_scrollbar* bar,
+								  rtgui_event_handler_ptr handler)
+{
+	if (bar == RT_NULL || handler == RT_NULL) return;
+
+	bar->on_scroll = handler;
+}

+ 5 - 8
components/rtgui/widgets/textbox.c

@@ -174,15 +174,12 @@ static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kb
 		else if (box->position != 0)
 		{
 			/* remove current character */
-			if (box->position != 0)
-			{
-				char *c;
+			char *c;
 
-				/* remove character */
-				for (c = &box->text[box->position - 1]; c[1] != '\0'; c++)
-					*c = c[1];
-				*c = '\0';
-			}
+			/* remove character */
+			for (c = &box->text[box->position - 1]; c[1] != '\0'; c++)
+				*c = c[1];
+			*c = '\0';
 			box->position --;
 		}
 	}