summaryrefslogtreecommitdiff
path: root/components/rtgui/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'components/rtgui/widgets')
-rw-r--r--components/rtgui/widgets/about_view.c202
-rw-r--r--components/rtgui/widgets/box.c16
-rw-r--r--components/rtgui/widgets/button.c19
-rw-r--r--components/rtgui/widgets/checkbox.c299
-rw-r--r--components/rtgui/widgets/combobox.c535
-rw-r--r--components/rtgui/widgets/container.c159
-rw-r--r--components/rtgui/widgets/filelist_view.c1673
-rw-r--r--components/rtgui/widgets/iconbox.c11
-rw-r--r--components/rtgui/widgets/label.c11
-rw-r--r--components/rtgui/widgets/list_view.c1272
-rw-r--r--components/rtgui/widgets/listbox.c775
-rw-r--r--components/rtgui/widgets/listctrl.c853
-rw-r--r--components/rtgui/widgets/menu.c562
-rw-r--r--components/rtgui/widgets/notebook.c686
-rw-r--r--components/rtgui/widgets/progressbar.c205
-rw-r--r--components/rtgui/widgets/radiobox.c490
-rw-r--r--components/rtgui/widgets/scrollbar.c834
-rw-r--r--components/rtgui/widgets/slider.c507
-rw-r--r--components/rtgui/widgets/staticline.c160
-rw-r--r--components/rtgui/widgets/textbox.c26
-rw-r--r--components/rtgui/widgets/textview.c703
-rw-r--r--components/rtgui/widgets/toplevel.c80
-rw-r--r--components/rtgui/widgets/view.c214
-rw-r--r--components/rtgui/widgets/widget.c152
-rw-r--r--components/rtgui/widgets/window.c554
-rw-r--r--components/rtgui/widgets/workbench.c581
26 files changed, 5451 insertions, 6128 deletions
diff --git a/components/rtgui/widgets/about_view.c b/components/rtgui/widgets/about_view.c
index 45f9a9431e..6bc012b255 100644
--- a/components/rtgui/widgets/about_view.c
+++ b/components/rtgui/widgets/about_view.c
@@ -1,101 +1,101 @@
-/*
- * File : about_view.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-01-06 Bernard first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/about_view.h>
-
-static void _rtgui_about_view_constructor(struct rtgui_about_view *view)
-{
- /* default rect */
- struct rtgui_rect rect = {0, 0, 200, 200};
-
- /* set default widget rect and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(view),rtgui_about_view_event_handler);
- rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
-
- RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
- view->logo = RT_NULL;
- view->description = RT_NULL;
-
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(aboutview, "aboutview",
- RTGUI_VIEW_TYPE,
- _rtgui_about_view_constructor,
- RT_NULL,
- sizeof(struct rtgui_about_view));
-
-void rtgui_about_view_ondraw(struct rtgui_about_view* view)
-{
- struct rtgui_rect rect;
- struct rtgui_dc* dc;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- if (view->logo != RT_NULL)
- rtgui_image_blit(view->logo, dc, &rect);
-
- rect.y1 += view->logo->h + 5;
- if (view->description != RT_NULL)
- rtgui_dc_draw_text(dc, view->description, &rect);
-
- rect.y1 += rtgui_dc_get_gc(dc)->font->height;
- rtgui_dc_draw_hline(dc, rect.x1 + 3, rect.x2 - 3, rect.y1);
- RTGUI_DC_FC(dc) = white;
- rtgui_dc_draw_hline(dc, rect.x1 + 4, rect.x2 - 2, rect.y1 + 1);
-
- rtgui_dc_end_drawing(dc);
-}
-
-rt_bool_t rtgui_about_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_about_view* view = RT_NULL;
-
- view = RTGUI_ABOUT_VIEW(widget);
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- rtgui_about_view_ondraw(view);
- return RT_FALSE;
- }
-
- /* use view event handler */
- return rtgui_view_event_handler(widget, event);
-}
-
-rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description)
-{
- struct rtgui_about_view* view = RT_NULL;
-
- view = (struct rtgui_about_view*) rtgui_widget_create(RTGUI_ABOUT_VIEW_TYPE);
- if (view != RT_NULL)
- {
- view->logo = logo;
- view->description = description;
- }
-
- return view;
-}
-
-void rtgui_about_view_destroy(rtgui_about_view_t* view)
-{
- /* destroy view */
- rtgui_widget_destroy(RTGUI_WIDGET(view));
-}
+/*
+ * File : about_view.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-01-06 Bernard first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/about_view.h>
+
+static void _rtgui_about_view_constructor(struct rtgui_about_view *view)
+{
+ /* default rect */
+ struct rtgui_rect rect = {0, 0, 200, 200};
+
+ /* set default widget rect and set event handler */
+ rtgui_object_set_event_handler(RTGUI_OBJECT(view),rtgui_about_view_event_handler);
+ rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
+
+ RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ view->logo = RT_NULL;
+ view->description = RT_NULL;
+
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(aboutview, "aboutview",
+ RTGUI_CONTAINER_TYPE,
+ _rtgui_about_view_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_about_view));
+
+void rtgui_about_view_ondraw(struct rtgui_about_view* view)
+{
+ struct rtgui_rect rect;
+ struct rtgui_dc* dc;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ if (view->logo != RT_NULL)
+ rtgui_image_blit(view->logo, dc, &rect);
+
+ rect.y1 += view->logo->h + 5;
+ if (view->description != RT_NULL)
+ rtgui_dc_draw_text(dc, view->description, &rect);
+
+ rect.y1 += rtgui_dc_get_gc(dc)->font->height;
+ rtgui_dc_draw_hline(dc, rect.x1 + 3, rect.x2 - 3, rect.y1);
+ RTGUI_DC_FC(dc) = white;
+ rtgui_dc_draw_hline(dc, rect.x1 + 4, rect.x2 - 2, rect.y1 + 1);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+rt_bool_t rtgui_about_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event)
+{
+ struct rtgui_about_view* view = RT_NULL;
+
+ view = RTGUI_ABOUT_VIEW(widget);
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ rtgui_about_view_ondraw(view);
+ return RT_FALSE;
+ }
+
+ /* use view event handler */
+ return rtgui_container_event_handler(widget, event);
+}
+
+rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description)
+{
+ struct rtgui_about_view* view = RT_NULL;
+
+ view = (struct rtgui_about_view*) rtgui_widget_create(RTGUI_ABOUT_VIEW_TYPE);
+ if (view != RT_NULL)
+ {
+ view->logo = logo;
+ view->description = description;
+ }
+
+ return view;
+}
+
+void rtgui_about_view_destroy(rtgui_about_view_t* view)
+{
+ /* destroy view */
+ rtgui_widget_destroy(RTGUI_WIDGET(view));
+}
diff --git a/components/rtgui/widgets/box.c b/components/rtgui/widgets/box.c
index e5fc0e8318..860245c0db 100644
--- a/components/rtgui/widgets/box.c
+++ b/components/rtgui/widgets/box.c
@@ -18,23 +18,23 @@
static void _rtgui_box_constructor(rtgui_box_t *box)
{
/* init widget and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_box_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler);
RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT;
- rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_box_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler);
/* set proper of control */
box->orient = RTGUI_HORIZONTAL;
box->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
}
-DEFINE_CLASS_TYPE(box, "box",
+DEFINE_CLASS_TYPE(box, "box",
RTGUI_CONTAINER_TYPE,
_rtgui_box_constructor,
RT_NULL,
sizeof(struct rtgui_box));
-rt_bool_t rtgui_box_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_box_event_handler(struct rtgui_object *widget, rtgui_event_t *event)
{
struct rtgui_box* box = (struct rtgui_box*)widget;
@@ -48,7 +48,7 @@ rt_bool_t rtgui_box_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
break;
default:
- return rtgui_container_event_handler(RTGUI_WIDGET(box), event);
+ return rtgui_container_event_handler(RTGUI_OBJECT(box), event);
}
return RT_FALSE;
@@ -166,7 +166,8 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box)
size_event.y = rect->y1;
size_event.w = rect->x2 - rect->x1;
size_event.h = rect->y2 - rect->y1;
- widget->event_handler(widget, &size_event.parent);
+ RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
+ &size_event.parent);
/* point to next height */
next_y = rect->y2;
@@ -258,7 +259,8 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box)
size_event.y = rect->y1;
size_event.w = rect->x2 - rect->x1;
size_event.h = rect->y2 - rect->y1;
- widget->event_handler(widget, &size_event.parent);
+ RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget),
+ &size_event.parent);
/* point to next width */
next_x = rect->x2;
diff --git a/components/rtgui/widgets/button.c b/components/rtgui/widgets/button.c
index ecd4e24e87..a10d04ebbf 100644
--- a/components/rtgui/widgets/button.c
+++ b/components/rtgui/widgets/button.c
@@ -14,13 +14,13 @@
#include <rtgui/dc.h>
#include <rtgui/rtgui_theme.h>
#include <rtgui/widgets/button.h>
-#include <rtgui/widgets/toplevel.h>
+#include <rtgui/widgets/window.h>
static void _rtgui_button_constructor(rtgui_button_t *button)
{
/* init widget and set event handler */
RTGUI_WIDGET(button)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
- rtgui_widget_set_event_handler(RTGUI_WIDGET(button), rtgui_button_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(button), rtgui_button_event_handler);
/* un-press button */
button->flag = 0;
@@ -57,13 +57,16 @@ DEFINE_CLASS_TYPE(button, "button",
_rtgui_button_destructor,
sizeof(struct rtgui_button));
-rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{
- struct rtgui_button* btn;
+ struct rtgui_widget *widget;
+ struct rtgui_button *btn;
RT_ASSERT(widget != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
- btn = (struct rtgui_button*) widget;
+ widget = RTGUI_WIDGET(object);
+ btn = RTGUI_BUTTON(widget);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
@@ -150,10 +153,10 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT)
{
/* set the last mouse event handled widget */
- rtgui_toplevel_t* toplevel;
+ struct rtgui_win* win;
- toplevel = RTGUI_TOPLEVEL(RTGUI_WIDGET(btn)->toplevel);
- toplevel->last_mevent_widget = RTGUI_WIDGET(btn);
+ win = RTGUI_WIN(RTGUI_WIDGET(btn)->toplevel);
+ win->last_mevent_widget = RTGUI_WIDGET(btn);
/* it's a normal button */
if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
diff --git a/components/rtgui/widgets/checkbox.c b/components/rtgui/widgets/checkbox.c
index 35c76d46a5..78c3cd97c8 100644
--- a/components/rtgui/widgets/checkbox.c
+++ b/components/rtgui/widgets/checkbox.c
@@ -1,146 +1,153 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/checkbox.h>
-
-static void _rtgui_checkbox_constructor(rtgui_checkbox_t *box)
-{
- /* init widget and set event handler */
- RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
- rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_checkbox_event_handler);
-
- /* set status */
- box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
- box->on_button = RT_NULL;
-
- /* set default gc */
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(checkbox, "checkbox",
- RTGUI_LABEL_TYPE,
- _rtgui_checkbox_constructor,
- RT_NULL,
- sizeof(struct rtgui_checkbox));
-
-void rtgui_checkbox_set_onbutton(rtgui_checkbox_t* checkbox, rtgui_onbutton_func_t func)
-{
- RT_ASSERT(checkbox != RT_NULL);
-
- checkbox->on_button = func;
-}
-
-rt_bool_t rtgui_checkbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_checkbox* box = (struct rtgui_checkbox*)widget;
-
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
-#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_draw != RT_NULL)
- {
- return widget->on_draw(widget, event);
- }
- else
-#endif
- rtgui_theme_draw_checkbox(box);
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- {
- if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(widget))
- {
- struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
- if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT &&
- emouse->button & RTGUI_MOUSE_BUTTON_UP)
- {
- /* set focus */
- rtgui_widget_focus(widget);
-
- if (box->status_down & RTGUI_CHECKBOX_STATUS_UNCHECKED)
- {
- /* check it */
- box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
- }
- else
- {
- /* un-check it */
- box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
- }
- }
-
- /* draw checkbox */
- rtgui_theme_draw_checkbox(box);
-
-#ifndef RTGUI_USING_SMALL_SIZE
- /* call user callback */
- if (widget->on_mouseclick != RT_NULL)
- {
- return widget->on_mouseclick(widget, event);
- }
-#endif
- if (box->on_button != RT_NULL)
- {
- box->on_button(widget, event);
- return RT_TRUE;
- }
- }
-
- return RT_TRUE;
- }
- }
-
- return RT_FALSE;
-}
-
-struct rtgui_checkbox* rtgui_checkbox_create(const char* text, rt_bool_t checked)
-{
- struct rtgui_checkbox* box;
-
- box = (struct rtgui_checkbox*) rtgui_widget_create (RTGUI_CHECKBOX_TYPE);
- if (box != RT_NULL)
- {
- rtgui_rect_t rect;
-
- /* set default rect */
- rtgui_font_get_metrics(rtgui_font_default(), text, &rect);
- rect.x2 += RTGUI_BORDER_DEFAULT_WIDTH + 5 + (RTGUI_BORDER_DEFAULT_WIDTH << 1);
- rect.y2 += (RTGUI_BORDER_DEFAULT_WIDTH << 1);
-
- rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
- rtgui_label_set_text(RTGUI_LABEL(box), text);
-
- if (checked == RT_TRUE)
- box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
- else
- box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
- }
-
- return box;
-}
-
-void rtgui_checkbox_destroy(rtgui_checkbox_t* box)
-{
- rtgui_widget_destroy(RTGUI_WIDGET(box));
-}
-
-void rtgui_checkbox_set_checked(rtgui_checkbox_t* checkbox, rt_bool_t checked)
-{
- RT_ASSERT(checkbox != RT_NULL);
- if (checked == RT_TRUE)
- checkbox->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
- else
- checkbox->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
-
-}
-
-rt_bool_t rtgui_checkbox_get_checked(rtgui_checkbox_t* checkbox)
-{
- RT_ASSERT(checkbox != RT_NULL);
-
- if (checkbox->status_down == RTGUI_CHECKBOX_STATUS_CHECKED)
- return RT_TRUE;
-
- return RT_FALSE;
-}
-
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/checkbox.h>
+
+static void _rtgui_checkbox_constructor(rtgui_checkbox_t *box)
+{
+ /* init widget and set event handler */
+ RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_checkbox_event_handler);
+
+ /* set status */
+ box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+ box->on_button = RT_NULL;
+
+ /* set default gc */
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(checkbox, "checkbox",
+ RTGUI_LABEL_TYPE,
+ _rtgui_checkbox_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_checkbox));
+
+void rtgui_checkbox_set_onbutton(rtgui_checkbox_t* checkbox, rtgui_onbutton_func_t func)
+{
+ RT_ASSERT(checkbox != RT_NULL);
+
+ checkbox->on_button = func;
+}
+
+rt_bool_t rtgui_checkbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_widget *widget;
+ struct rtgui_checkbox *box = (struct rtgui_checkbox*)widget;
+
+ RT_ASSERT(widget != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ widget = RTGUI_WIDGET(object);
+ box = RTGUI_CHECKBOX(object);
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (widget->on_draw != RT_NULL)
+ {
+ return widget->on_draw(widget, event);
+ }
+ else
+#endif
+ rtgui_theme_draw_checkbox(box);
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(widget))
+ {
+ struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
+ if (emouse->button & RTGUI_MOUSE_BUTTON_LEFT &&
+ emouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ /* set focus */
+ rtgui_widget_focus(widget);
+
+ if (box->status_down & RTGUI_CHECKBOX_STATUS_UNCHECKED)
+ {
+ /* check it */
+ box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
+ }
+ else
+ {
+ /* un-check it */
+ box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+ }
+ }
+
+ /* draw checkbox */
+ rtgui_theme_draw_checkbox(box);
+
+#ifndef RTGUI_USING_SMALL_SIZE
+ /* call user callback */
+ if (widget->on_mouseclick != RT_NULL)
+ {
+ return widget->on_mouseclick(widget, event);
+ }
+#endif
+ if (box->on_button != RT_NULL)
+ {
+ box->on_button(widget, event);
+ return RT_TRUE;
+ }
+ }
+
+ return RT_TRUE;
+ }
+ }
+
+ return RT_FALSE;
+}
+
+struct rtgui_checkbox* rtgui_checkbox_create(const char* text, rt_bool_t checked)
+{
+ struct rtgui_checkbox* box;
+
+ box = (struct rtgui_checkbox*) rtgui_widget_create (RTGUI_CHECKBOX_TYPE);
+ if (box != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ /* set default rect */
+ rtgui_font_get_metrics(rtgui_font_default(), text, &rect);
+ rect.x2 += RTGUI_BORDER_DEFAULT_WIDTH + 5 + (RTGUI_BORDER_DEFAULT_WIDTH << 1);
+ rect.y2 += (RTGUI_BORDER_DEFAULT_WIDTH << 1);
+
+ rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
+ rtgui_label_set_text(RTGUI_LABEL(box), text);
+
+ if (checked == RT_TRUE)
+ box->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
+ else
+ box->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+ }
+
+ return box;
+}
+
+void rtgui_checkbox_destroy(rtgui_checkbox_t* box)
+{
+ rtgui_widget_destroy(RTGUI_WIDGET(box));
+}
+
+void rtgui_checkbox_set_checked(rtgui_checkbox_t* checkbox, rt_bool_t checked)
+{
+ RT_ASSERT(checkbox != RT_NULL);
+ if (checked == RT_TRUE)
+ checkbox->status_down = RTGUI_CHECKBOX_STATUS_CHECKED;
+ else
+ checkbox->status_down = RTGUI_CHECKBOX_STATUS_UNCHECKED;
+
+}
+
+rt_bool_t rtgui_checkbox_get_checked(rtgui_checkbox_t* checkbox)
+{
+ RT_ASSERT(checkbox != RT_NULL);
+
+ if (checkbox->status_down == RTGUI_CHECKBOX_STATUS_CHECKED)
+ return RT_TRUE;
+
+ return RT_FALSE;
+}
+
diff --git a/components/rtgui/widgets/combobox.c b/components/rtgui/widgets/combobox.c
index 972d467fed..282a975f08 100644
--- a/components/rtgui/widgets/combobox.c
+++ b/components/rtgui/widgets/combobox.c
@@ -1,259 +1,276 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/combobox.h>
-
-static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_widget* widget, struct rtgui_event* event);
-const static rt_uint8_t down_arrow[] = {0xff, 0x7e, 0x3c, 0x18};
-
-static void _rtgui_combobox_constructor(rtgui_combobox_t *box)
-{
- rtgui_rect_t rect = {0, 0, RTGUI_COMBOBOX_WIDTH, RTGUI_COMBOBOX_HEIGHT};
-
- /* init widget and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_combobox_event_handler);
- rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
-
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
-
- box->pd_pressed = RT_FALSE;
- box->current_item = 0;
- box->on_selected = RT_NULL;
- box->pd_win = RT_NULL;
-}
-
-static void _rtgui_combobox_destructor(rtgui_combobox_t *box)
-{
- /* destroy pull down window */
- rtgui_win_destroy(box->pd_win);
-
- /* reset box field */
- box->pd_win = RT_NULL;
-}
-
-void rtgui_combobox_pdwin_onitem(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- rtgui_win_t* pd_win;
- rtgui_combobox_t* combo;
- rtgui_listbox_t* list;
-
- list = RTGUI_LISTBOX(widget);
- pd_win = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
- combo = RTGUI_COMBOBOX(pd_win->user_data);
- combo->current_item = list->current_item;
-
- if (combo->on_selected != RT_NULL)
- combo->on_selected(RTGUI_WIDGET(combo), RT_NULL);
-
- rtgui_win_hiden(pd_win);
- rtgui_widget_update(RTGUI_WIDGET(combo));
-
- return ;
-}
-
-rt_bool_t rtgui_combobox_pdwin_ondeactive(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- rtgui_win_hiden(RTGUI_WIN(widget));
- return RT_TRUE;
-}
-
-DEFINE_CLASS_TYPE(combobox, "combobox",
- RTGUI_WIDGET_TYPE,
- _rtgui_combobox_constructor,
- _rtgui_combobox_destructor,
- sizeof(struct rtgui_combobox));
-
-rtgui_combobox_t *rtgui_combobox_create(struct rtgui_listbox_item* items, rt_uint16_t count, struct rtgui_rect* rect)
-{
- rtgui_combobox_t *box;
-
- box = (rtgui_combobox_t*)rtgui_widget_create(RTGUI_COMBOBOX_TYPE);
- box->items_count = count;
- box->items = items;
- rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
-
- box->pd_win = RT_NULL;
-
- return box;
-}
-
-void rtgui_combobox_destroy(rtgui_combobox_t* box)
-{
- rtgui_widget_destroy(RTGUI_WIDGET(box));
-}
-
-static void rtgui_combobox_ondraw(struct rtgui_combobox* box)
-{
- /* draw button */
- rtgui_color_t bc;
- struct rtgui_dc* dc;
- struct rtgui_rect rect, r;
-
- /* begin drawing */
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
- if (dc == RT_NULL) return;
-
- bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box));
-
- /* get widget rect */
- rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
-
- /* fill widget rect with background color */
- rtgui_dc_fill_rect(dc, &rect);
- rtgui_dc_draw_rect(dc, &rect);
-
- /* draw current item */
- if (box->current_item < box->items_count)
- {
- rect.x1 += 5;
- rtgui_dc_draw_text(dc, box->items[box->current_item].name, &rect);
- }
-
- /* restore background color */
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = bc;
-
- /* draw pull down button */
- rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
- rtgui_rect_inflate(&rect, -1);
- rtgui_dc_fill_rect(dc, &rect);
- if (box->pd_pressed == RT_TRUE) rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
- else rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE);
-
- r.x1 = 0; r.y1 = 0; r.x2 = 8; r.y2 = 4;
- rtgui_rect_moveto_align(&rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
- rtgui_dc_draw_byte(dc, r.x1, r.y1, 4, down_arrow);
-
- /* end drawing */
- rtgui_dc_end_drawing(dc);
- return;
-}
-
-static rt_bool_t rtgui_combobox_onmouse_button(struct rtgui_combobox* box, struct rtgui_event_mouse* event)
-{
- struct rtgui_rect rect;
-
- /* get widget rect */
- rect = RTGUI_WIDGET(box)->extent;
-
- /* move to the pull down button */
- rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
- if (rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
- {
- /* handle mouse button on pull down button */
- if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
- event->button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- box->pd_pressed = RT_TRUE;
- rtgui_widget_update(RTGUI_WIDGET(box));
- }
- else if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
- event->button & RTGUI_MOUSE_BUTTON_UP)
- {
- box->pd_pressed = RT_FALSE;
- rtgui_widget_update(RTGUI_WIDGET(box));
-
- /* pop pull down window */
- if (box->pd_win == RT_NULL)
- {
- rtgui_listbox_t *list;
-
- /* create pull down window */
- rect = RTGUI_WIDGET(box)->extent;
- rect.y1 = rect.y2;
- rect.y2 = rect.y1 + 5 * (2 + rtgui_theme_get_selected_height());
- box->pd_win = rtgui_win_create(RT_NULL, "combo", &rect, RTGUI_WIN_STYLE_NO_TITLE);
- rtgui_win_set_ondeactivate(RTGUI_WIN(box->pd_win), rtgui_combobox_pulldown_hide);
- /* set user data to parent combobox */
- box->pd_win->user_data = (rt_uint32_t)box;
-
- /* create list box */
- rtgui_rect_inflate(&rect, -1);
- list = rtgui_listbox_create(box->items, box->items_count, &rect);
- rtgui_container_add_child(RTGUI_CONTAINER(box->pd_win), RTGUI_WIDGET(list));
- rtgui_widget_focus(RTGUI_WIDGET(list));
-
- rtgui_listbox_set_onitem(list, rtgui_combobox_pdwin_onitem);
- rtgui_win_set_ondeactivate(box->pd_win, rtgui_combobox_pdwin_ondeactive);
- }
-
- /* show combo box pull down window */
- rtgui_win_show(RTGUI_WIN(box->pd_win), RT_FALSE);
- }
-
- return RT_TRUE;
- }
-
- return RT_FALSE;
-}
-
-rt_bool_t rtgui_combobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_combobox* box = (struct rtgui_combobox*)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_combobox_ondraw(box);
-
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- return rtgui_combobox_onmouse_button(box, (struct rtgui_event_mouse*)event);
-
- case RTGUI_EVENT_FOCUSED:
- {
- /* item focused */
- struct rtgui_event_focused* focused;
-
- focused = (struct rtgui_event_focused*) event;
-
- if (focused->widget != RT_NULL)
- {
- /* hide pull down window */
- rtgui_win_hiden(RTGUI_WIN(box->pd_win));
- rtgui_combobox_ondraw(box);
- }
- }
- break;
- }
-
- return RT_FALSE;
-}
-
-static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_combobox* box;
-
- if (widget == RT_NULL) return RT_TRUE;
-
- box = (struct rtgui_combobox*) (((struct rtgui_win*)widget)->user_data);
- if (box == RT_NULL) return RT_TRUE;
-
- /* hide pull down window */
- rtgui_win_hiden(RTGUI_WIN(box->pd_win));
-
- /* clear pull down button state */
- box->pd_pressed = RT_FALSE;
- rtgui_widget_update(RTGUI_WIDGET(box));
-
- return RT_TRUE;
-}
-
-struct rtgui_listbox_item* rtgui_combox_get_select(struct rtgui_combobox* box)
-{
- if ((box != RT_NULL) && (box->current_item < box->items_count))
- {
- return &(box->items[box->current_item]);
- }
-
- return RT_NULL;
-}
-
-void rtgui_combobox_set_onselected(struct rtgui_combobox* box, rtgui_onitem_func_t func)
-{
- box->on_selected = func;
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/combobox.h>
+
+static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_object* object, struct rtgui_event* event);
+const static rt_uint8_t down_arrow[] = {0xff, 0x7e, 0x3c, 0x18};
+
+static void _rtgui_combobox_constructor(rtgui_combobox_t *box)
+{
+ rtgui_rect_t rect = {0, 0, RTGUI_COMBOBOX_WIDTH, RTGUI_COMBOBOX_HEIGHT};
+
+ /* init widget and set event handler */
+ rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_combobox_event_handler);
+ rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
+
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
+
+ box->pd_pressed = RT_FALSE;
+ box->current_item = 0;
+ box->on_selected = RT_NULL;
+ box->pd_win = RT_NULL;
+}
+
+static void _rtgui_combobox_destructor(rtgui_combobox_t *box)
+{
+ /* destroy pull down window */
+ rtgui_win_destroy(box->pd_win);
+
+ /* reset box field */
+ box->pd_win = RT_NULL;
+}
+
+rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_widget *widget;
+ rtgui_win_t* pd_win;
+ rtgui_combobox_t* combo;
+ rtgui_listbox_t* list;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ widget = RTGUI_WIDGET(object);
+ list = RTGUI_LISTBOX(widget);
+ pd_win = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
+ combo = RTGUI_COMBOBOX(pd_win->user_data);
+ combo->current_item = list->current_item;
+
+ if (combo->on_selected != RT_NULL)
+ combo->on_selected(RTGUI_OBJECT(combo), RT_NULL);
+
+ rtgui_win_hiden(pd_win);
+ rtgui_widget_update(RTGUI_WIDGET(combo));
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_combobox_pdwin_ondeactive(struct rtgui_object* object, struct rtgui_event* event)
+{
+ rtgui_win_hiden(RTGUI_WIN(object));
+ return RT_TRUE;
+}
+
+DEFINE_CLASS_TYPE(combobox, "combobox",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_combobox_constructor,
+ _rtgui_combobox_destructor,
+ sizeof(struct rtgui_combobox));
+
+rtgui_combobox_t *rtgui_combobox_create(struct rtgui_listbox_item* items, rt_uint16_t count, struct rtgui_rect* rect)
+{
+ rtgui_combobox_t *box;
+
+ box = (rtgui_combobox_t*)rtgui_widget_create(RTGUI_COMBOBOX_TYPE);
+ box->items_count = count;
+ box->items = items;
+ rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
+
+ box->pd_win = RT_NULL;
+
+ return box;
+}
+
+void rtgui_combobox_destroy(rtgui_combobox_t* box)
+{
+ rtgui_widget_destroy(RTGUI_WIDGET(box));
+}
+
+static void rtgui_combobox_ondraw(struct rtgui_combobox* box)
+{
+ /* draw button */
+ rtgui_color_t bc;
+ struct rtgui_dc* dc;
+ struct rtgui_rect rect, r;
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+ if (dc == RT_NULL) return;
+
+ bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box));
+
+ /* get widget rect */
+ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
+
+ /* fill widget rect with background color */
+ rtgui_dc_fill_rect(dc, &rect);
+ rtgui_dc_draw_rect(dc, &rect);
+
+ /* draw current item */
+ if (box->current_item < box->items_count)
+ {
+ rect.x1 += 5;
+ rtgui_dc_draw_text(dc, box->items[box->current_item].name, &rect);
+ }
+
+ /* restore background color */
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = bc;
+
+ /* draw pull down button */
+ rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
+ rtgui_rect_inflate(&rect, -1);
+ rtgui_dc_fill_rect(dc, &rect);
+ if (box->pd_pressed == RT_TRUE) rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
+ else rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE);
+
+ r.x1 = 0; r.y1 = 0; r.x2 = 8; r.y2 = 4;
+ rtgui_rect_moveto_align(&rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
+ rtgui_dc_draw_byte(dc, r.x1, r.y1, 4, down_arrow);
+
+ /* end drawing */
+ rtgui_dc_end_drawing(dc);
+ return;
+}
+
+static rt_bool_t rtgui_combobox_onmouse_button(struct rtgui_combobox* box, struct rtgui_event_mouse* event)
+{
+ struct rtgui_rect rect;
+
+ /* get widget rect */
+ rect = RTGUI_WIDGET(box)->extent;
+
+ /* move to the pull down button */
+ rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
+ if (rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ /* handle mouse button on pull down button */
+ if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
+ event->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ box->pd_pressed = RT_TRUE;
+ rtgui_widget_update(RTGUI_WIDGET(box));
+ }
+ else if (event->button & RTGUI_MOUSE_BUTTON_LEFT &&
+ event->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ box->pd_pressed = RT_FALSE;
+ rtgui_widget_update(RTGUI_WIDGET(box));
+
+ /* pop pull down window */
+ if (box->pd_win == RT_NULL)
+ {
+ rtgui_listbox_t *list;
+
+ /* create pull down window */
+ rect = RTGUI_WIDGET(box)->extent;
+ rect.y1 = rect.y2;
+ rect.y2 = rect.y1 + 5 * (2 + rtgui_theme_get_selected_height());
+ box->pd_win = rtgui_win_create(RT_NULL, "combo", &rect, RTGUI_WIN_STYLE_NO_TITLE);
+ rtgui_win_set_ondeactivate(RTGUI_WIN(box->pd_win), rtgui_combobox_pulldown_hide);
+ /* set user data to parent combobox */
+ box->pd_win->user_data = (rt_uint32_t)box;
+
+ /* create list box */
+ rtgui_rect_inflate(&rect, -1);
+ list = rtgui_listbox_create(box->items, box->items_count, &rect);
+ rtgui_container_add_child(RTGUI_CONTAINER(box->pd_win), RTGUI_WIDGET(list));
+ rtgui_widget_focus(RTGUI_WIDGET(list));
+
+ rtgui_listbox_set_onitem(list, rtgui_combobox_pdwin_onitem);
+ rtgui_win_set_ondeactivate(box->pd_win, rtgui_combobox_pdwin_ondeactive);
+ }
+
+ /* show combo box pull down window */
+ rtgui_win_show(RTGUI_WIN(box->pd_win), RT_FALSE);
+ }
+
+ return RT_TRUE;
+ }
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_combobox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_combobox *box;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ box = RTGUI_COMBOBOX(object);
+
+ 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_combobox_ondraw(box);
+
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ return rtgui_combobox_onmouse_button(box, (struct rtgui_event_mouse*)event);
+
+ case RTGUI_EVENT_FOCUSED:
+ {
+ /* item focused */
+ struct rtgui_event_focused* focused;
+
+ focused = (struct rtgui_event_focused*) event;
+
+ if (focused->widget != RT_NULL)
+ {
+ /* hide pull down window */
+ rtgui_win_hiden(RTGUI_WIN(box->pd_win));
+ rtgui_combobox_ondraw(box);
+ }
+ }
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_widget *widget;
+ struct rtgui_combobox *box;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ widget = RTGUI_WIDGET(object);
+ box = RTGUI_COMBOBOX(object);
+
+ if (widget == RT_NULL) return RT_TRUE;
+
+ box = (struct rtgui_combobox*) (((struct rtgui_win*)widget)->user_data);
+ if (box == RT_NULL) return RT_TRUE;
+
+ /* hide pull down window */
+ rtgui_win_hiden(RTGUI_WIN(box->pd_win));
+
+ /* clear pull down button state */
+ box->pd_pressed = RT_FALSE;
+ rtgui_widget_update(RTGUI_WIDGET(box));
+
+ return RT_TRUE;
+}
+
+struct rtgui_listbox_item* rtgui_combox_get_select(struct rtgui_combobox* box)
+{
+ if ((box != RT_NULL) && (box->current_item < box->items_count))
+ {
+ return &(box->items[box->current_item]);
+ }
+
+ return RT_NULL;
+}
+
+void rtgui_combobox_set_onselected(struct rtgui_combobox* box, rtgui_event_handler_ptr func)
+{
+ box->on_selected = func;
+}
diff --git a/components/rtgui/widgets/container.c b/components/rtgui/widgets/container.c
index c1e90f719a..3e919ba19a 100644
--- a/components/rtgui/widgets/container.c
+++ b/components/rtgui/widgets/container.c
@@ -10,37 +10,55 @@
* Change Logs:
* Date Author Notes
* 2009-10-16 Bernard first version
+ * 2010-09-24 Bernard fix container destroy issue
*/
-#include <rtgui/widgets/toplevel.h>
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/container.h>
+#include <rtgui/widgets/window.h>
static void _rtgui_container_constructor(rtgui_container_t *container)
{
- /* set event handler and init field */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(container), rtgui_container_event_handler);
+ /* init container */
+ rtgui_object_set_event_handler(RTGUI_OBJECT(container),
+ rtgui_container_event_handler);
+
rtgui_list_init(&(container->children));
-
- /* set focused widget to itself */
- container->focused = RTGUI_WIDGET(container);
- /* set container as focusable widget */
- RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ /* container is used to 'contain'(show) widgets and dispatch events to
+ * them, not interact with user. So no need to grab focus. If we did it,
+ * some widget inherited from container(e.g. notebook) will grab the focus
+ * annoyingly.
+ *
+ * For example, a focusable notebook N has a widget W. When the user press
+ * W, N will gain the focus and W will lose it at first. Then N will set
+ * focus to W because it is W that eventually interact with people. N will
+ * yield focus and W will gain the focus again. This loop will make W
+ * repaint twice every time user press it.
+ *
+ * Just eliminate it.
+ */
+ RTGUI_WIDGET(container)->flag &= ~RTGUI_WIDGET_FLAG_FOCUSABLE;
}
static void _rtgui_container_destructor(rtgui_container_t *container)
{
- /* destroy children of container */
rtgui_container_destroy_children(container);
}
static void _rtgui_container_update_toplevel(rtgui_container_t* container)
{
+ struct rtgui_win *window;
struct rtgui_list_node* node;
+ window = rtgui_widget_get_toplevel(RTGUI_WIDGET(container));
+
rtgui_list_foreach(node, &(container->children))
{
rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
/* set child toplevel */
- child->toplevel = rtgui_widget_get_toplevel(RTGUI_WIDGET(container));
+ child->toplevel = window;
if (RTGUI_IS_CONTAINER(child))
{
@@ -49,7 +67,7 @@ static void _rtgui_container_update_toplevel(rtgui_container_t* container)
}
}
-DEFINE_CLASS_TYPE(container, "container",
+DEFINE_CLASS_TYPE(container, "container",
RTGUI_WIDGET_TYPE,
_rtgui_container_constructor,
_rtgui_container_destructor,
@@ -65,7 +83,8 @@ rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_eve
struct rtgui_widget* w;
w = rtgui_list_entry(node, struct rtgui_widget, sibling);
- if (w->event_handler(w, event) == RT_TRUE) return RT_TRUE;
+ if (RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w), event) == RT_TRUE)
+ return RT_TRUE;
}
return RT_FALSE;
@@ -75,64 +94,106 @@ rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, str
{
/* handle in child widget */
struct rtgui_list_node* node;
- rtgui_widget_t *focus;
+ struct rtgui_widget *old_focus;
+
+ old_focus = RTGUI_WIDGET(container)->toplevel->focused_widget;
- /* get focus widget on toplevel */
- focus = RTGUI_CONTAINER(RTGUI_WIDGET(container)->toplevel)->focused;
rtgui_list_foreach(node, &(container->children))
{
struct rtgui_widget* w;
w = rtgui_list_entry(node, struct rtgui_widget, sibling);
- if (rtgui_rect_contains_point(&(w->extent), event->x, event->y) == RT_EOK)
+ if (rtgui_rect_contains_point(&(w->extent),
+ event->x, event->y) == RT_EOK)
{
- if ((focus != w) && RTGUI_WIDGET_IS_FOCUSABLE(w))
+ if ((old_focus != w) && RTGUI_WIDGET_IS_FOCUSABLE(w))
rtgui_widget_focus(w);
- if (w->event_handler(w, (rtgui_event_t*)event) == RT_TRUE) return RT_TRUE;
+ if (RTGUI_OBJECT(w)->event_handler(RTGUI_OBJECT(w),
+ (rtgui_event_t*)event) == RT_TRUE)
+ return RT_TRUE;
}
}
return RT_FALSE;
}
-rt_bool_t rtgui_container_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{
- rtgui_container_t *container = RTGUI_CONTAINER(widget);
+ struct rtgui_container *container;
+ struct rtgui_widget *widget;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ container = RTGUI_CONTAINER(object);
+ widget = RTGUI_WIDGET(object);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
- case RTGUI_EVENT_COMMAND:
- case RTGUI_EVENT_RESIZE:
- rtgui_container_dispatch_event(container, event);
+ {
+ struct rtgui_dc* dc;
+ struct rtgui_rect rect;
+
+ dc = rtgui_dc_begin_drawing(widget);
+ if (dc == RT_NULL)
+ return RT_FALSE;
+ rtgui_widget_get_rect(widget, &rect);
+
+ /* fill container with background */
+ rtgui_dc_fill_rect(dc, &rect);
+
+ /* paint on each child */
+ rtgui_container_dispatch_event(container, event);
+
+ rtgui_dc_end_drawing(dc);
+ }
break;
case RTGUI_EVENT_KBD:
+ /* let parent to handle keyboard event */
+ if (widget->parent != RT_NULL &&
+ widget->parent != RTGUI_WIDGET(widget->toplevel))
{
- /* let parent to handle keyboard event */
- if (widget->parent != RT_NULL && widget->parent != widget->toplevel)
- {
- return widget->parent->event_handler(widget->parent, event);
- }
+ return RTGUI_OBJECT(widget->parent)->event_handler(
+ RTGUI_OBJECT(widget->parent),
+ event);
}
break;
case RTGUI_EVENT_MOUSE_BUTTON:
+ case RTGUI_EVENT_MOUSE_MOTION:
/* handle in child widget */
return rtgui_container_dispatch_mouse_event(container,
(struct rtgui_event_mouse*)event);
- case RTGUI_EVENT_MOUSE_MOTION:
- return rtgui_container_dispatch_mouse_event(container,
- (struct rtgui_event_mouse*)event);
+ case RTGUI_EVENT_COMMAND:
+ case RTGUI_EVENT_RESIZE:
+ rtgui_container_dispatch_event(container, event);
+ break;
default:
/* call parent widget event handler */
- return rtgui_widget_event_handler(widget, event);
+ return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
}
return RT_FALSE;
}
+rtgui_container_t* rtgui_container_create(void)
+{
+ struct rtgui_container* container;
+
+ /* allocate container */
+ container = (struct rtgui_container*) rtgui_widget_create (RTGUI_CONTAINER_TYPE);
+ return container;
+}
+
+void rtgui_container_destroy(rtgui_container_t* container)
+{
+ rtgui_container_hide(container);
+ rtgui_widget_destroy(RTGUI_WIDGET(container));
+}
+
/*
* This function will add a child to a container widget
* Note: this function will not change the widget layout
@@ -168,13 +229,7 @@ void rtgui_container_remove_child(rtgui_container_t *container, rtgui_widget_t*
RT_ASSERT(container != RT_NULL);
RT_ASSERT(child != RT_NULL);
- if (child == container->focused)
- {
- /* set focused to itself */
- container->focused = RTGUI_WIDGET(container);
-
- rtgui_widget_focus(RTGUI_WIDGET(container));
- }
+ rtgui_widget_unfocus(child);
/* remove widget from parent's children list */
rtgui_list_remove(&(container->children), &(child->sibling));
@@ -218,9 +273,6 @@ void rtgui_container_destroy_children(rtgui_container_t *container)
}
container->children.next = RT_NULL;
- container->focused = RTGUI_WIDGET(container);
- if (RTGUI_WIDGET(container)->parent != RT_NULL)
- rtgui_widget_focus(RTGUI_WIDGET(container));
/* update widget clip */
rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(RTGUI_WIDGET(container)->toplevel));
@@ -237,3 +289,26 @@ rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container)
return child;
}
+
+#ifndef RTGUI_USING_SMALL_SIZE
+void rtgui_container_set_box(rtgui_container_t* container, struct rtgui_box* box)
+{
+ if (container == RT_NULL || box == RT_NULL)
+ return;
+
+ rtgui_container_add_child(RTGUI_CONTAINER(container), RTGUI_WIDGET(box));
+ rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(container)->extent));
+}
+#endif
+
+void rtgui_container_hide(rtgui_container_t* container)
+{
+ if (container == RT_NULL) return;
+
+ if (RTGUI_WIDGET(container)->parent == RT_NULL)
+ {
+ RTGUI_WIDGET_HIDE(RTGUI_WIDGET(container));
+ return;
+ }
+}
+
diff --git a/components/rtgui/widgets/filelist_view.c b/components/rtgui/widgets/filelist_view.c
index 3e38cb193f..14209749ca 100644
--- a/components/rtgui/widgets/filelist_view.c
+++ b/components/rtgui/widgets/filelist_view.c
@@ -1,846 +1,827 @@
-/*
- * File : filelist_view.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-01-06 Bernard first version
- */
-
-#include <rtgui/rtgui_object.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/rtgui_theme.h>
-
-#include <rtgui/list.h>
-#include <rtgui/image.h>
-#include <rtgui/widgets/view.h>
-#include <rtgui/widgets/workbench.h>
-#include <rtgui/widgets/filelist_view.h>
-#include <rtgui/widgets/listbox.h>
-#include <rtgui/widgets/window.h>
-
-#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
-#ifdef _WIN32
-#include <io.h>
-#include <dirent.h>
-#include <sys/stat.h>
-#define PATH_SEPARATOR '\\'
-#else
-#include <dfs_posix.h>
-#define PATH_SEPARATOR '/'
-#endif
-
-#include <string.h>
-
-#define RTGUI_FILELIST_MARGIN 5
-
-const static char * file_xpm[] = {
-"16 16 21 1",
-" c None",
-". c #999999",
-"+ c #818181",
-"@ c #FFFFFF",
-"# c #ECECEC",
-"$ c #EAEAEA",
-"% c #EBEBEB",
-"& c #EDEDED",
-"* c #F0F0F0",
-"= c #C4C4C4",
-"- c #C5C5C5",
-"; c #C6C6C6",
-"> c #C7C7C7",
-", c #EEEEEE",
-"' c #EDEDE5",
-") c #EDEDE6",
-"! c #EFEFEF",
-"~ c #C8C8C8",
-"{ c #F1F1F1",
-"] c #F2F2F2",
-"^ c #959595",
-".++++++++++++ ",
-"+@@@@@@@@@@@@+ ",
-"+@#$$%%%##&*@+ ",
-"+@$=--;;;;>*@+ ",
-"+@$%%###&&,*@+ ",
-"+@%-;;;;;;>*@+ ",
-"+@%%##&&'#,*@+ ",
-"+@%;;;;,,),*@+ ",
-"+@##&&,,!!!*@+ ",
-"+@#;;;>>~~~*@+ ",
-"+@#&,,!!*{{{@+ ",
-"+@&;>>~~~{{]@+ ",
-"+@&&,!!**{]]@+ ",
-"+@@@@@@@@@@@@+ ",
-"^++++++++++++^ ",
-" "};
-
-const static char * folder_xpm[] = {
-"16 16 121 2",
-" c None",
-". c #D9B434",
-"+ c #E1C25E",
-"@ c #E2C360",
-"# c #E2C35F",
-"$ c #DBB63C",
-"% c #DAB336",
-"& c #FEFEFD",
-"* c #FFFFFE",
-"= c #FFFEFE",
-"- c #FFFEFD",
-"; c #FBF7EA",
-"> c #E4C76B",
-", c #E3C76B",
-"' c #E6CD79",
-") c #E5CA74",
-"! c #DAAF35",
-"~ c #FEFCF7",
-"{ c #F8E48E",
-"] c #F5DE91",
-"^ c #F5E09F",
-"/ c #F6E1AC",
-"( c #FEFBEF",
-"_ c #FEFDF4",
-": c #FEFCF3",
-"< c #FEFCF1",
-"[ c #FEFBEE",
-"} c #FFFDFA",
-"| c #DAAF36",
-"1 c #DAAA36",
-"2 c #FDFAF1",
-"3 c #F5DE94",
-"4 c #F4DC93",
-"5 c #F2D581",
-"6 c #EDCA6A",
-"7 c #EACB6C",
-"8 c #EFD385",
-"9 c #EFD280",
-"0 c #EFD07A",
-"a c #EECF76",
-"b c #EECF72",
-"c c #FBF7E9",
-"d c #DAAE34",
-"e c #DAAB35",
-"f c #FBF6E8",
-"g c #EFD494",
-"h c #EECE88",
-"i c #E9C173",
-"j c #F6E9C9",
-"k c #FEFCF2",
-"l c #FEFCF0",
-"m c #DAAB36",
-"n c #DAA637",
-"o c #FFFDF8",
-"p c #FFFDF6",
-"q c #FFFCF5",
-"r c #FCF6D8",
-"s c #F8E694",
-"t c #F7E385",
-"u c #F6DF76",
-"v c #F5DB68",
-"w c #F4D85C",
-"x c #FCF4D7",
-"y c #DAA435",
-"z c #DAA136",
-"A c #FEFCF6",
-"B c #FCF2C8",
-"C c #FBEFB9",
-"D c #FAECAC",
-"E c #F9E89C",
-"F c #F7E38B",
-"G c #F6E07C",
-"H c #F6DC6C",
-"I c #F5D95D",
-"J c #F4D64F",
-"K c #F3D344",
-"L c #FCF3D0",
-"M c #DA9F35",
-"N c #DA9A36",
-"O c #FDFAF2",
-"P c #FAEDB3",
-"Q c #F9E9A4",
-"R c #F8E695",
-"S c #F7E285",
-"T c #F6DE76",
-"U c #F5DB65",
-"V c #F4D757",
-"W c #F3D449",
-"X c #F2D13B",
-"Y c #F1CE30",
-"Z c #FBF2CC",
-"` c #DA9835",
-" . c #DA9435",
-".. c #FEFAEF",
-"+. c #F9E9A1",
-"@. c #F8E591",
-"#. c #F7E181",
-"$. c #F6DE72",
-"%. c #F5DA63",
-"&. c #F4D754",
-"*. c #F3D347",
-"=. c #F2D039",
-"-. c #F1CD2E",
-";. c #F0CB26",
-">. c #FBF2CA",
-",. c #D98E33",
-"'. c #FAF0DC",
-"). c #F4DDA7",
-"!. c #F4DB9E",
-"~. c #F3DA96",
-"{. c #F3D88E",
-"]. c #F3D786",
-"^. c #F2D47F",
-"/. c #F2D379",
-"(. c #F1D272",
-"_. c #F1D06C",
-":. c #F1CF69",
-"<. c #F8EAC2",
-"[. c #D8882D",
-"}. c #D8872D",
-"|. c #D8862C",
-" ",
-" ",
-" ",
-" . + @ @ @ # $ ",
-" % & * = - * ; > , , , ' ) ",
-" ! ~ { ] ^ / ( _ : < ( [ } | ",
-" 1 2 3 4 5 6 7 8 9 0 a b c d ",
-" e f g h i j k : k l ( [ * m ",
-" n * o p q : r s t u v w x y ",
-" z A B C D E F G H I J K L M ",
-" N O P Q R S T U V W X Y Z ` ",
-" ...+.@.#.$.%.&.*.=.-.;.>. . ",
-" ,.'.).!.~.{.].^./.(._.:.<.,. ",
-" [.}.[.[.[.[.[.[.[.[.}.[.|. ",
-" ",
-" "};
-
-/* image for file and folder */
-static rtgui_image_t *file_image, *folder_image;
-static struct rtgui_listbox_item items[] =
-{
-#ifdef RTGUI_USING_FONTHZ
- {"�����", RT_NULL},
- {"ѡ���ļ���", RT_NULL},
- {"�˳�", RT_NULL}
-#else
- {"Open folder", RT_NULL},
- {"Select folder", RT_NULL},
- {"Cancel", RT_NULL}
-#endif
-};
-static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view);
-
-static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rtgui_event* event)
-{
- rtgui_win_t *menu;
- rtgui_listbox_t *listbox;
- rtgui_filelist_view_t *view;
-
- listbox = RTGUI_LISTBOX(widget);
- menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
- view = RTGUI_FILELIST_VIEW(menu->user_data);
-
- /* hide window */
- rtgui_win_hiden(menu);
-
- switch (listbox->current_item)
- {
- case 0:
- {
- char* dir_ptr;
-
- /* destroy menu window */
- rtgui_win_destroy(menu);
-
- dir_ptr = (char*) rtgui_malloc (256);
- rtgui_filelist_view_get_fullpath(view, dir_ptr, 256);
- rtgui_filelist_view_set_directory(view, dir_ptr);
- rt_free(dir_ptr);
- }
- break;
- case 1:
- /* destroy menu window */
- rtgui_win_destroy(menu);
- if (RTGUI_VIEW(view)->modal_show == RT_TRUE)
- {
- rtgui_view_end_modal(RTGUI_VIEW(view), RTGUI_MODAL_OK);
- }
- break;
-
- default:
- /* destroy menu window */
- rtgui_win_destroy(menu);
- break;
- }
-}
-
-static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_widget_t* widget, struct rtgui_event* event)
-{
- rtgui_win_t *menu;
- menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
-
- /* destroy menu window */
- rtgui_win_destroy(menu);
-
- return RT_TRUE;
-}
-
-static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent)
-{
- rtgui_win_t *menu;
- rtgui_listbox_t *listbox;
- rtgui_rect_t screen, rect = {0, 0, 140, 85};
-
- rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen);
- rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
-
- menu = rtgui_win_create(RTGUI_TOPLEVEL(rtgui_widget_get_toplevel(parent)),
- "Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT);
- if (menu != RT_NULL)
- {
- /* set user data on menu window */
- menu->user_data = (rt_uint32_t)parent;
-
- rtgui_win_set_ondeactivate(menu, rtgui_filelist_view_on_menu_deactivate);
-
- listbox = rtgui_listbox_create(items, sizeof(items)/sizeof(items[0]), &rect);
- rtgui_listbox_set_onitem(listbox, rtgui_filelist_view_on_folder_item);
- rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(listbox));
- rtgui_win_show(menu, RT_FALSE);
- rtgui_widget_focus(RTGUI_WIDGET(listbox));
- rtgui_listbox_set_current_item(listbox, 0);
- }
-}
-
-static void _rtgui_filelist_view_constructor(struct rtgui_filelist_view *view)
-{
- /* default rect */
- struct rtgui_rect rect = {0, 0, 200, 200};
-
- /* set default widget rect and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(view), rtgui_filelist_view_event_handler);
- rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
-
- RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
- view->current_item = 0;
- view->items_count = 0;
- view->page_items = 0;
-
- view->current_directory = RT_NULL;
- view->pattern = RT_NULL;
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
-
- file_image = rtgui_image_create_from_mem("xpm",
- (rt_uint8_t*)file_xpm, sizeof(file_xpm), RT_TRUE);
- folder_image = rtgui_image_create_from_mem("xpm",
- (rt_uint8_t*)folder_xpm, sizeof(folder_xpm), RT_TRUE);
-}
-
-static void _rtgui_filelist_view_destructor(struct rtgui_filelist_view *view)
-{
- /* delete all file items */
- rtgui_filelist_view_clear(view);
- /* delete current directory and pattern */
- rtgui_free(view->current_directory); view->current_directory = RT_NULL;
- rtgui_free(view->pattern); view->pattern = RT_NULL;
-
- /* delete image */
- rtgui_image_destroy(file_image);
- rtgui_image_destroy(folder_image);
-}
-
-DEFINE_CLASS_TYPE(filelist, "filelist",
- RTGUI_VIEW_TYPE,
- _rtgui_filelist_view_constructor,
- _rtgui_filelist_view_destructor,
- sizeof(struct rtgui_filelist_view));
-
-void rtgui_filelist_view_ondraw(struct rtgui_filelist_view* view)
-{
- struct rtgui_dc* dc;
- rt_uint16_t page_index, index;
- struct rtgui_file_item* item;
- struct rtgui_rect rect, item_rect, image_rect;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- /* get item base rect */
- item_rect = rect;
- item_rect.y1 += 1;
- item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
-
- /* get image base rect */
- image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
- image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
- /* get current page */
- page_index = (view->current_item / view->page_items) * view->page_items;
- for (index = 0; index < view->page_items; index ++)
- {
- if (page_index + index >= view->items_count) break;
-
- item = &(view->items[page_index + index]);
-
- if (page_index + index == view->current_item)
- {
- rtgui_theme_draw_selected(dc, &item_rect);
- }
- else
- {
- /* draw background */
- rtgui_dc_fill_rect(dc, &item_rect);
- }
-
- /* draw item */
-
- if (item->type == RTGUI_FITEM_FILE)
- rtgui_image_blit(file_image, dc, &image_rect);
- else
- rtgui_image_blit(folder_image, dc, &image_rect);
-
- /* draw text */
- item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
- rtgui_dc_draw_text(dc, item->name, &item_rect);
- item_rect.x1 -= RTGUI_FILELIST_MARGIN + file_image->w + 2;
-
- /* move to next item position */
- item_rect.y1 += (rtgui_theme_get_selected_height() + 1);
- item_rect.y2 += (rtgui_theme_get_selected_height() + 1);
-
- image_rect.y1 += (rtgui_theme_get_selected_height() + 1);
- image_rect.y2 += (rtgui_theme_get_selected_height() + 1);
- }
-
- rtgui_dc_end_drawing(dc);
-}
-
-void rtgui_filelist_view_update_current(struct rtgui_filelist_view* view, rt_uint16_t old_item)
-{
- struct rtgui_dc* dc;
- struct rtgui_file_item* item;
- rtgui_rect_t rect, item_rect, image_rect;
-
- if (old_item/view->page_items != view->current_item/view->page_items)
- {
- /* it's not a same page, update all */
- rtgui_widget_update(RTGUI_WIDGET(view));
- return;
- }
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
- /* get old item rect */
- item_rect = rect;
- item_rect.y1 += 1;
- item_rect.y1 += (old_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
-
- /* get image rect */
- image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
- image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
- /* draw old item */
- rtgui_dc_fill_rect(dc, &item_rect);
-
- item = &(view->items[old_item]);
- if (item->type == RTGUI_FITEM_FILE) /* draw item image */
- rtgui_image_blit(file_image, dc, &image_rect);
- else
- rtgui_image_blit(folder_image, dc, &image_rect);
-
- item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- /* draw current item */
- item_rect = rect;
- item_rect.y1 += 1;
- item_rect.y1 += (view->current_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
-
- rtgui_theme_draw_selected(dc, &item_rect);
-
- /* get image base rect */
- image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
- image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
- item = &(view->items[view->current_item]);
- if (item->type == RTGUI_FITEM_FILE) /* draw item image */
- rtgui_image_blit(file_image, dc, &image_rect);
- else
- rtgui_image_blit(folder_image, dc, &image_rect);
-
- item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- rtgui_dc_end_drawing(dc);
-}
-
-static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view)
-{
- if (view->items[view->current_item].type == RTGUI_FITEM_DIR)
- {
- char new_path[64];
-
- if (strcmp(view->items[view->current_item].name, ".") == 0) return ;
- if (strcmp(view->items[view->current_item].name, "..") == 0)
- {
- char *ptr;
- ptr = strrchr(view->current_directory, PATH_SEPARATOR);
-
- if (ptr == RT_NULL) return ;
- if (ptr == &(view->current_directory[0]))
- {
- /* it's root directory */
- new_path[0] = PATH_SEPARATOR;
- new_path[1] = '\0';
- }
- else
- {
- strncpy(new_path, view->current_directory, ptr - view->current_directory + 1);
- new_path[ptr - view->current_directory] = '\0';
- }
- }
- else if (view->current_item == 0 &&
-#ifdef _WIN32
- (view->current_directory[1] == ':') && (view->current_directory[2] == '\\'))
-#else
- (view->current_directory[0] == '/') && (view->current_directory[1] == '\0'))
-#endif
- {
- if (RTGUI_VIEW(view)->modal_show == RT_TRUE)
- {
- rtgui_view_end_modal(RTGUI_VIEW(view), RTGUI_MODAL_CANCEL);
- }
- else
- {
- rtgui_filelist_view_destroy(view);
- }
-
- return ;
- }
- else
- {
- rtgui_filelist_view_menu_pop(RTGUI_WIDGET(view));
- return ;
- }
- rtgui_filelist_view_set_directory(view, new_path);
- }
- else
- {
- if (RTGUI_VIEW(view)->modal_show == RT_TRUE)
- {
- rtgui_view_end_modal(RTGUI_VIEW(view), RTGUI_MODAL_OK);
- }
- }
-}
-
-rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_filelist_view* view = RT_NULL;
-
- view = RTGUI_FILELIST_VIEW(widget);
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- rtgui_filelist_view_ondraw(view);
- return RT_FALSE;
-
- case RTGUI_EVENT_RESIZE:
- {
- struct rtgui_event_resize* resize;
-
- resize = (struct rtgui_event_resize*)event;
-
- /* recalculate page items */
- if (file_image != RT_NULL)
- view->page_items = resize->h / (1 + rtgui_theme_get_selected_height());
- else
- view->page_items = resize->h / (2 + 14);
- }
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- {
- rtgui_rect_t rect;
- struct rtgui_event_mouse* emouse;
-
- emouse = (struct rtgui_event_mouse*)event;
-
- /* calculate selected item */
-
- /* get physical extent information */
- rtgui_widget_get_rect(widget, &rect);
- rtgui_widget_rect_to_device(widget, &rect);
-
- if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
- {
- rt_uint16_t index;
- rt_uint16_t current_page;
- rt_uint16_t old_item;
-
- index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-
- /* get current page */
- current_page = view->current_item/view->page_items;
- old_item = view->current_item;
-
- if (index + current_page * view->page_items < view->items_count)
- {
- /* set selected item */
- view->current_item = index + current_page * view->page_items;
- if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- rtgui_filelist_view_update_current(view, old_item);
- }
- else
- {
- /* up event */
- rtgui_filelist_view_onenturn(view);
- }
- }
-
- return RT_TRUE;
- }
- }
- break;
-
- case RTGUI_EVENT_KBD:
- {
- struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
- if (ekbd->type == RTGUI_KEYDOWN)
- {
- rt_uint16_t old_item;
-
- old_item = view->current_item;
- switch (ekbd->key)
- {
- case RTGUIK_UP:
- if (view->current_item > 0)
- view->current_item --;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
-
- case RTGUIK_DOWN:
- if (view->current_item < view->items_count - 1)
- view->current_item ++;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
-
- case RTGUIK_LEFT:
- if (view->current_item - view->page_items >= 0)
- view->current_item -= view->page_items;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
-
- case RTGUIK_RIGHT:
- if (view->current_item + view->page_items < view->items_count - 1)
- view->current_item += view->page_items;
- rtgui_filelist_view_update_current(view, old_item);
- return RT_TRUE;
-
- case RTGUIK_RETURN:
- rtgui_filelist_view_onenturn(view);
- return RT_TRUE;
-
- default:
- break;
- }
- }
- }
- return RT_FALSE;
- }
-
- /* use view event handler */
- return rtgui_view_event_handler(widget, event);
-}
-
-rtgui_filelist_view_t* rtgui_filelist_view_create(rtgui_workbench_t* workbench,
- const char* directory, const char* pattern, const rtgui_rect_t* rect)
-{
- struct rtgui_filelist_view* view = RT_NULL;
-
- /* create a new view */
- view = (struct rtgui_filelist_view*) rtgui_widget_create(RTGUI_FILELIST_VIEW_TYPE);
- if (view != RT_NULL)
- {
- view->items = RT_NULL;
- view->pattern = rt_strdup(pattern);
- view->page_items = rtgui_rect_height(*rect) / (1 + rtgui_theme_get_selected_height());
- rtgui_filelist_view_set_directory(view, directory);
-
- rtgui_workbench_add_view(workbench, RTGUI_VIEW(view));
- }
-
- return view;
-}
-
-void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view)
-{
- /* destroy view */
- rtgui_widget_destroy(RTGUI_WIDGET(view));
-}
-
-/* clear all file items */
-static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view)
-{
- rt_uint32_t index;
- struct rtgui_file_item* item;
-
- for (index = 0; index < view->items_count; index ++)
- {
- item = &(view->items[index]);
-
- /* release item name */
- rt_free(item->name);
- item->name = RT_NULL;
- }
-
- /* release items */
- rtgui_free(view->items);
- view->items = RT_NULL;
-
- view->items_count = 0;
- view->current_item = 0;
-}
-
-void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory)
-{
- struct rtgui_file_item *item;
-
- RT_ASSERT(view != RT_NULL);
-
- /* clear file items firstly */
- rtgui_filelist_view_clear(view);
- if (directory != RT_NULL)
- {
- DIR* dir;
- struct stat s;
- char* fullpath;
- rt_uint32_t index;
- struct dirent* dirent;
-
- view->items_count = 0;
- dir = opendir(directory);
- if (dir == RT_NULL) goto __return;
-
- /* current directory exists, set it */
- if (view->current_directory != RT_NULL) rt_free(view->current_directory);
- view->current_directory = rt_strdup(directory);
-
- do
- {
- dirent = readdir(dir);
- if (dirent == RT_NULL) break;
-
- if (strcmp(dirent->d_name, ".") == 0) continue;
- if (strcmp(dirent->d_name, "..") == 0) continue;
-
- view->items_count ++;
- } while (dirent != RT_NULL);
- closedir(dir);
-
- view->items_count ++; /* root directory for [x] exit, others for .. */
-
- view->items = (struct rtgui_file_item*) rtgui_malloc(sizeof(struct rtgui_file_item) * view->items_count);
- if (view->items == RT_NULL) return; /* no memory */
-
- index = 0;
- if (directory[0] == '/' && directory[1] != '\0')
- {
- item = &(view->items[0]);
-
- /* add .. directory */
- item->name = rt_strdup("..");
- item->type = RTGUI_FITEM_DIR;
- item->size = 0;
-
- index ++;
- }
- else
- {
- item = &(view->items[0]);
-
- /* add .. directory */
- item->name = rt_strdup("�˳��ļ����");
- item->type = RTGUI_FITEM_DIR;
- item->size = 0;
-
- index ++;
- }
-
- /* reopen directory */
- dir = opendir(directory);
- fullpath = rtgui_malloc(256);
- while (index < view->items_count)
- {
- dirent = readdir(dir);
- if (dirent == RT_NULL) break;
-
- if (strcmp(dirent->d_name, ".") == 0) continue;
- if (strcmp(dirent->d_name, "..") == 0) continue;
-
- item = &(view->items[index]);
- item->name = rt_strdup(dirent->d_name);
-
- rt_memset(&s, 0, sizeof(struct stat));
-
- /* build full path for the file */
- if (directory[strlen(directory) - 1] != PATH_SEPARATOR)
- rt_snprintf(fullpath, 256, "%s%c%s", directory, PATH_SEPARATOR, dirent->d_name);
- else
- rt_snprintf(fullpath, 256, "%s%s", directory, dirent->d_name);
-
- stat(fullpath, &s);
- if ( s.st_mode & S_IFDIR )
- {
- item->type = RTGUI_FITEM_DIR;
- item->size = 0;
- }
- else
- {
- item->type = RTGUI_FITEM_FILE;
- item->size = s.st_size;
- }
-
- index ++;
- }
- rtgui_free(fullpath);
- closedir(dir);
- }
-
- view->current_item = 0;
-
-__return:
- /* update view */
- rtgui_widget_update(RTGUI_WIDGET(view));
-}
-
-void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len)
-{
- RT_ASSERT(view != RT_NULL);
-
- if (view->current_directory[strlen(view->current_directory) - 1] != PATH_SEPARATOR)
- rt_snprintf(path, len, "%s%c%s",view->current_directory, PATH_SEPARATOR,
- view->items[view->current_item].name);
- else
- rt_snprintf(path, len, "%s%s",view->current_directory,
- view->items[view->current_item].name);
-}
-#endif
+/*
+ * File : filelist_view.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-01-06 Bernard first version
+ */
+
+#include <rtgui/rtgui_object.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/rtgui_application.h>
+
+#include <rtgui/list.h>
+#include <rtgui/image.h>
+#include <rtgui/widgets/container.h>
+#include <rtgui/widgets/filelist_view.h>
+#include <rtgui/widgets/listbox.h>
+#include <rtgui/widgets/window.h>
+
+#if defined(RTGUI_USING_DFS_FILERW) || defined(RTGUI_USING_STDIO_FILERW)
+#ifdef _WIN32
+#include <io.h>
+#include <dirent.h>
+#include <sys/stat.h>
+#define PATH_SEPARATOR '\\'
+#else
+#include <dfs_posix.h>
+#define PATH_SEPARATOR '/'
+#endif
+
+#include <string.h>
+
+#define RTGUI_FILELIST_MARGIN 5
+
+const static char * file_xpm[] = {
+"16 16 21 1",
+" c None",
+". c #999999",
+"+ c #818181",
+"@ c #FFFFFF",
+"# c #ECECEC",
+"$ c #EAEAEA",
+"% c #EBEBEB",
+"& c #EDEDED",
+"* c #F0F0F0",
+"= c #C4C4C4",
+"- c #C5C5C5",
+"; c #C6C6C6",
+"> c #C7C7C7",
+", c #EEEEEE",
+"' c #EDEDE5",
+") c #EDEDE6",
+"! c #EFEFEF",
+"~ c #C8C8C8",
+"{ c #F1F1F1",
+"] c #F2F2F2",
+"^ c #959595",
+".++++++++++++ ",
+"+@@@@@@@@@@@@+ ",
+"+@#$$%%%##&*@+ ",
+"+@$=--;;;;>*@+ ",
+"+@$%%###&&,*@+ ",
+"+@%-;;;;;;>*@+ ",
+"+@%%##&&'#,*@+ ",
+"+@%;;;;,,),*@+ ",
+"+@##&&,,!!!*@+ ",
+"+@#;;;>>~~~*@+ ",
+"+@#&,,!!*{{{@+ ",
+"+@&;>>~~~{{]@+ ",
+"+@&&,!!**{]]@+ ",
+"+@@@@@@@@@@@@+ ",
+"^++++++++++++^ ",
+" "};
+
+const static char * folder_xpm[] = {
+"16 16 121 2",
+" c None",
+". c #D9B434",
+"+ c #E1C25E",
+"@ c #E2C360",
+"# c #E2C35F",
+"$ c #DBB63C",
+"% c #DAB336",
+"& c #FEFEFD",
+"* c #FFFFFE",
+"= c #FFFEFE",
+"- c #FFFEFD",
+"; c #FBF7EA",
+"> c #E4C76B",
+", c #E3C76B",
+"' c #E6CD79",
+") c #E5CA74",
+"! c #DAAF35",
+"~ c #FEFCF7",
+"{ c #F8E48E",
+"] c #F5DE91",
+"^ c #F5E09F",
+"/ c #F6E1AC",
+"( c #FEFBEF",
+"_ c #FEFDF4",
+": c #FEFCF3",
+"< c #FEFCF1",
+"[ c #FEFBEE",
+"} c #FFFDFA",
+"| c #DAAF36",
+"1 c #DAAA36",
+"2 c #FDFAF1",
+"3 c #F5DE94",
+"4 c #F4DC93",
+"5 c #F2D581",
+"6 c #EDCA6A",
+"7 c #EACB6C",
+"8 c #EFD385",
+"9 c #EFD280",
+"0 c #EFD07A",
+"a c #EECF76",
+"b c #EECF72",
+"c c #FBF7E9",
+"d c #DAAE34",
+"e c #DAAB35",
+"f c #FBF6E8",
+"g c #EFD494",
+"h c #EECE88",
+"i c #E9C173",
+"j c #F6E9C9",
+"k c #FEFCF2",
+"l c #FEFCF0",
+"m c #DAAB36",
+"n c #DAA637",
+"o c #FFFDF8",
+"p c #FFFDF6",
+"q c #FFFCF5",
+"r c #FCF6D8",
+"s c #F8E694",
+"t c #F7E385",
+"u c #F6DF76",
+"v c #F5DB68",
+"w c #F4D85C",
+"x c #FCF4D7",
+"y c #DAA435",
+"z c #DAA136",
+"A c #FEFCF6",
+"B c #FCF2C8",
+"C c #FBEFB9",
+"D c #FAECAC",
+"E c #F9E89C",
+"F c #F7E38B",
+"G c #F6E07C",
+"H c #F6DC6C",
+"I c #F5D95D",
+"J c #F4D64F",
+"K c #F3D344",
+"L c #FCF3D0",
+"M c #DA9F35",
+"N c #DA9A36",
+"O c #FDFAF2",
+"P c #FAEDB3",
+"Q c #F9E9A4",
+"R c #F8E695",
+"S c #F7E285",
+"T c #F6DE76",
+"U c #F5DB65",
+"V c #F4D757",
+"W c #F3D449",
+"X c #F2D13B",
+"Y c #F1CE30",
+"Z c #FBF2CC",
+"` c #DA9835",
+" . c #DA9435",
+".. c #FEFAEF",
+"+. c #F9E9A1",
+"@. c #F8E591",
+"#. c #F7E181",
+"$. c #F6DE72",
+"%. c #F5DA63",
+"&. c #F4D754",
+"*. c #F3D347",
+"=. c #F2D039",
+"-. c #F1CD2E",
+";. c #F0CB26",
+">. c #FBF2CA",
+",. c #D98E33",
+"'. c #FAF0DC",
+"). c #F4DDA7",
+"!. c #F4DB9E",
+"~. c #F3DA96",
+"{. c #F3D88E",
+"]. c #F3D786",
+"^. c #F2D47F",
+"/. c #F2D379",
+"(. c #F1D272",
+"_. c #F1D06C",
+":. c #F1CF69",
+"<. c #F8EAC2",
+"[. c #D8882D",
+"}. c #D8872D",
+"|. c #D8862C",
+" ",
+" ",
+" ",
+" . + @ @ @ # $ ",
+" % & * = - * ; > , , , ' ) ",
+" ! ~ { ] ^ / ( _ : < ( [ } | ",
+" 1 2 3 4 5 6 7 8 9 0 a b c d ",
+" e f g h i j k : k l ( [ * m ",
+" n * o p q : r s t u v w x y ",
+" z A B C D E F G H I J K L M ",
+" N O P Q R S T U V W X Y Z ` ",
+" ...+.@.#.$.%.&.*.=.-.;.>. . ",
+" ,.'.).!.~.{.].^./.(._.:.<.,. ",
+" [.}.[.[.[.[.[.[.[.[.}.[.|. ",
+" ",
+" "};
+
+/* image for file and folder */
+static rtgui_image_t *file_image, *folder_image;
+static struct rtgui_listbox_item items[] =
+{
+#ifdef RTGUI_USING_FONTHZ
+ {"���ː`����", RT_NULL},
+ {"���v�`����", RT_NULL},
+ {"�X��", RT_NULL}
+#else
+ {"Open folder", RT_NULL},
+ {"Select folder", RT_NULL},
+ {"Cancel", RT_NULL}
+#endif
+};
+static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view);
+
+static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rtgui_event* event)
+{
+ rtgui_win_t *menu;
+ rtgui_listbox_t *listbox;
+ rtgui_filelist_view_t *view;
+
+ listbox = RTGUI_LISTBOX(widget);
+ menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
+ view = RTGUI_FILELIST_VIEW(menu->user_data);
+
+ /* hide window */
+ rtgui_win_hiden(menu);
+
+ switch (listbox->current_item)
+ {
+ case 0:
+ {
+ char* dir_ptr;
+
+ /* destroy menu window */
+ rtgui_win_destroy(menu);
+
+ dir_ptr = (char*) rtgui_malloc (256);
+ rtgui_filelist_view_get_fullpath(view, dir_ptr, 256);
+ rtgui_filelist_view_set_directory(view, dir_ptr);
+ rt_free(dir_ptr);
+ }
+ break;
+ case 1:
+ /* destroy menu window */
+ rtgui_win_destroy(menu);
+ break;
+
+ default:
+ /* destroy menu window */
+ rtgui_win_destroy(menu);
+ break;
+ }
+}
+
+static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_widget_t* widget, struct rtgui_event* event)
+{
+ rtgui_win_t *menu;
+ menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget));
+
+ /* destroy menu window */
+ rtgui_win_destroy(menu);
+
+ return RT_TRUE;
+}
+
+static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent)
+{
+ rtgui_win_t *menu;
+ rtgui_listbox_t *listbox;
+ rtgui_rect_t screen, rect = {0, 0, 140, 85};
+
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen);
+ rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
+
+ menu = rtgui_win_create(RTGUI_TOPLEVEL(rtgui_widget_get_toplevel(parent)),
+ "Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT);
+ if (menu != RT_NULL)
+ {
+ /* set user data on menu window */
+ menu->user_data = (rt_uint32_t)parent;
+
+ rtgui_win_set_ondeactivate(menu, rtgui_filelist_view_on_menu_deactivate);
+
+ listbox = rtgui_listbox_create(items, sizeof(items)/sizeof(items[0]), &rect);
+ rtgui_listbox_set_onitem(listbox, rtgui_filelist_view_on_folder_item);
+ rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(listbox));
+ rtgui_win_show(menu, RT_FALSE);
+ rtgui_widget_focus(RTGUI_WIDGET(listbox));
+ rtgui_listbox_set_current_item(listbox, 0);
+ }
+}
+
+static void _rtgui_filelist_view_constructor(struct rtgui_filelist_view *view)
+{
+ /* default rect */
+ struct rtgui_rect rect = {0, 0, 200, 200};
+
+ /* set default widget rect and set event handler */
+ rtgui_object_set_event_handler(RTGUI_WIDGET(view), rtgui_filelist_view_event_handler);
+ rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
+
+ RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ view->current_item = 0;
+ view->items_count = 0;
+ view->page_items = 0;
+
+ view->current_directory = RT_NULL;
+ view->pattern = RT_NULL;
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
+
+ file_image = rtgui_image_create_from_mem("xpm",
+ (rt_uint8_t*)file_xpm, sizeof(file_xpm), RT_TRUE);
+ folder_image = rtgui_image_create_from_mem("xpm",
+ (rt_uint8_t*)folder_xpm, sizeof(folder_xpm), RT_TRUE);
+}
+
+static void _rtgui_filelist_view_destructor(struct rtgui_filelist_view *view)
+{
+ /* delete all file items */
+ rtgui_filelist_view_clear(view);
+ /* delete current directory and pattern */
+ rtgui_free(view->current_directory); view->current_directory = RT_NULL;
+ rtgui_free(view->pattern); view->pattern = RT_NULL;
+
+ /* delete image */
+ rtgui_image_destroy(file_image);
+ rtgui_image_destroy(folder_image);
+}
+
+DEFINE_CLASS_TYPE(filelist, "filelist",
+ RTGUI_CONTAINER_TYPE,
+ _rtgui_filelist_view_constructor,
+ _rtgui_filelist_view_destructor,
+ sizeof(struct rtgui_filelist_view));
+
+void rtgui_filelist_view_ondraw(struct rtgui_filelist_view* view)
+{
+ struct rtgui_dc* dc;
+ rt_uint16_t page_index, index;
+ struct rtgui_file_item* item;
+ struct rtgui_rect rect, item_rect, image_rect;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ /* get item base rect */
+ item_rect = rect;
+ item_rect.y1 += 1;
+ item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
+
+ /* get image base rect */
+ image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
+ image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ /* get current page */
+ page_index = (view->current_item / view->page_items) * view->page_items;
+ for (index = 0; index < view->page_items; index ++)
+ {
+ if (page_index + index >= view->items_count) break;
+
+ item = &(view->items[page_index + index]);
+
+ if (page_index + index == view->current_item)
+ {
+ rtgui_theme_draw_selected(dc, &item_rect);
+ }
+ else
+ {
+ /* draw background */
+ rtgui_dc_fill_rect(dc, &item_rect);
+ }
+
+ /* draw item */
+ if (item->type == RTGUI_FITEM_FILE)
+ rtgui_image_blit(file_image, dc, &image_rect);
+ else
+ rtgui_image_blit(folder_image, dc, &image_rect);
+
+ /* draw text */
+ item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ item_rect.x1 -= RTGUI_FILELIST_MARGIN + file_image->w + 2;
+
+ /* move to next item position */
+ item_rect.y1 += (rtgui_theme_get_selected_height() + 1);
+ item_rect.y2 += (rtgui_theme_get_selected_height() + 1);
+
+ image_rect.y1 += (rtgui_theme_get_selected_height() + 1);
+ image_rect.y2 += (rtgui_theme_get_selected_height() + 1);
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_filelist_view_update_current(struct rtgui_filelist_view* view, rt_uint16_t old_item)
+{
+ struct rtgui_dc* dc;
+ struct rtgui_file_item* item;
+ rtgui_rect_t rect, item_rect, image_rect;
+
+ if (old_item/view->page_items != view->current_item/view->page_items)
+ {
+ /* it's not a same page, update all */
+ rtgui_widget_update(RTGUI_WIDGET(view));
+ return;
+ }
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+ /* get old item rect */
+ item_rect = rect;
+ item_rect.y1 += 1;
+ item_rect.y1 += (old_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
+
+ /* get image rect */
+ image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
+ image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ /* draw old item */
+ rtgui_dc_fill_rect(dc, &item_rect);
+
+ item = &(view->items[old_item]);
+ if (item->type == RTGUI_FITEM_FILE) /* draw item image */
+ rtgui_image_blit(file_image, dc, &image_rect);
+ else
+ rtgui_image_blit(folder_image, dc, &image_rect);
+
+ item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ /* draw current item */
+ item_rect = rect;
+ item_rect.y1 += 1;
+ item_rect.y1 += (view->current_item % view->page_items) * (1 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (1 + rtgui_theme_get_selected_height());
+
+ rtgui_theme_draw_selected(dc, &item_rect);
+
+ /* get image base rect */
+ image_rect.x1 = RTGUI_FILELIST_MARGIN; image_rect.y1 = 0;
+ image_rect.x2 = RTGUI_FILELIST_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ item = &(view->items[view->current_item]);
+ if (item->type == RTGUI_FITEM_FILE) /* draw item image */
+ rtgui_image_blit(file_image, dc, &image_rect);
+ else
+ rtgui_image_blit(folder_image, dc, &image_rect);
+
+ item_rect.x1 += RTGUI_FILELIST_MARGIN + file_image->w + 2;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view)
+{
+ if (view->items[view->current_item].type == RTGUI_FITEM_DIR)
+ {
+ char new_path[64];
+
+ if (strcmp(view->items[view->current_item].name, ".") == 0) return ;
+ if (strcmp(view->items[view->current_item].name, "..") == 0)
+ {
+ char *ptr;
+ ptr = strrchr(view->current_directory, PATH_SEPARATOR);
+
+ if (ptr == RT_NULL) return ;
+ if (ptr == &(view->current_directory[0]))
+ {
+ /* it's root directory */
+ new_path[0] = PATH_SEPARATOR;
+ new_path[1] = '\0';
+ }
+ else
+ {
+ strncpy(new_path, view->current_directory, ptr - view->current_directory + 1);
+ new_path[ptr - view->current_directory] = '\0';
+ }
+ }
+ else if (view->current_item == 0 &&
+#ifdef _WIN32
+ (view->current_directory[1] == ':') && (view->current_directory[2] == '\\')
+#else
+ (view->current_directory[0] == '/') && (view->current_directory[1] == '\0')
+#endif
+ )
+ {
+ rtgui_filelist_view_destroy(view);
+
+ return ;
+ }
+ else
+ {
+ rtgui_filelist_view_menu_pop(RTGUI_WIDGET(view));
+ return ;
+ }
+ rtgui_filelist_view_set_directory(view, new_path);
+ }
+}
+
+rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+{
+ struct rtgui_filelist_view* view = RT_NULL;
+
+ view = RTGUI_FILELIST_VIEW(widget);
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ rtgui_filelist_view_ondraw(view);
+ return RT_FALSE;
+
+ case RTGUI_EVENT_RESIZE:
+ {
+ struct rtgui_event_resize* resize;
+
+ resize = (struct rtgui_event_resize*)event;
+
+ /* recalculate page items */
+ if (file_image != RT_NULL)
+ view->page_items = resize->h / (1 + rtgui_theme_get_selected_height());
+ else
+ view->page_items = resize->h / (2 + 14);
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_rect_t rect;
+ struct rtgui_event_mouse* emouse;
+
+ emouse = (struct rtgui_event_mouse*)event;
+
+ /* calculate selected item */
+
+ /* get physical extent information */
+ rtgui_widget_get_rect(widget, &rect);
+ rtgui_widget_rect_to_device(widget, &rect);
+
+ if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+ {
+ rt_uint16_t index;
+ rt_uint16_t current_page;
+ rt_uint16_t old_item;
+
+ index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+ /* get current page */
+ current_page = view->current_item/view->page_items;
+ old_item = view->current_item;
+
+ if (index + current_page * view->page_items < view->items_count)
+ {
+ /* set selected item */
+ view->current_item = index + current_page * view->page_items;
+ if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ rtgui_filelist_view_update_current(view, old_item);
+ }
+ else
+ {
+ /* up event */
+ rtgui_filelist_view_onenturn(view);
+ }
+ }
+
+ return RT_TRUE;
+ }
+ }
+ break;
+
+ case RTGUI_EVENT_KBD:
+ {
+ struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+ if (ekbd->type == RTGUI_KEYDOWN)
+ {
+ rt_uint16_t old_item;
+
+ old_item = view->current_item;
+ switch (ekbd->key)
+ {
+ case RTGUIK_UP:
+ if (view->current_item > 0)
+ view->current_item --;
+ rtgui_filelist_view_update_current(view, old_item);
+ return RT_TRUE;
+
+ case RTGUIK_DOWN:
+ if (view->current_item < view->items_count - 1)
+ view->current_item ++;
+ rtgui_filelist_view_update_current(view, old_item);
+ return RT_TRUE;
+
+ case RTGUIK_LEFT:
+ if (view->current_item - view->page_items >= 0)
+ view->current_item -= view->page_items;
+ rtgui_filelist_view_update_current(view, old_item);
+ return RT_TRUE;
+
+ case RTGUIK_RIGHT:
+ if (view->current_item + view->page_items < view->items_count - 1)
+ view->current_item += view->page_items;
+ rtgui_filelist_view_update_current(view, old_item);
+ return RT_TRUE;
+
+ case RTGUIK_RETURN:
+ rtgui_filelist_view_onenturn(view);
+ return RT_TRUE;
+
+ default:
+ break;
+ }
+ }
+ }
+ return RT_FALSE;
+ }
+
+ /* use view event handler */
+ return rtgui_container_event_handler(widget, event);
+}
+
+rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory,
+ const char* pattern,
+ const rtgui_rect_t* rect)
+{
+ struct rtgui_filelist_view* view = RT_NULL;
+
+ /* create a new view */
+ view = (struct rtgui_filelist_view*) rtgui_widget_create(RTGUI_FILELIST_VIEW_TYPE);
+ if (view != RT_NULL)
+ {
+ view->items = RT_NULL;
+ view->pattern = rt_strdup(pattern);
+ view->page_items = rtgui_rect_height(*rect) / (1 + rtgui_theme_get_selected_height());
+ rtgui_filelist_view_set_directory(view, directory);
+ }
+
+ return view;
+}
+
+void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view)
+{
+ /* destroy view */
+ rtgui_widget_destroy(RTGUI_WIDGET(view));
+}
+
+/* clear all file items */
+static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view)
+{
+ rt_uint32_t index;
+ struct rtgui_file_item* item;
+
+ for (index = 0; index < view->items_count; index ++)
+ {
+ item = &(view->items[index]);
+
+ /* release item name */
+ rt_free(item->name);
+ item->name = RT_NULL;
+ }
+
+ /* release items */
+ rtgui_free(view->items);
+ view->items = RT_NULL;
+
+ view->items_count = 0;
+ view->current_item = 0;
+}
+
+void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory)
+{
+ struct rtgui_file_item *item;
+
+ RT_ASSERT(view != RT_NULL);
+
+ /* clear file items firstly */
+ rtgui_filelist_view_clear(view);
+ if (directory != RT_NULL)
+ {
+ DIR* dir;
+ struct stat s;
+ char* fullpath;
+ rt_uint32_t index;
+ struct dirent* dirent;
+
+ view->items_count = 0;
+ dir = opendir(directory);
+ if (dir == RT_NULL) goto __return;
+
+ /* current directory exists, set it */
+ if (view->current_directory != RT_NULL) rt_free(view->current_directory);
+ view->current_directory = rt_strdup(directory);
+
+ do
+ {
+ dirent = readdir(dir);
+ if (dirent == RT_NULL) break;
+
+ if (strcmp(dirent->d_name, ".") == 0) continue;
+ if (strcmp(dirent->d_name, "..") == 0) continue;
+
+ view->items_count ++;
+ } while (dirent != RT_NULL);
+ closedir(dir);
+
+ view->items_count ++; /* root directory for [x] exit, others for .. */
+
+ view->items = (struct rtgui_file_item*) rtgui_malloc(sizeof(struct rtgui_file_item) * view->items_count);
+ if (view->items == RT_NULL) return; /* no memory */
+
+ index = 0;
+ if (directory[0] == '/' && directory[1] != '\0')
+ {
+ item = &(view->items[0]);
+
+ /* add .. directory */
+ item->name = rt_strdup("..");
+ item->type = RTGUI_FITEM_DIR;
+ item->size = 0;
+
+ index ++;
+ }
+ else
+ {
+ item = &(view->items[0]);
+
+ /* add .. directory */
+ item->name = rt_strdup("�X�̐`��㚔M");
+ item->type = RTGUI_FITEM_DIR;
+ item->size = 0;
+
+ index ++;
+ }
+
+ /* reopen directory */
+ dir = opendir(directory);
+ fullpath = rtgui_malloc(256);
+ while (index < view->items_count)
+ {
+ dirent = readdir(dir);
+ if (dirent == RT_NULL) break;
+
+ if (strcmp(dirent->d_name, ".") == 0) continue;
+ if (strcmp(dirent->d_name, "..") == 0) continue;
+
+ item = &(view->items[index]);
+ item->name = rt_strdup(dirent->d_name);
+
+ rt_memset(&s, 0, sizeof(struct stat));
+
+ /* build full path for the file */
+ if (directory[strlen(directory) - 1] != PATH_SEPARATOR)
+ rt_snprintf(fullpath, 256, "%s%c%s", directory, PATH_SEPARATOR, dirent->d_name);
+ else
+ rt_snprintf(fullpath, 256, "%s%s", directory, dirent->d_name);
+
+ stat(fullpath, &s);
+ if ( s.st_mode & S_IFDIR )
+ {
+ item->type = RTGUI_FITEM_DIR;
+ item->size = 0;
+ }
+ else
+ {
+ item->type = RTGUI_FITEM_FILE;
+ item->size = s.st_size;
+ }
+
+ index ++;
+ }
+ rtgui_free(fullpath);
+ closedir(dir);
+ }
+
+ view->current_item = 0;
+
+__return:
+ /* update view */
+ rtgui_widget_update(RTGUI_WIDGET(view));
+}
+
+void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len)
+{
+ RT_ASSERT(view != RT_NULL);
+
+ if (view->current_directory[strlen(view->current_directory) - 1] != PATH_SEPARATOR)
+ rt_snprintf(path, len, "%s%c%s",view->current_directory, PATH_SEPARATOR,
+ view->items[view->current_item].name);
+ else
+ rt_snprintf(path, len, "%s%s",view->current_directory,
+ view->items[view->current_item].name);
+}
+#endif
diff --git a/components/rtgui/widgets/iconbox.c b/components/rtgui/widgets/iconbox.c
index 860fc44476..1ba74e3ce2 100644
--- a/components/rtgui/widgets/iconbox.c
+++ b/components/rtgui/widgets/iconbox.c
@@ -19,7 +19,7 @@ static void _rtgui_iconbox_constructor(rtgui_iconbox_t *iconbox)
{
/* init widget and set event handler */
RTGUI_WIDGET(iconbox)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT;
- rtgui_widget_set_event_handler(RTGUI_WIDGET(iconbox), rtgui_iconbox_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(iconbox), rtgui_iconbox_event_handler);
/* set proper of control */
iconbox->image = RT_NULL;
@@ -46,9 +46,14 @@ DEFINE_CLASS_TYPE(iconbox, "iconbox",
_rtgui_iconbox_destructor,
sizeof(struct rtgui_iconbox));
-rt_bool_t rtgui_iconbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{
- struct rtgui_iconbox* iconbox = (struct rtgui_iconbox*)widget;
+ struct rtgui_iconbox* iconbox;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ iconbox = RTGUI_ICONBOX(object);
switch (event->type)
{
diff --git a/components/rtgui/widgets/label.c b/components/rtgui/widgets/label.c
index 59cf22b6f4..db8528e139 100644
--- a/components/rtgui/widgets/label.c
+++ b/components/rtgui/widgets/label.c
@@ -19,7 +19,7 @@
static void _rtgui_label_constructor(rtgui_label_t *label)
{
/* init widget and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(label), rtgui_label_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(label), rtgui_label_event_handler);
/* set field */
label->text = RT_NULL;
@@ -38,13 +38,12 @@ DEFINE_CLASS_TYPE(label, "label",
_rtgui_label_destructor,
sizeof(struct rtgui_label));
-rt_bool_t rtgui_label_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_label_event_handler(struct rtgui_object *object, struct rtgui_event* event)
{
- struct rtgui_label* label;
+ struct rtgui_label *label;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
- RT_ASSERT(widget != RT_NULL);
-
- label = (struct rtgui_label*) widget;
+ label = RTGUI_LABEL(object);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
diff --git a/components/rtgui/widgets/list_view.c b/components/rtgui/widgets/list_view.c
index 99783f2cf3..1b45365271 100644
--- a/components/rtgui/widgets/list_view.c
+++ b/components/rtgui/widgets/list_view.c
@@ -1,636 +1,636 @@
-/*
- * File : list_view.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-01-06 Bernard first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/list_view.h>
-
-#define LIST_MARGIN 5
-
-static void _rtgui_list_view_constructor(struct rtgui_list_view *view)
-{
- /* default rect */
- struct rtgui_rect rect = {0, 0, 200, 200};
-
- /* set default widget rect and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(view),rtgui_list_view_event_handler);
- rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
-
- RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
- view->flag = RTGUI_LIST_VIEW_LIST;
- view->current_item = 0;
- view->items_count = 0;
- view->page_items = 0;
-
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(listview, "listview",
- RTGUI_VIEW_TYPE,
- _rtgui_list_view_constructor,
- RT_NULL,
- sizeof(struct rtgui_list_view));
-
-static void rtgui_list_view_onicondraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
-{
- struct rtgui_rect rect, item_rect, drawing_rect;
- rt_ubase_t c, r, item_index; /* col and row index */
- rt_ubase_t item_width, item_height;
- rtgui_image_t* image;
-
- if (view->items_count == 0) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
- item_index = (view->current_item / view->page_items) * view->page_items;
-
- item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
- item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
- image = view->items[0].image;
-
- for (r = 0; r < view->row_items; r ++)
- {
- for (c = 0; c < view->col_items; c ++)
- {
- if (item_index < view->items_count)
- {
- item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
- item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
- item_rect.x2 = item_rect.x1 + item_width;
- item_rect.y2 = item_rect.y1 + item_height;
-
- if (item_index == view->current_item)
- {
- rtgui_theme_draw_selected(dc, &item_rect);
- }
-
- drawing_rect.x1 = drawing_rect.y1 = 0;
- drawing_rect.x2 = image->w;
- drawing_rect.y2 = image->h;
- rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
- drawing_rect.y1 += 5; drawing_rect.y2 += 5;
- rtgui_image_blit(view->items[item_index].image, dc, &drawing_rect);
-
- item_rect.y1 = drawing_rect.y2 + LIST_MARGIN;
- item_rect.x1 += 3; item_rect.x2 -=3;
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[item_index].name,
- &drawing_rect);
- rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
- rtgui_dc_draw_text(dc, view->items[item_index].name, &drawing_rect);
-
- item_index ++;
- }
- else break;
- }
- }
-}
-
-static void rtgui_list_view_update_icon(struct rtgui_list_view* view, rt_int16_t old_item)
-{
- struct rtgui_rect rect, item_rect, drawing_rect;
- rt_ubase_t c, r; /* col and row index */
- rt_ubase_t item_width, item_height;
- rtgui_image_t* image;
- struct rtgui_dc* dc;
-
- if ((view->items_count == 0) ||
- (old_item == view->current_item))
- return;
-
- if (old_item/view->page_items != view->current_item/view->page_items)
- {
- /* it's not a same page, update all */
- rtgui_widget_update(RTGUI_WIDGET(view));
- return;
- }
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
- item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
- item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
- image = view->items[0].image;
-
- /* update old item */
- r = (old_item % view->page_items)/ view->col_items;
- c = (old_item % view->page_items)% view->col_items;
- item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
- item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
- item_rect.x2 = item_rect.x1 + item_width;
- item_rect.y2 = item_rect.y1 + item_height;
- rtgui_dc_fill_rect(dc, &item_rect);
-
- /* draw image */
- drawing_rect.x1 = drawing_rect.y1 = 0;
- drawing_rect.x2 = image->w;
- drawing_rect.y2 = image->h;
- rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
- drawing_rect.y1 += 5; drawing_rect.y2 += 5;
- rtgui_image_blit(view->items[old_item].image, dc, &drawing_rect);
-
- /* draw text */
- item_rect.y1 = drawing_rect.y2 + LIST_MARGIN;
- item_rect.x1 += 3; item_rect.x2 -=3;
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[old_item].name,
- &drawing_rect);
- rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
- rtgui_dc_draw_text(dc, view->items[old_item].name, &drawing_rect);
-
- /* update new item as selected */
- r = (view->current_item % view->page_items) / view->col_items;
- c = (view->current_item % view->page_items) % view->col_items;
- item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
- item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
- item_rect.x2 = item_rect.x1 + item_width;
- item_rect.y2 = item_rect.y1 + item_height;
- rtgui_theme_draw_selected(dc, &item_rect);
-
- /* draw image */
- drawing_rect.x1 = 0;
- drawing_rect.y1 = 3;
- drawing_rect.x2 = image->w;
- drawing_rect.y2 = 3 + image->h;
-
- rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
- rtgui_image_blit(view->items[view->current_item].image, dc, &drawing_rect);
-
- /* draw text */
- item_rect.y1 = drawing_rect.y2 + LIST_MARGIN;
- item_rect.x1 += 3; item_rect.x2 -=3;
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)),
- view->items[view->current_item].name,
- &drawing_rect);
- rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
- rtgui_dc_draw_text(dc, view->items[view->current_item].name, &drawing_rect);
-
- rtgui_dc_end_drawing(dc);
-}
-
-static void rtgui_list_view_onlistdraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
-{
- rt_ubase_t index, page_index;
- rtgui_rect_t rect, item_rect, image_rect;
- const struct rtgui_list_item* item;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
- /* get item base rect */
- item_rect = rect;
- item_rect.y1 += 2;
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* get current page */
- page_index = (view->current_item / view->page_items) * view->page_items;
- for (index = 0; index < view->page_items; index ++)
- {
- if (page_index + index >= view->items_count) break;
-
- item = &(view->items[page_index + index]);
-
- if (page_index + index == view->current_item)
- {
- rtgui_theme_draw_selected(dc, &item_rect);
- }
- item_rect.x1 += LIST_MARGIN;
-
- if (item->image != RT_NULL)
- {
- /* blit on center */
- image_rect.x1 = 0; image_rect.y1 = 0;
- image_rect.x2 = item->image->w;
- image_rect.y2 = item->image->h;
-
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
- rtgui_image_blit(item->image, dc, &image_rect);
- item_rect.x1 += item->image->w + 2;
- }
- /* draw text */
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- if (item->image != RT_NULL)
- item_rect.x1 -= (item->image->w + 2);
- item_rect.x1 -= LIST_MARGIN;
-
- /* move to next item position */
- item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
- item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
- }
-}
-
-void rtgui_list_view_update_list(struct rtgui_list_view* view, rt_int16_t old_item)
-{
- struct rtgui_dc* dc;
- const struct rtgui_list_item* item;
- rtgui_rect_t rect, item_rect;
-
- if (old_item/view->page_items != view->current_item/view->page_items)
- {
- /* it's not a same page, update all */
- rtgui_widget_update(RTGUI_WIDGET(view));
- return;
- }
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
- /* get old item's rect and draw old item */
- item_rect.x1 = rect.x1; item_rect.x2 = rect.x2;
- item_rect.y1 = rect.y1 + 2;
- item_rect.y1 += (old_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
- rtgui_dc_fill_rect(dc, &item_rect);
-
- item_rect.x1 += LIST_MARGIN;
-
- item = &(view->items[old_item]);
- if (item->image != RT_NULL)
- {
- struct rtgui_rect image_rect;
-
- /* blit on center */
- image_rect.x1 = 0; image_rect.y1 = 0;
- image_rect.x2 = item->image->w;
- image_rect.y2 = item->image->h;
-
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
- rtgui_image_blit(item->image, dc, &image_rect);
- item_rect.x1 += item->image->w + 2;
- }
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- /* draw current item */
- item_rect = rect;
- /* get current item's rect */
- item_rect.y1 += 2;
- item_rect.y1 += (view->current_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* draw current item */
- rtgui_theme_draw_selected(dc, &item_rect);
-
- item_rect.x1 += LIST_MARGIN;
-
- item = &(view->items[view->current_item]);
- if (item->image != RT_NULL)
- {
- struct rtgui_rect image_rect;
-
- /* blit on center */
- image_rect.x1 = 0; image_rect.y1 = 0;
- image_rect.x2 = item->image->w;
- image_rect.y2 = item->image->h;
-
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
- rtgui_image_blit(item->image, dc, &image_rect);
- item_rect.x1 += (item->image->w + 2);
- }
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- rtgui_dc_end_drawing(dc);
-}
-
-void rtgui_list_view_ondraw(struct rtgui_list_view* view)
-{
- struct rtgui_rect rect;
- struct rtgui_dc* dc;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- switch (view->flag)
- {
- case RTGUI_LIST_VIEW_LIST:
- rtgui_list_view_onlistdraw(view, dc);
- break;
-
- case RTGUI_LIST_VIEW_ICON:
- rtgui_list_view_onicondraw(view, dc);
- break;
- }
-
- rtgui_dc_end_drawing(dc);
-}
-
-static rt_bool_t rtgui_list_view_onmouse(struct rtgui_list_view* view, struct rtgui_event_mouse* emouse)
-{
- rtgui_rect_t rect;
-
- /* calculate selected item */
-
- /* get physical extent information */
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
- rtgui_widget_rect_to_device(RTGUI_WIDGET(view), &rect);
-
- if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
- {
- rt_uint16_t index;
- rt_uint16_t old_item;
-
- /* get old item */
- old_item = view->current_item;
-
- switch (view->flag)
- {
- case RTGUI_LIST_VIEW_LIST:
- index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-
- if ((index < view->items_count) && (index < view->page_items))
- {
- /* set selected item */
- view->current_item = (view->current_item/view->page_items) * view->page_items + index;
- if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- /* down event */
- rtgui_list_view_update_list(view, old_item);
- }
- else
- {
- /* up event */
- if (view->items[view->current_item].action != RT_NULL)
- {
- view->items[view->current_item].action(RTGUI_WIDGET(view),
- view->items[view->current_item].parameter);
- }
- }
- }
- break;
-
- case RTGUI_LIST_VIEW_ICON:
- {
- rt_uint16_t x, y;
- rt_uint16_t item_height, item_width;
- rt_ubase_t current_page;
-
- item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
- item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
- x = emouse->x - rect.x1;
- y = emouse->y - rect.y1;
-
- index = (y / item_height * view->col_items) + x / item_width;
- current_page = view->current_item / view->page_items;
-
- if ((index + (current_page * view->page_items) < view->items_count))
- {
- if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- view->current_item = index + (current_page * view->page_items);
-
- /* down event */
- rtgui_list_view_update_icon(view, old_item);
- }
- else
- {
- /* up event */
- if (view->items[view->current_item].action != RT_NULL)
- {
- view->items[view->current_item].action(RTGUI_WIDGET(view),
- view->items[view->current_item].parameter);
- }
- }
- }
- }
- break;
-
- case RTGUI_LIST_VIEW_REPORT:
- break;
- }
-
- return RT_TRUE;
- }
-
- return RT_FALSE;
-}
-
-rt_bool_t rtgui_list_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_list_view* view = RT_NULL;
-
- view = RTGUI_LIST_VIEW(widget);
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- rtgui_list_view_ondraw(view);
- return RT_FALSE;
-
- case RTGUI_EVENT_RESIZE:
- {
- struct rtgui_event_resize* resize;
-
- resize = (struct rtgui_event_resize*)event;
-
- /* recalculate page items */
- view->page_items = resize->h / (2 + rtgui_theme_get_selected_height());
- }
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- {
- struct rtgui_event_mouse* emouse;
-
- emouse = (struct rtgui_event_mouse*)event;
- return rtgui_list_view_onmouse(view, emouse);
- }
-
- case RTGUI_EVENT_KBD:
- {
- struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
- if (ekbd->type == RTGUI_KEYDOWN)
- {
- rt_uint16_t old_item;
-
- if (view->current_item == -1)
- {
- /* set a initial item */
- if ((view->items_count > 0) &&
- (ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
- {
- view->current_item = 0;
- if (view->flag == RTGUI_LIST_VIEW_LIST)
- rtgui_list_view_update_list(view, -1);
- else
- rtgui_list_view_update_icon(view, -1);
- break;
- }
- else return RT_FALSE;
- }
-
- old_item = view->current_item;
- switch (ekbd->key)
- {
- case RTGUIK_LEFT:
- if (view->flag == RTGUI_LIST_VIEW_LIST)
- {
- if (view->current_item - view->page_items >= 0)
- view->current_item -= view->page_items;
-
- rtgui_list_view_update_list(view, old_item);
- }
- else if (view->flag == RTGUI_LIST_VIEW_ICON)
- {
- if (view->current_item > 0)
- view->current_item --;
- rtgui_list_view_update_icon(view, old_item);
- }
- return RT_FALSE;
-
- case RTGUIK_UP:
- if (view->flag == RTGUI_LIST_VIEW_LIST)
- {
- if (view->current_item > 0)
- view->current_item --;
- rtgui_list_view_update_list(view, old_item);
- }
- else if (view->flag == RTGUI_LIST_VIEW_ICON)
- {
- if (view->current_item >= view->col_items)
- view->current_item -= view->col_items;
- else
- view->current_item = 0;
-
- rtgui_list_view_update_icon(view, old_item);
- }
- return RT_FALSE;
-
- case RTGUIK_RIGHT:
- if (view->flag == RTGUI_LIST_VIEW_LIST)
- {
- if (view->current_item + view->page_items < view->items_count - 1)
- view->current_item += view->page_items;
-
- rtgui_list_view_update_list(view, old_item);
- }
- else if (view->flag == RTGUI_LIST_VIEW_ICON)
- {
- if (view->current_item < view->items_count - 1)
- view->current_item ++;
-
- rtgui_list_view_update_icon(view, old_item);
- }
- return RT_FALSE;
-
- case RTGUIK_DOWN:
- if (view->flag == RTGUI_LIST_VIEW_LIST)
- {
- if (view->current_item < view->items_count - 1)
- view->current_item ++;
-
- rtgui_list_view_update_list(view, old_item);
- }
- else if (view->flag == RTGUI_LIST_VIEW_ICON)
- {
- if (view->current_item + view->col_items <= (view->items_count - 1))
- view->current_item += view->col_items;
- else
- view->current_item = view->items_count - 1;
-
- rtgui_list_view_update_icon(view, old_item);
- }
- return RT_FALSE;
-
- case RTGUIK_RETURN:
- if (view->items[view->current_item].action != RT_NULL)
- {
- view->items[view->current_item].action(RTGUI_WIDGET(view),
- view->items[view->current_item].parameter);
- }
- return RT_FALSE;
-
- default:
- break;
- }
- }
- }
- return RT_FALSE;
- }
-
- /* use view event handler */
- return rtgui_view_event_handler(widget, event);
-}
-
-static void rtgui_list_view_calc(struct rtgui_list_view* view)
-{
- rtgui_rect_t rect;
- rt_uint32_t image_width, image_height;
- rt_ubase_t text_width, text_height;
- rt_ubase_t item_width, item_height;
-
- if (view->items_count == 0) return;
-
- /* get image width and height */
- if (view->items[0].image != RT_NULL)
- {
- image_width = view->items[0].image->w;
- image_height = view->items[0].image->h;
- }
- else
- {
- image_width = 0;
- image_height = 0;
- }
-
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "HHHHHH", &rect);
-
- text_height = rtgui_rect_height(rect);
- text_width = rtgui_rect_width(rect);
-
- rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
-
- item_width = (image_width + LIST_MARGIN);
- if (item_width < (text_width + LIST_MARGIN)) item_width = text_width + LIST_MARGIN;
- item_height = image_height + 8 + text_height + LIST_MARGIN;
- if (item_width > item_height) item_height = item_width;
- else item_width = item_height;
-
- view->row_items = (rtgui_rect_height(rect) - 2 * LIST_MARGIN) / item_height;
- view->col_items = (rtgui_rect_width(rect) - 2 * LIST_MARGIN) / item_width;
- view->page_items = view->row_items * view->col_items;
-}
-
-rtgui_list_view_t* rtgui_list_view_create(const struct rtgui_list_item* items, rt_uint16_t count,
- rtgui_rect_t *rect, rt_uint16_t flag)
-{
- struct rtgui_list_view* view = RT_NULL;
-
- view = (struct rtgui_list_view*) rtgui_widget_create(RTGUI_LIST_VIEW_TYPE);
- if (view != RT_NULL)
- {
- view->items = items;
- view->items_count = count;
-
- view->flag = flag;
- rtgui_widget_set_rect(RTGUI_WIDGET(view), rect);
-
- if (flag == RTGUI_LIST_VIEW_LIST)
- view->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
- else if ((flag == RTGUI_LIST_VIEW_ICON) && (count > 0))
- {
- rtgui_list_view_calc(view);
- }
- }
-
- return view;
-}
-
-void rtgui_list_view_destroy(rtgui_list_view_t* view)
-{
- /* destroy view */
- rtgui_widget_destroy(RTGUI_WIDGET(view));
-}
+/*
+ * File : list_view.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-01-06 Bernard first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/list_view.h>
+
+#define LIST_MARGIN 5
+
+static void _rtgui_list_view_constructor(struct rtgui_list_view *view)
+{
+ /* default rect */
+ struct rtgui_rect rect = {0, 0, 200, 200};
+
+ /* set default widget rect and set event handler */
+ rtgui_object_set_event_handler(RTGUI_OBJECT(view),rtgui_list_view_event_handler);
+ rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
+
+ RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ view->flag = RTGUI_LIST_VIEW_LIST;
+ view->current_item = 0;
+ view->items_count = 0;
+ view->page_items = 0;
+
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(view)) = white;
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(listview, "listview",
+ RTGUI_CONTAINER_TYPE,
+ _rtgui_list_view_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_list_view));
+
+static void rtgui_list_view_onicondraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
+{
+ struct rtgui_rect rect, item_rect, drawing_rect;
+ rt_ubase_t c, r, item_index; /* col and row index */
+ rt_ubase_t item_width, item_height;
+ rtgui_image_t* image;
+
+ if (view->items_count == 0) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+ item_index = (view->current_item / view->page_items) * view->page_items;
+
+ item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
+ item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
+ image = view->items[0].image;
+
+ for (r = 0; r < view->row_items; r ++)
+ {
+ for (c = 0; c < view->col_items; c ++)
+ {
+ if (item_index < view->items_count)
+ {
+ item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
+ item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
+ item_rect.x2 = item_rect.x1 + item_width;
+ item_rect.y2 = item_rect.y1 + item_height;
+
+ if (item_index == view->current_item)
+ {
+ rtgui_theme_draw_selected(dc, &item_rect);
+ }
+
+ drawing_rect.x1 = drawing_rect.y1 = 0;
+ drawing_rect.x2 = image->w;
+ drawing_rect.y2 = image->h;
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ drawing_rect.y1 += 5; drawing_rect.y2 += 5;
+ rtgui_image_blit(view->items[item_index].image, dc, &drawing_rect);
+
+ item_rect.y1 = drawing_rect.y2 + LIST_MARGIN;
+ item_rect.x1 += 3; item_rect.x2 -=3;
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[item_index].name,
+ &drawing_rect);
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ rtgui_dc_draw_text(dc, view->items[item_index].name, &drawing_rect);
+
+ item_index ++;
+ }
+ else break;
+ }
+ }
+}
+
+static void rtgui_list_view_update_icon(struct rtgui_list_view* view, rt_uint16_t old_item)
+{
+ struct rtgui_rect rect, item_rect, drawing_rect;
+ rt_ubase_t c, r; /* col and row index */
+ rt_ubase_t item_width, item_height;
+ rtgui_image_t* image;
+ struct rtgui_dc* dc;
+
+ if ((view->items_count == 0) ||
+ (old_item == view->current_item))
+ return;
+
+ if (old_item/view->page_items != view->current_item/view->page_items)
+ {
+ /* it's not a same page, update all */
+ rtgui_widget_update(RTGUI_WIDGET(view));
+ return;
+ }
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+ item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
+ item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
+ image = view->items[0].image;
+
+ /* update old item */
+ r = (old_item % view->page_items)/ view->col_items;
+ c = (old_item % view->page_items)% view->col_items;
+ item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
+ item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
+ item_rect.x2 = item_rect.x1 + item_width;
+ item_rect.y2 = item_rect.y1 + item_height;
+ rtgui_dc_fill_rect(dc, &item_rect);
+
+ /* draw image */
+ drawing_rect.x1 = drawing_rect.y1 = 0;
+ drawing_rect.x2 = image->w;
+ drawing_rect.y2 = image->h;
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ drawing_rect.y1 += 5; drawing_rect.y2 += 5;
+ rtgui_image_blit(view->items[old_item].image, dc, &drawing_rect);
+
+ /* draw text */
+ item_rect.y1 = drawing_rect.y2 + LIST_MARGIN;
+ item_rect.x1 += 3; item_rect.x2 -=3;
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), view->items[old_item].name,
+ &drawing_rect);
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ rtgui_dc_draw_text(dc, view->items[old_item].name, &drawing_rect);
+
+ /* update new item as selected */
+ r = (view->current_item % view->page_items) / view->col_items;
+ c = (view->current_item % view->page_items) % view->col_items;
+ item_rect.y1 = rect.y1 + LIST_MARGIN + r * item_height;
+ item_rect.x1 = rect.x1 + LIST_MARGIN + c * item_width;
+ item_rect.x2 = item_rect.x1 + item_width;
+ item_rect.y2 = item_rect.y1 + item_height;
+ rtgui_theme_draw_selected(dc, &item_rect);
+
+ /* draw image */
+ drawing_rect.x1 = 0;
+ drawing_rect.y1 = 3;
+ drawing_rect.x2 = image->w;
+ drawing_rect.y2 = 3 + image->h;
+
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ rtgui_image_blit(view->items[view->current_item].image, dc, &drawing_rect);
+
+ /* draw text */
+ item_rect.y1 = drawing_rect.y2 + LIST_MARGIN;
+ item_rect.x1 += 3; item_rect.x2 -=3;
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)),
+ view->items[view->current_item].name,
+ &drawing_rect);
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ rtgui_dc_draw_text(dc, view->items[view->current_item].name, &drawing_rect);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_list_view_onlistdraw(struct rtgui_list_view* view, struct rtgui_dc *dc)
+{
+ rt_ubase_t index, page_index;
+ rtgui_rect_t rect, item_rect, image_rect;
+ const struct rtgui_list_item* item;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+ /* get item base rect */
+ item_rect = rect;
+ item_rect.y1 += 2;
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* get current page */
+ page_index = (view->current_item / view->page_items) * view->page_items;
+ for (index = 0; index < view->page_items; index ++)
+ {
+ if (page_index + index >= view->items_count) break;
+
+ item = &(view->items[page_index + index]);
+
+ if (page_index + index == view->current_item)
+ {
+ rtgui_theme_draw_selected(dc, &item_rect);
+ }
+ item_rect.x1 += LIST_MARGIN;
+
+ if (item->image != RT_NULL)
+ {
+ /* blit on center */
+ image_rect.x1 = 0; image_rect.y1 = 0;
+ image_rect.x2 = item->image->w;
+ image_rect.y2 = item->image->h;
+
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+ rtgui_image_blit(item->image, dc, &image_rect);
+ item_rect.x1 += item->image->w + 2;
+ }
+ /* draw text */
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ if (item->image != RT_NULL)
+ item_rect.x1 -= (item->image->w + 2);
+ item_rect.x1 -= LIST_MARGIN;
+
+ /* move to next item position */
+ item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
+ item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
+ }
+}
+
+void rtgui_list_view_update_list(struct rtgui_list_view* view, rt_uint16_t old_item)
+{
+ struct rtgui_dc* dc;
+ const struct rtgui_list_item* item;
+ rtgui_rect_t rect, item_rect;
+
+ if (old_item/view->page_items != view->current_item/view->page_items)
+ {
+ /* it's not a same page, update all */
+ rtgui_widget_update(RTGUI_WIDGET(view));
+ return;
+ }
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+ /* get old item's rect and draw old item */
+ item_rect.x1 = rect.x1; item_rect.x2 = rect.x2;
+ item_rect.y1 = rect.y1 + 2;
+ item_rect.y1 += (old_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+ rtgui_dc_fill_rect(dc, &item_rect);
+
+ item_rect.x1 += LIST_MARGIN;
+
+ item = &(view->items[old_item]);
+ if (item->image != RT_NULL)
+ {
+ struct rtgui_rect image_rect;
+
+ /* blit on center */
+ image_rect.x1 = 0; image_rect.y1 = 0;
+ image_rect.x2 = item->image->w;
+ image_rect.y2 = item->image->h;
+
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+ rtgui_image_blit(item->image, dc, &image_rect);
+ item_rect.x1 += item->image->w + 2;
+ }
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ /* draw current item */
+ item_rect = rect;
+ /* get current item's rect */
+ item_rect.y1 += 2;
+ item_rect.y1 += (view->current_item % view->page_items) * (2 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* draw current item */
+ rtgui_theme_draw_selected(dc, &item_rect);
+
+ item_rect.x1 += LIST_MARGIN;
+
+ item = &(view->items[view->current_item]);
+ if (item->image != RT_NULL)
+ {
+ struct rtgui_rect image_rect;
+
+ /* blit on center */
+ image_rect.x1 = 0; image_rect.y1 = 0;
+ image_rect.x2 = item->image->w;
+ image_rect.y2 = item->image->h;
+
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+ rtgui_image_blit(item->image, dc, &image_rect);
+ item_rect.x1 += (item->image->w + 2);
+ }
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_list_view_ondraw(struct rtgui_list_view* view)
+{
+ struct rtgui_rect rect;
+ struct rtgui_dc* dc;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ switch (view->flag)
+ {
+ case RTGUI_LIST_VIEW_LIST:
+ rtgui_list_view_onlistdraw(view, dc);
+ break;
+
+ case RTGUI_LIST_VIEW_ICON:
+ rtgui_list_view_onicondraw(view, dc);
+ break;
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+static rt_bool_t rtgui_list_view_onmouse(struct rtgui_list_view* view, struct rtgui_event_mouse* emouse)
+{
+ rtgui_rect_t rect;
+
+ /* calculate selected item */
+
+ /* get physical extent information */
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+ rtgui_widget_rect_to_device(RTGUI_WIDGET(view), &rect);
+
+ if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+ {
+ rt_uint16_t index;
+ rt_uint16_t old_item;
+
+ /* get old item */
+ old_item = view->current_item;
+
+ switch (view->flag)
+ {
+ case RTGUI_LIST_VIEW_LIST:
+ index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+ if ((index < view->items_count) && (index < view->page_items))
+ {
+ /* set selected item */
+ view->current_item = (view->current_item/view->page_items) * view->page_items + index;
+ if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ /* down event */
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else
+ {
+ /* up event */
+ if (view->items[view->current_item].action != RT_NULL)
+ {
+ view->items[view->current_item].action(RTGUI_WIDGET(view),
+ view->items[view->current_item].parameter);
+ }
+ }
+ }
+ break;
+
+ case RTGUI_LIST_VIEW_ICON:
+ {
+ rt_uint16_t x, y;
+ rt_uint16_t item_height, item_width;
+ rt_ubase_t current_page;
+
+ item_width = (rtgui_rect_width(rect) - 2 * LIST_MARGIN)/view->col_items;
+ item_height = (rtgui_rect_height(rect) - 4)/view->row_items;
+ x = emouse->x - rect.x1;
+ y = emouse->y - rect.y1;
+
+ index = (y / item_height * view->col_items) + x / item_width;
+ current_page = view->current_item / view->page_items;
+
+ if ((index + (current_page * view->page_items) < view->items_count))
+ {
+ if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ view->current_item = index + (current_page * view->page_items);
+
+ /* down event */
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ else
+ {
+ /* up event */
+ if (view->items[view->current_item].action != RT_NULL)
+ {
+ view->items[view->current_item].action(RTGUI_WIDGET(view),
+ view->items[view->current_item].parameter);
+ }
+ }
+ }
+ }
+ break;
+
+ case RTGUI_LIST_VIEW_REPORT:
+ break;
+ }
+
+ return RT_TRUE;
+ }
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_list_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event)
+{
+ struct rtgui_list_view* view = RT_NULL;
+
+ view = RTGUI_LIST_VIEW(widget);
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ rtgui_list_view_ondraw(view);
+ return RT_FALSE;
+
+ case RTGUI_EVENT_RESIZE:
+ {
+ struct rtgui_event_resize* resize;
+
+ resize = (struct rtgui_event_resize*)event;
+
+ /* recalculate page items */
+ view->page_items = resize->h / (2 + rtgui_theme_get_selected_height());
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ struct rtgui_event_mouse* emouse;
+
+ emouse = (struct rtgui_event_mouse*)event;
+ return rtgui_list_view_onmouse(view, emouse);
+ }
+
+ case RTGUI_EVENT_KBD:
+ {
+ struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+ if (ekbd->type == RTGUI_KEYDOWN)
+ {
+ rt_uint16_t old_item;
+
+ if (view->current_item == -1)
+ {
+ /* set a initial item */
+ if ((view->items_count > 0) &&
+ (ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
+ {
+ view->current_item = 0;
+ if (view->flag == RTGUI_LIST_VIEW_LIST)
+ rtgui_list_view_update_list(view, -1);
+ else
+ rtgui_list_view_update_icon(view, -1);
+ break;
+ }
+ else return RT_FALSE;
+ }
+
+ old_item = view->current_item;
+ switch (ekbd->key)
+ {
+ case RTGUIK_LEFT:
+ if (view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if (view->current_item - view->page_items >= 0)
+ view->current_item -= view->page_items;
+
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if (view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if (view->current_item > 0)
+ view->current_item --;
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_UP:
+ if (view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if (view->current_item > 0)
+ view->current_item --;
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if (view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if (view->current_item >= view->col_items)
+ view->current_item -= view->col_items;
+ else
+ view->current_item = 0;
+
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_RIGHT:
+ if (view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if (view->current_item + view->page_items < view->items_count - 1)
+ view->current_item += view->page_items;
+
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if (view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if (view->current_item < view->items_count - 1)
+ view->current_item ++;
+
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_DOWN:
+ if (view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if (view->current_item < view->items_count - 1)
+ view->current_item ++;
+
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if (view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if (view->current_item + view->col_items <= (view->items_count - 1))
+ view->current_item += view->col_items;
+ else
+ view->current_item = view->items_count - 1;
+
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_RETURN:
+ if (view->items[view->current_item].action != RT_NULL)
+ {
+ view->items[view->current_item].action(RTGUI_WIDGET(view),
+ view->items[view->current_item].parameter);
+ }
+ return RT_FALSE;
+
+ default:
+ break;
+ }
+ }
+ }
+ return RT_FALSE;
+ }
+
+ /* use view event handler */
+ return rtgui_container_event_handler(widget, event);
+}
+
+static void rtgui_list_view_calc(struct rtgui_list_view* view)
+{
+ rtgui_rect_t rect;
+ rt_uint32_t image_width, image_height;
+ rt_ubase_t text_width, text_height;
+ rt_ubase_t item_width, item_height;
+
+ if (view->items_count == 0) return;
+
+ /* get image width and height */
+ if (view->items[0].image != RT_NULL)
+ {
+ image_width = view->items[0].image->w;
+ image_height = view->items[0].image->h;
+ }
+ else
+ {
+ image_width = 0;
+ image_height = 0;
+ }
+
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(view)), "HHHHHH", &rect);
+
+ text_height = rtgui_rect_height(rect);
+ text_width = rtgui_rect_width(rect);
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
+
+ item_width = (image_width + LIST_MARGIN);
+ if (item_width < (text_width + LIST_MARGIN)) item_width = text_width + LIST_MARGIN;
+ item_height = image_height + 8 + text_height + LIST_MARGIN;
+ if (item_width > item_height) item_height = item_width;
+ else item_width = item_height;
+
+ view->row_items = (rtgui_rect_height(rect) - 2 * LIST_MARGIN) / item_height;
+ view->col_items = (rtgui_rect_width(rect) - 2 * LIST_MARGIN) / item_width;
+ view->page_items = view->row_items * view->col_items;
+}
+
+rtgui_list_view_t* rtgui_list_view_create(const struct rtgui_list_item* items, rt_uint16_t count,
+ rtgui_rect_t *rect, rt_uint16_t flag)
+{
+ struct rtgui_list_view* view = RT_NULL;
+
+ view = (struct rtgui_list_view*) rtgui_widget_create(RTGUI_LIST_VIEW_TYPE);
+ if (view != RT_NULL)
+ {
+ view->items = items;
+ view->items_count = count;
+
+ view->flag = flag;
+ rtgui_widget_set_rect(RTGUI_WIDGET(view), rect);
+
+ if (flag == RTGUI_LIST_VIEW_LIST)
+ view->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
+ else if ((flag == RTGUI_LIST_VIEW_ICON) && (count > 0))
+ {
+ rtgui_list_view_calc(view);
+ }
+ }
+
+ return view;
+}
+
+void rtgui_list_view_destroy(rtgui_list_view_t* view)
+{
+ /* destroy view */
+ rtgui_widget_destroy(RTGUI_WIDGET(view));
+}
diff --git a/components/rtgui/widgets/listbox.c b/components/rtgui/widgets/listbox.c
index 0ce5aebe32..859cbc1304 100644
--- a/components/rtgui/widgets/listbox.c
+++ b/components/rtgui/widgets/listbox.c
@@ -1,387 +1,388 @@
-/*
- * File : listbox.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-01-06 Bernard first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/listbox.h>
-
-#define LIST_MARGIN 5
-
-static void _rtgui_listbox_constructor(struct rtgui_listbox *box)
-{
- /* set default widget rect and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(box),rtgui_listbox_event_handler);
-
- RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
- box->current_item = -1;
- box->items_count = 0;
- box->page_items = 1;
- box->on_item = 0;
-
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(listbox, "listbox",
- RTGUI_WIDGET_TYPE,
- _rtgui_listbox_constructor,
- RT_NULL,
- sizeof(struct rtgui_listbox));
-
-void rtgui_listbox_ondraw(struct rtgui_listbox* box)
-{
- struct rtgui_dc* dc;
- rt_uint16_t page_index, index;
- const struct rtgui_listbox_item* item;
- struct rtgui_rect rect, item_rect, image_rect;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- rect.x2 -= 1; rect.y2 -= 1;
- /* draw focused border */
- if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
- rtgui_dc_draw_focus_rect(dc, &rect);
-
- /* get item base rect */
- item_rect = rect;
- item_rect.x1 += 1; item_rect.x2 -= 1;
- item_rect.y1 += 2;
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* get current page */
- if (box->current_item == -1)
- page_index = 0;
- else
- page_index = (box->current_item / box->page_items) * box->page_items;
-
- for (index = 0; index < box->page_items; index ++)
- {
- if (page_index + index >= box->items_count) break;
-
- item = &(box->items[page_index + index]);
-
- if (page_index + index == box->current_item)
- {
- rtgui_theme_draw_selected(dc, &item_rect);
- }
- item_rect.x1 += LIST_MARGIN;
-
- if (item->image != RT_NULL)
- {
- rtgui_image_get_rect(item->image, &image_rect);
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
- rtgui_image_blit(item->image, dc, &image_rect);
- item_rect.x1 += item->image->w + 2;
- }
- /* draw text */
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- if (item->image != RT_NULL)
- item_rect.x1 -= (item->image->w + 2);
- item_rect.x1 -= LIST_MARGIN;
-
- /* move to next item position */
- item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
- item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
- }
- rtgui_dc_end_drawing(dc);
-}
-
-static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t old_item)
-{
- struct rtgui_dc* dc;
- const struct rtgui_listbox_item* item;
- rtgui_rect_t rect, item_rect, image_rect;
-
- if ((old_item == -1) || (old_item/box->page_items != box->current_item/box->page_items))
- {
- /* it's not a same page, update all */
- rtgui_widget_update(RTGUI_WIDGET(box));
- return;
- }
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
- if (dc == RT_NULL) return;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
- rect.x2 -= 1; rect.y2 -= 1;
-
- item_rect = rect;
- /* get old item's rect */
- item_rect.x1 += 1; item_rect.x2 -= 1;
- item_rect.y1 += 2;
- item_rect.y1 += (old_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* draw old item */
- rtgui_dc_fill_rect(dc, &item_rect);
-
- item_rect.x1 += LIST_MARGIN;
-
- item = &(box->items[old_item]);
- if (item->image != RT_NULL)
- {
- rtgui_image_get_rect(item->image, &image_rect);
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
- rtgui_image_blit(item->image, dc, &image_rect);
- item_rect.x1 += item->image->w + 2;
- }
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- /* draw current item */
- item_rect = rect;
- /* get current item's rect */
- item_rect.x1 += 1; item_rect.x2 -= 1;
- item_rect.y1 += 2;
- item_rect.y1 += (box->current_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* draw current item */
- rtgui_theme_draw_selected(dc, &item_rect);
-
- item_rect.x1 += LIST_MARGIN;
-
- item = &(box->items[box->current_item]);
- if (item->image != RT_NULL)
- {
- rtgui_image_get_rect(item->image, &image_rect);
- rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
-
- rtgui_image_blit(item->image, dc, &image_rect);
- item_rect.x1 += (item->image->w + 2);
- }
- rtgui_dc_draw_text(dc, item->name, &item_rect);
-
- rtgui_dc_end_drawing(dc);
-}
-
-rt_bool_t rtgui_listbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_listbox* box = RT_NULL;
-
- box = RTGUI_LISTBOX(widget);
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- rtgui_listbox_ondraw(box);
- return RT_FALSE;
-
- case RTGUI_EVENT_RESIZE:
- {
- struct rtgui_event_resize* resize;
-
- resize = (struct rtgui_event_resize*)event;
-
- /* recalculate page items */
- box->page_items = resize->h / (2 + rtgui_theme_get_selected_height());
- }
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- {
- rtgui_rect_t rect;
- struct rtgui_event_mouse* emouse;
-
- emouse = (struct rtgui_event_mouse*)event;
-
- /* calculate selected item */
-
- /* get physical extent information */
- rtgui_widget_get_rect(widget, &rect);
- rtgui_widget_rect_to_device(widget, &rect);
-
- if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) && (box->items_count > 0))
- {
- rt_uint16_t index;
- index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-
- /* set focus */
- rtgui_widget_focus(widget);
- {
- struct rtgui_rect rect;
- struct rtgui_dc* dc;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
- if (dc != RT_NULL)
- {
- /* get widget rect */
- rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
- /* update focus border */
- rect.x2 -= 1; rect.y2 -= 1;
- /* draw focused border */
- if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
- rtgui_dc_draw_focus_rect(dc, &rect);
- rtgui_dc_end_drawing(dc);
- }
- }
-
- if ((index < box->items_count) && (index < box->page_items))
- {
- rt_uint16_t old_item;
-
- old_item = box->current_item;
-
- /* set selected item */
- box->current_item = (box->current_item/box->page_items) * box->page_items + index;
- if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- /* down event */
- rtgui_listbox_update_current(box, old_item);
- }
- else
- {
- /* up event */
- if (box->on_item != RT_NULL)
- {
- box->on_item(RTGUI_WIDGET(box), RT_NULL);
- }
- }
- }
- }
-
- return RT_TRUE;
- }
-
- case RTGUI_EVENT_KBD:
- {
- struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
- if ((ekbd->type == RTGUI_KEYDOWN) && (box->items_count > 0))
- {
- rt_int16_t old_item;
-
- if (box->current_item == -1)
- {
- /* set a initial item */
- if ((box->items_count > 0) &&
- (ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
- {
- box->current_item = 0;
- rtgui_listbox_update_current(box, -1);
- break;
- }
- else return RT_FALSE;
- }
- old_item = box->current_item;
-
- switch (ekbd->key)
- {
- case RTGUIK_LEFT:
- if (box->current_item - box->page_items >= 0)
- box->current_item -= box->page_items;
- rtgui_listbox_update_current(box, old_item);
- return RT_FALSE;
-
- case RTGUIK_UP:
- if (box->current_item > 0)
- box->current_item --;
- rtgui_listbox_update_current(box, old_item);
- return RT_FALSE;
-
- case RTGUIK_RIGHT:
- if (box->current_item + box->page_items < box->items_count - 1)
- box->current_item += box->page_items;
- rtgui_listbox_update_current(box, old_item);
- return RT_FALSE;
-
- case RTGUIK_DOWN:
- if (box->current_item < box->items_count - 1)
- box->current_item ++;
- rtgui_listbox_update_current(box, old_item);
- return RT_FALSE;
-
- case RTGUIK_RETURN:
- if (box->on_item != RT_NULL)
- {
- box->on_item(RTGUI_WIDGET(box), RT_NULL);
- }
- return RT_FALSE;
-
- default:
- break;
- }
- }
- }
- return RT_FALSE;
- }
-
- /* use box event handler */
- return rtgui_widget_event_handler(widget, event);
-}
-
-rtgui_listbox_t* rtgui_listbox_create(const struct rtgui_listbox_item* items, rt_uint16_t count, rtgui_rect_t *rect)
-{
- struct rtgui_listbox* box = RT_NULL;
-
- box = (struct rtgui_listbox*) rtgui_widget_create(RTGUI_LISTBOX_TYPE);
- if (box != RT_NULL)
- {
- box->items = items;
- box->items_count = count;
-
- box->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
- if (box->page_items == 0) box->page_items = 1;
- rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
- }
-
- return box;
-}
-
-void rtgui_listbox_destroy(rtgui_listbox_t* box)
-{
- /* destroy box */
- rtgui_widget_destroy(RTGUI_WIDGET(box));
-}
-
-void rtgui_listbox_set_onitem(rtgui_listbox_t* box, rtgui_onitem_func_t func)
-{
- RT_ASSERT(box != RT_NULL);
-
- box->on_item = func;
-}
-
-void rtgui_listbox_set_items(rtgui_listbox_t* box, struct rtgui_listbox_item* items, rt_uint16_t count)
-{
- rtgui_rect_t rect;
-
- box->items = items;
- box->items_count = count;
- box->current_item = -1;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
- box->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
-
- rtgui_widget_update(RTGUI_WIDGET(box));
-}
-
-void rtgui_listbox_set_current_item(rtgui_listbox_t* box, int index)
-{
- RT_ASSERT(box != RT_NULL);
-
- if (index != box->current_item)
- {
- int old_item;
-
- old_item = box->current_item;
- box->current_item = index;
-
- rtgui_listbox_update_current(box, old_item);
- }
-}
-
+/*
+ * File : listbox.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-01-06 Bernard first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/listbox.h>
+
+#define LIST_MARGIN 5
+
+static void _rtgui_listbox_constructor(struct rtgui_listbox *box)
+{
+ /* set default widget rect and set event handler */
+ rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_listbox_event_handler);
+
+ RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ box->current_item = -1;
+ box->items_count = 0;
+ box->page_items = 1;
+ box->on_item = 0;
+
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(listbox, "listbox",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_listbox_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_listbox));
+
+void rtgui_listbox_ondraw(struct rtgui_listbox* box)
+{
+ struct rtgui_dc* dc;
+ rt_uint16_t page_index, index;
+ const struct rtgui_listbox_item* item;
+ struct rtgui_rect rect, item_rect, image_rect;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ rect.x2 -= 1; rect.y2 -= 1;
+ /* draw focused border */
+ if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
+ rtgui_dc_draw_focus_rect(dc, &rect);
+
+ /* get item base rect */
+ item_rect = rect;
+ item_rect.x1 += 1; item_rect.x2 -= 1;
+ item_rect.y1 += 2;
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* get current page */
+ if (box->current_item == -1)
+ page_index = 0;
+ else
+ page_index = (box->current_item / box->page_items) * box->page_items;
+
+ for (index = 0; index < box->page_items; index ++)
+ {
+ if (page_index + index >= box->items_count) break;
+
+ item = &(box->items[page_index + index]);
+
+ if (page_index + index == box->current_item)
+ {
+ rtgui_theme_draw_selected(dc, &item_rect);
+ }
+ item_rect.x1 += LIST_MARGIN;
+
+ if (item->image != RT_NULL)
+ {
+ rtgui_image_get_rect(item->image, &image_rect);
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ rtgui_image_blit(item->image, dc, &image_rect);
+ item_rect.x1 += item->image->w + 2;
+ }
+ /* draw text */
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ if (item->image != RT_NULL)
+ item_rect.x1 -= (item->image->w + 2);
+ item_rect.x1 -= LIST_MARGIN;
+
+ /* move to next item position */
+ item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
+ item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
+ }
+ rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t old_item)
+{
+ struct rtgui_dc* dc;
+ const struct rtgui_listbox_item* item;
+ rtgui_rect_t rect, item_rect, image_rect;
+
+ if ((old_item == -1) || (old_item/box->page_items != box->current_item/box->page_items))
+ {
+ /* it's not a same page, update all */
+ rtgui_widget_update(RTGUI_WIDGET(box));
+ return;
+ }
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+ if (dc == RT_NULL) return;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+ rect.x2 -= 1; rect.y2 -= 1;
+
+ item_rect = rect;
+ /* get old item's rect */
+ item_rect.x1 += 1; item_rect.x2 -= 1;
+ item_rect.y1 += 2;
+ item_rect.y1 += (old_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* draw old item */
+ rtgui_dc_fill_rect(dc, &item_rect);
+
+ item_rect.x1 += LIST_MARGIN;
+
+ item = &(box->items[old_item]);
+ if (item->image != RT_NULL)
+ {
+ rtgui_image_get_rect(item->image, &image_rect);
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ rtgui_image_blit(item->image, dc, &image_rect);
+ item_rect.x1 += item->image->w + 2;
+ }
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ /* draw current item */
+ item_rect = rect;
+ /* get current item's rect */
+ item_rect.x1 += 1; item_rect.x2 -= 1;
+ item_rect.y1 += 2;
+ item_rect.y1 += (box->current_item % box->page_items) * (2 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* draw current item */
+ rtgui_theme_draw_selected(dc, &item_rect);
+
+ item_rect.x1 += LIST_MARGIN;
+
+ item = &(box->items[box->current_item]);
+ if (item->image != RT_NULL)
+ {
+ rtgui_image_get_rect(item->image, &image_rect);
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ rtgui_image_blit(item->image, dc, &image_rect);
+ item_rect.x1 += (item->image->w + 2);
+ }
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_listbox* box;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ box = RTGUI_LISTBOX(object);
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ rtgui_listbox_ondraw(box);
+ return RT_FALSE;
+
+ case RTGUI_EVENT_RESIZE:
+ {
+ struct rtgui_event_resize* resize;
+
+ resize = (struct rtgui_event_resize*)event;
+
+ /* recalculate page items */
+ box->page_items = resize->h / (2 + rtgui_theme_get_selected_height());
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_rect_t rect;
+ struct rtgui_event_mouse* emouse;
+
+ emouse = (struct rtgui_event_mouse*)event;
+
+ /* calculate selected item */
+
+ /* get physical extent information */
+ rtgui_widget_get_rect(widget, &rect);
+ rtgui_widget_rect_to_device(widget, &rect);
+
+ if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) && (box->items_count > 0))
+ {
+ rt_uint16_t index;
+ index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+ /* set focus */
+ rtgui_widget_focus(widget);
+ {
+ struct rtgui_rect rect;
+ struct rtgui_dc* dc;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
+ if (dc != RT_NULL)
+ {
+ /* get widget rect */
+ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+ /* update focus border */
+ rect.x2 -= 1; rect.y2 -= 1;
+ /* draw focused border */
+ if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
+ rtgui_dc_draw_focus_rect(dc, &rect);
+ rtgui_dc_end_drawing(dc);
+ }
+ }
+
+ if ((index < box->items_count) && (index < box->page_items))
+ {
+ rt_uint16_t old_item;
+
+ old_item = box->current_item;
+
+ /* set selected item */
+ box->current_item = (box->current_item/box->page_items) * box->page_items + index;
+ if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ /* down event */
+ rtgui_listbox_update_current(box, old_item);
+ }
+ else
+ {
+ /* up event */
+ if (box->on_item != RT_NULL)
+ {
+ box->on_item(RTGUI_OBJECT(box), RT_NULL);
+ }
+ }
+ }
+ }
+
+ return RT_TRUE;
+ }
+
+ case RTGUI_EVENT_KBD:
+ {
+ struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+ if ((ekbd->type == RTGUI_KEYDOWN) && (box->items_count > 0))
+ {
+ rt_int16_t old_item;
+
+ if (box->current_item == -1)
+ {
+ /* set a initial item */
+ if ((box->items_count > 0) &&
+ (ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
+ {
+ box->current_item = 0;
+ rtgui_listbox_update_current(box, -1);
+ break;
+ }
+ else return RT_FALSE;
+ }
+ old_item = box->current_item;
+
+ switch (ekbd->key)
+ {
+ case RTGUIK_LEFT:
+ if (box->current_item - box->page_items >= 0)
+ box->current_item -= box->page_items;
+ rtgui_listbox_update_current(box, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_UP:
+ if (box->current_item > 0)
+ box->current_item --;
+ rtgui_listbox_update_current(box, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_RIGHT:
+ if (box->current_item + box->page_items < box->items_count - 1)
+ box->current_item += box->page_items;
+ rtgui_listbox_update_current(box, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_DOWN:
+ if (box->current_item < box->items_count - 1)
+ box->current_item ++;
+ rtgui_listbox_update_current(box, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_RETURN:
+ if (box->on_item != RT_NULL)
+ {
+ box->on_item(RTGUI_OBJECT(box), RT_NULL);
+ }
+ return RT_FALSE;
+
+ default:
+ break;
+ }
+ }
+ }
+ return RT_FALSE;
+ }
+
+ /* use box event handler */
+ return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
+}
+
+rtgui_listbox_t* rtgui_listbox_create(const struct rtgui_listbox_item* items, rt_uint16_t count, rtgui_rect_t *rect)
+{
+ struct rtgui_listbox* box = RT_NULL;
+
+ box = (struct rtgui_listbox*) rtgui_widget_create(RTGUI_LISTBOX_TYPE);
+ if (box != RT_NULL)
+ {
+ box->items = items;
+ box->items_count = count;
+
+ box->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
+ if (box->page_items == 0) box->page_items = 1;
+ rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
+ }
+
+ return box;
+}
+
+void rtgui_listbox_destroy(rtgui_listbox_t* box)
+{
+ /* destroy box */
+ rtgui_widget_destroy(RTGUI_WIDGET(box));
+}
+
+void rtgui_listbox_set_onitem(rtgui_listbox_t* box, rtgui_event_handler_ptr func)
+{
+ RT_ASSERT(box != RT_NULL);
+
+ box->on_item = func;
+}
+
+void rtgui_listbox_set_items(rtgui_listbox_t* box, struct rtgui_listbox_item* items, rt_uint16_t count)
+{
+ rtgui_rect_t rect;
+
+ box->items = items;
+ box->items_count = count;
+ box->current_item = -1;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);
+ box->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
+
+ rtgui_widget_update(RTGUI_WIDGET(box));
+}
+
+void rtgui_listbox_set_current_item(rtgui_listbox_t* box, int index)
+{
+ RT_ASSERT(box != RT_NULL);
+
+ if (index != box->current_item)
+ {
+ int old_item;
+
+ old_item = box->current_item;
+ box->current_item = index;
+
+ rtgui_listbox_update_current(box, old_item);
+ }
+}
+
diff --git a/components/rtgui/widgets/listctrl.c b/components/rtgui/widgets/listctrl.c
index 23e5c8696a..6fdc4028d6 100644
--- a/components/rtgui/widgets/listctrl.c
+++ b/components/rtgui/widgets/listctrl.c
@@ -1,426 +1,427 @@
-/*
- * File : listctrl.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-01-06 Bernard first version
- */
-
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/listctrl.h>
-
-static void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item);
-
-static void _rtgui_listctrl_constructor(struct rtgui_listctrl *ctrl)
-{
- /* set default widget rect and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(ctrl),rtgui_listctrl_event_handler);
-
- RTGUI_WIDGET(ctrl)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
- ctrl->current_item = -1;
- ctrl->items_count = 0;
- ctrl->page_items = 0;
- ctrl->on_item = 0;
- ctrl->on_item_draw = RT_NULL;
-
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(ctrl)) = white;
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(ctrl)) = RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(listctrl, "listctrl",
- RTGUI_WIDGET_TYPE,
- _rtgui_listctrl_constructor,
- RT_NULL,
- sizeof(struct rtgui_listctrl));
-
-static void _rtgui_listctrl_get_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
-{
- rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
- if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
- {
- rect->x2 = rect->x2 - 8;
- }
-}
-
-static void _rtgui_listctrl_get_scrollbar_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
-{
- rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
- if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
- {
- rect->x1 = rect->x2 - 8;
- }
- else
- {
- /* no scrollbar */
- rt_memset(rect, 0, sizeof(rtgui_rect_t));
- }
-}
-
-static void _rtgui_listctrl_scrollbar_ondraw(struct rtgui_listctrl* ctrl, struct rtgui_dc* dc)
-{
- rtgui_rect_t rect;
- rt_uint32_t height, y1;
-
- /* get scrollbar rect */
- _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- height = rtgui_rect_height(rect);
-
- height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
- y1 = (ctrl->current_item / ctrl->page_items) * height;
-
- rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
- rect.x1 -= 3;
- rtgui_theme_draw_selected(dc, &rect);
-}
-
-static void _rtgui_listctrl_scrollbar_onmouse(struct rtgui_listctrl* ctrl, struct rtgui_event_mouse* mouse)
-{
- rtgui_rect_t rect;
- rt_uint32_t height, y1;
- rt_uint16_t old_item;
-
- /* get scrollbar rect */
- _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
- height = rtgui_rect_height(rect);
- height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
- y1 = (ctrl->current_item / ctrl->page_items) * height;
-
- rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
- rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
-
- old_item = ctrl->current_item;
- if (mouse->y < rect.y1)
- {
- if (ctrl->current_item - ctrl->page_items >= 0)
- ctrl->current_item -= ctrl->page_items;
- rtgui_listctrl_update_current(ctrl, old_item);
- }
- else if (mouse->y > rect.y2)
- {
- if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
- ctrl->current_item += ctrl->page_items;
- else
- ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
- rtgui_listctrl_update_current(ctrl, old_item);
- }
-}
-
-static void _rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl)
-{
- struct rtgui_rect rect, item_rect;
- struct rtgui_dc* dc;
- rt_uint16_t page_index, index;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
- if (dc == RT_NULL) return;
-
- _rtgui_listctrl_get_rect(ctrl, &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- rect.x2 -= 1; rect.y2 -= 1;
-
- /* get item base rect */
- item_rect = rect;
- item_rect.x1 += 1; item_rect.x2 -= 1;
- item_rect.y1 += 2;
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* get current page */
- page_index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
- for (index = 0; index < ctrl->page_items; index ++)
- {
- if (page_index + index >= ctrl->items_count) break;
-
- if (page_index + index == ctrl->current_item)
- {
- rtgui_theme_draw_selected(dc, &item_rect);
- }
-
- if (ctrl->on_item_draw != RT_NULL)
- {
- ctrl->on_item_draw(ctrl, dc, &item_rect, page_index + index);
- }
-
- /* move to next item position */
- item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
- item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
- }
-
- /* draw scrollbar */
- _rtgui_listctrl_scrollbar_ondraw(ctrl, dc);
- rtgui_dc_end_drawing(dc);
-}
-
-void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item)
-{
- struct rtgui_dc* dc;
- rtgui_rect_t rect, item_rect;
-
- if (old_item/ctrl->page_items != ctrl->current_item/ctrl->page_items)
- {
- /* it's not a same page, update all */
- rtgui_widget_update(RTGUI_WIDGET(ctrl));
- return;
- }
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
- if (dc == RT_NULL) return;
-
- _rtgui_listctrl_get_rect(ctrl, &rect);
- rect.x2 -= 1; rect.y2 -= 1;
-
- item_rect = rect;
- /* get old item's rect */
- item_rect.x1 += 1; item_rect.x2 -= 1;
- item_rect.y1 += 2;
- item_rect.y1 += (old_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* draw old item */
- rtgui_dc_fill_rect(dc, &item_rect);
- if (ctrl->on_item_draw != RT_NULL)
- ctrl->on_item_draw(ctrl, dc, &item_rect, old_item);
-
- /* draw current item */
- item_rect = rect;
- /* get current item's rect */
- item_rect.x1 += 1; item_rect.x2 -= 1;
- item_rect.y1 += 2;
- item_rect.y1 += (ctrl->current_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
- item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
-
- /* draw current item */
- rtgui_theme_draw_selected(dc, &item_rect);
- if (ctrl->on_item_draw != RT_NULL)
- ctrl->on_item_draw(ctrl, dc, &item_rect, ctrl->current_item);
-
- rtgui_dc_end_drawing(dc);
-}
-
-rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_listctrl* ctrl = RT_NULL;
-
- ctrl = RTGUI_LISTCTRL(widget);
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- _rtgui_listctrl_ondraw(ctrl);
- return RT_FALSE;
-
- case RTGUI_EVENT_RESIZE:
- {
- struct rtgui_event_resize* resize;
-
- resize = (struct rtgui_event_resize*)event;
-
- /* recalculate page items */
- ctrl->page_items = resize->h / (2 + rtgui_theme_get_selected_height());
- }
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- {
- rtgui_rect_t rect;
- struct rtgui_event_mouse* emouse;
-
- emouse = (struct rtgui_event_mouse*)event;
-
- /* get scrollbar rect */
- _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
- rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
- if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
- {
- _rtgui_listctrl_scrollbar_onmouse(ctrl, emouse);
- return RT_TRUE;
- }
-
- /* calculate selected item */
-
- /* get physical extent information */
- _rtgui_listctrl_get_rect(ctrl, &rect);
- rtgui_widget_rect_to_device(widget, &rect);
-
- if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) &&
- (ctrl->items_count > 0))
- {
- rt_uint16_t index;
- index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
-
- /* set focus */
- rtgui_widget_focus(widget);
- {
- struct rtgui_rect rect;
- struct rtgui_dc* dc;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
- if (dc != RT_NULL)
- {
- /* get widget rect */
- rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
- /* update focus border */
- rect.x2 -= 1; rect.y2 -= 1;
- rtgui_dc_end_drawing(dc);
- }
- }
-
- if ((index < ctrl->page_items) &&
- (ctrl->current_item/ctrl->page_items)* ctrl->page_items + index < ctrl->items_count)
- {
- rt_uint16_t old_item;
-
- old_item = ctrl->current_item;
-
- /* set selected item */
- ctrl->current_item = (ctrl->current_item/ctrl->page_items) * ctrl->page_items + index;
- if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
- {
- /* down event */
- rtgui_listctrl_update_current(ctrl, old_item);
- }
- else
- {
- /* up event */
- if (ctrl->on_item != RT_NULL)
- {
- ctrl->on_item(RTGUI_WIDGET(ctrl), RT_NULL);
- }
- }
- }
- }
-
- return RT_TRUE;
- }
-
- case RTGUI_EVENT_KBD:
- {
- struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
- if ((ekbd->type == RTGUI_KEYDOWN) && (ctrl->items_count > 0))
- {
- rt_uint16_t old_item;
-
- old_item = ctrl->current_item;
- switch (ekbd->key)
- {
- case RTGUIK_LEFT:
- if (ctrl->current_item - ctrl->page_items >= 0)
- ctrl->current_item -= ctrl->page_items;
- rtgui_listctrl_update_current(ctrl, old_item);
- return RT_FALSE;
-
- case RTGUIK_UP:
- if (ctrl->current_item > 0)
- ctrl->current_item --;
- rtgui_listctrl_update_current(ctrl, old_item);
- return RT_FALSE;
-
- case RTGUIK_RIGHT:
- if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
- ctrl->current_item += ctrl->page_items;
- else
- {
- if ((((ctrl->current_item/ctrl->page_items) + 1) * ctrl->page_items) < ctrl->items_count - 1)
- ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
- }
- rtgui_listctrl_update_current(ctrl, old_item);
- return RT_FALSE;
-
- case RTGUIK_DOWN:
- if (ctrl->current_item < ctrl->items_count - 1)
- ctrl->current_item ++;
- rtgui_listctrl_update_current(ctrl, old_item);
- return RT_FALSE;
-
- case RTGUIK_RETURN:
- if (ctrl->on_item != RT_NULL)
- {
- ctrl->on_item(RTGUI_WIDGET(ctrl), RT_NULL);
- }
- return RT_FALSE;
-
- default:
- break;
- }
- }
- }
- return RT_FALSE;
- }
-
- /* use ctrl event handler */
- return rtgui_widget_event_handler(widget, event);
-}
-
-rtgui_listctrl_t* rtgui_listctrl_create(rt_uint32_t items, rt_uint16_t count, rtgui_rect_t *rect,
- rtgui_onitem_draw_t ondraw)
-{
- struct rtgui_listctrl* ctrl = RT_NULL;
-
- ctrl = (struct rtgui_listctrl*) rtgui_widget_create(RTGUI_LISTCTRL_TYPE);
- if (ctrl != RT_NULL)
- {
- ctrl->items = items;
- ctrl->items_count = count;
- ctrl->on_item_draw = ondraw;
-
- ctrl->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
- rtgui_widget_set_rect(RTGUI_WIDGET(ctrl), rect);
- }
-
- return ctrl;
-}
-
-void rtgui_listctrl_destroy(rtgui_listctrl_t* ctrl)
-{
- /* destroy ctrl */
- rtgui_widget_destroy(RTGUI_WIDGET(ctrl));
-}
-
-void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_onitem_func_t func)
-{
- RT_ASSERT(ctrl != RT_NULL);
-
- ctrl->on_item = func;
-}
-
-void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count)
-{
- rtgui_rect_t rect;
-
- ctrl->items = items;
- ctrl->items_count = count;
- ctrl->current_item = 0;
-
- rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
- ctrl->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
-
- rtgui_widget_update(RTGUI_WIDGET(ctrl));
-}
-
-rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect)
-{
- if (item < ctrl->items_count)
- {
- rt_uint16_t index;
-
- /* check whether this item in current page */
- index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
- if (index > item || index + ctrl->page_items <= item) return RT_FALSE;
-
- rtgui_widget_get_extent(RTGUI_WIDGET(ctrl), item_rect);
- item_rect->y1 -= 2;
- item_rect->y1 += (item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
- item_rect->y2 = item_rect->y1 + (2 + rtgui_theme_get_selected_height());
- return RT_TRUE;
- }
-
- return RT_FALSE;
-}
+/*
+ * File : listctrl.c
+ * This file is part of RTGUI in RT-Thread RTOS
+ * COPYRIGHT (C) 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-01-06 Bernard first version
+ */
+
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/listctrl.h>
+
+static void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item);
+
+static void _rtgui_listctrl_constructor(struct rtgui_listctrl *ctrl)
+{
+ /* set default widget rect and set event handler */
+ rtgui_object_set_event_handler(RTGUI_OBJECT(ctrl), rtgui_listctrl_event_handler);
+
+ RTGUI_WIDGET(ctrl)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ ctrl->current_item = -1;
+ ctrl->items_count = 0;
+ ctrl->page_items = 0;
+ ctrl->on_item = 0;
+ ctrl->on_item_draw = RT_NULL;
+
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(ctrl)) = white;
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(ctrl)) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(listctrl, "listctrl",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_listctrl_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_listctrl));
+
+static void _rtgui_listctrl_get_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
+{
+ rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
+ if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
+ {
+ rect->x2 = rect->x2 - 8;
+ }
+}
+
+static void _rtgui_listctrl_get_scrollbar_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect)
+{
+ rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect);
+ if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height())
+ {
+ rect->x1 = rect->x2 - 8;
+ }
+ else
+ {
+ /* no scrollbar */
+ rt_memset(rect, 0, sizeof(rtgui_rect_t));
+ }
+}
+
+static void _rtgui_listctrl_scrollbar_ondraw(struct rtgui_listctrl* ctrl, struct rtgui_dc* dc)
+{
+ rtgui_rect_t rect;
+ rt_uint32_t height, y1;
+
+ /* get scrollbar rect */
+ _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ height = rtgui_rect_height(rect);
+
+ height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
+ y1 = (ctrl->current_item / ctrl->page_items) * height;
+
+ rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
+ rect.x1 -= 3;
+ rtgui_theme_draw_selected(dc, &rect);
+}
+
+static void _rtgui_listctrl_scrollbar_onmouse(struct rtgui_listctrl* ctrl, struct rtgui_event_mouse* mouse)
+{
+ rtgui_rect_t rect;
+ rt_uint32_t height, y1;
+ rt_uint16_t old_item;
+
+ /* get scrollbar rect */
+ _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
+ height = rtgui_rect_height(rect);
+ height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items);
+ y1 = (ctrl->current_item / ctrl->page_items) * height;
+
+ rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height;
+ rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
+
+ old_item = ctrl->current_item;
+ if (mouse->y < rect.y1)
+ {
+ if (ctrl->current_item - ctrl->page_items >= 0)
+ ctrl->current_item -= ctrl->page_items;
+ rtgui_listctrl_update_current(ctrl, old_item);
+ }
+ else if (mouse->y > rect.y2)
+ {
+ if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
+ ctrl->current_item += ctrl->page_items;
+ else
+ ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
+ rtgui_listctrl_update_current(ctrl, old_item);
+ }
+}
+
+static void _rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl)
+{
+ struct rtgui_rect rect, item_rect;
+ struct rtgui_dc* dc;
+ rt_uint16_t page_index, index;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
+ if (dc == RT_NULL) return;
+
+ _rtgui_listctrl_get_rect(ctrl, &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ rect.x2 -= 1; rect.y2 -= 1;
+
+ /* get item base rect */
+ item_rect = rect;
+ item_rect.x1 += 1; item_rect.x2 -= 1;
+ item_rect.y1 += 2;
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* get current page */
+ page_index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
+ for (index = 0; index < ctrl->page_items; index ++)
+ {
+ if (page_index + index >= ctrl->items_count) break;
+
+ if (page_index + index == ctrl->current_item)
+ {
+ rtgui_theme_draw_selected(dc, &item_rect);
+ }
+
+ if (ctrl->on_item_draw != RT_NULL)
+ {
+ ctrl->on_item_draw(ctrl, dc, &item_rect, page_index + index);
+ }
+
+ /* move to next item position */
+ item_rect.y1 += (rtgui_theme_get_selected_height() + 2);
+ item_rect.y2 += (rtgui_theme_get_selected_height() + 2);
+ }
+
+ /* draw scrollbar */
+ _rtgui_listctrl_scrollbar_ondraw(ctrl, dc);
+ rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item)
+{
+ struct rtgui_dc* dc;
+ rtgui_rect_t rect, item_rect;
+
+ if (old_item/ctrl->page_items != ctrl->current_item/ctrl->page_items)
+ {
+ /* it's not a same page, update all */
+ rtgui_widget_update(RTGUI_WIDGET(ctrl));
+ return;
+ }
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
+ if (dc == RT_NULL) return;
+
+ _rtgui_listctrl_get_rect(ctrl, &rect);
+ rect.x2 -= 1; rect.y2 -= 1;
+
+ item_rect = rect;
+ /* get old item's rect */
+ item_rect.x1 += 1; item_rect.x2 -= 1;
+ item_rect.y1 += 2;
+ item_rect.y1 += (old_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* draw old item */
+ rtgui_dc_fill_rect(dc, &item_rect);
+ if (ctrl->on_item_draw != RT_NULL)
+ ctrl->on_item_draw(ctrl, dc, &item_rect, old_item);
+
+ /* draw current item */
+ item_rect = rect;
+ /* get current item's rect */
+ item_rect.x1 += 1; item_rect.x2 -= 1;
+ item_rect.y1 += 2;
+ item_rect.y1 += (ctrl->current_item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
+ item_rect.y2 = item_rect.y1 + (2 + rtgui_theme_get_selected_height());
+
+ /* draw current item */
+ rtgui_theme_draw_selected(dc, &item_rect);
+ if (ctrl->on_item_draw != RT_NULL)
+ ctrl->on_item_draw(ctrl, dc, &item_rect, ctrl->current_item);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_listctrl* ctrl;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ ctrl = RTGUI_LISTCTRL(object);
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ _rtgui_listctrl_ondraw(ctrl);
+ return RT_FALSE;
+
+ case RTGUI_EVENT_RESIZE:
+ {
+ struct rtgui_event_resize* resize;
+
+ resize = (struct rtgui_event_resize*)event;
+
+ /* recalculate page items */
+ ctrl->page_items = resize->h / (2 + rtgui_theme_get_selected_height());
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_rect_t rect;
+ struct rtgui_event_mouse* emouse;
+
+ emouse = (struct rtgui_event_mouse*)event;
+
+ /* get scrollbar rect */
+ _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect);
+ rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect);
+ if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+ {
+ _rtgui_listctrl_scrollbar_onmouse(ctrl, emouse);
+ return RT_TRUE;
+ }
+
+ /* calculate selected item */
+
+ /* get physical extent information */
+ _rtgui_listctrl_get_rect(ctrl, &rect);
+ rtgui_widget_rect_to_device(widget, &rect);
+
+ if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) &&
+ (ctrl->items_count > 0))
+ {
+ rt_uint16_t index;
+ index = (emouse->y - rect.y1) / (2 + rtgui_theme_get_selected_height());
+
+ /* set focus */
+ rtgui_widget_focus(widget);
+ {
+ struct rtgui_rect rect;
+ struct rtgui_dc* dc;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl));
+ if (dc != RT_NULL)
+ {
+ /* get widget rect */
+ rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
+ /* update focus border */
+ rect.x2 -= 1; rect.y2 -= 1;
+ rtgui_dc_end_drawing(dc);
+ }
+ }
+
+ if ((index < ctrl->page_items) &&
+ (ctrl->current_item/ctrl->page_items)* ctrl->page_items + index < ctrl->items_count)
+ {
+ rt_uint16_t old_item;
+
+ old_item = ctrl->current_item;
+
+ /* set selected item */
+ ctrl->current_item = (ctrl->current_item/ctrl->page_items) * ctrl->page_items + index;
+ if (emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ /* down event */
+ rtgui_listctrl_update_current(ctrl, old_item);
+ }
+ else
+ {
+ /* up event */
+ if (ctrl->on_item != RT_NULL)
+ {
+ ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL);
+ }
+ }
+ }
+ }
+
+ return RT_TRUE;
+ }
+
+ case RTGUI_EVENT_KBD:
+ {
+ struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+ if ((ekbd->type == RTGUI_KEYDOWN) && (ctrl->items_count > 0))
+ {
+ rt_uint16_t old_item;
+
+ old_item = ctrl->current_item;
+ switch (ekbd->key)
+ {
+ case RTGUIK_LEFT:
+ if (ctrl->current_item - ctrl->page_items >= 0)
+ ctrl->current_item -= ctrl->page_items;
+ rtgui_listctrl_update_current(ctrl, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_UP:
+ if (ctrl->current_item > 0)
+ ctrl->current_item --;
+ rtgui_listctrl_update_current(ctrl, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_RIGHT:
+ if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
+ ctrl->current_item += ctrl->page_items;
+ else
+ {
+ if ((((ctrl->current_item/ctrl->page_items) + 1) * ctrl->page_items) < ctrl->items_count - 1)
+ ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
+ }
+ rtgui_listctrl_update_current(ctrl, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_DOWN:
+ if (ctrl->current_item < ctrl->items_count - 1)
+ ctrl->current_item ++;
+ rtgui_listctrl_update_current(ctrl, old_item);
+ return RT_FALSE;
+
+ case RTGUIK_RETURN:
+ if (ctrl->on_item != RT_NULL)
+ {
+ ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL);
+ }
+ return RT_FALSE;
+
+ default:
+ break;
+ }
+ }
+ }
+ return RT_FALSE;
+ }
+
+ /* use ctrl event handler */
+ return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event);
+}
+
+rtgui_listctrl_t* rtgui_listctrl_create(rt_uint32_t items, rt_uint16_t count, rtgui_rect_t *rect,
+ rtgui_onitem_draw_t ondraw)
+{
+ struct rtgui_listctrl* ctrl = RT_NULL;
+
+ ctrl = (struct rtgui_listctrl*) rtgui_widget_create(RTGUI_LISTCTRL_TYPE);
+ if (ctrl != RT_NULL)
+ {
+ ctrl->items = items;
+ ctrl->items_count = count;
+ ctrl->on_item_draw = ondraw;
+
+ ctrl->page_items = rtgui_rect_height(*rect) / (2 + rtgui_theme_get_selected_height());
+ rtgui_widget_set_rect(RTGUI_WIDGET(ctrl), rect);
+ }
+
+ return ctrl;
+}
+
+void rtgui_listctrl_destroy(rtgui_listctrl_t* ctrl)
+{
+ /* destroy ctrl */
+ rtgui_widget_destroy(RTGUI_WIDGET(ctrl));
+}
+
+void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_event_handler_ptr func)
+{
+ RT_ASSERT(ctrl != RT_NULL);
+
+ ctrl->on_item = func;
+}
+
+void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count)
+{
+ rtgui_rect_t rect;
+
+ ctrl->items = items;
+ ctrl->items_count = count;
+ ctrl->current_item = 0;
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect);
+ ctrl->page_items = rtgui_rect_height(rect) / (2 + rtgui_theme_get_selected_height());
+
+ rtgui_widget_update(RTGUI_WIDGET(ctrl));
+}
+
+rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect)
+{
+ if (item < ctrl->items_count)
+ {
+ rt_uint16_t index;
+
+ /* check whether this item in current page */
+ index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items;
+ if (index > item || index + ctrl->page_items <= item) return RT_FALSE;
+
+ rtgui_widget_get_extent(RTGUI_WIDGET(ctrl), item_rect);
+ item_rect->y1 -= 2;
+ item_rect->y1 += (item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height());
+ item_rect->y2 = item_rect->y1 + (2 + rtgui_theme_get_selected_height());
+ return RT_TRUE;
+ }
+
+ return RT_FALSE;
+}
diff --git a/components/rtgui/widgets/menu.c b/components/rtgui/widgets/menu.c
index 7d8b02dd3b..c56041db83 100644
--- a/components/rtgui/widgets/menu.c
+++ b/components/rtgui/widgets/menu.c
@@ -1,275 +1,287 @@
-#include <rtgui/dc.h>
-#include <rtgui/widgets/menu.h>
-#include <rtgui/rtgui_theme.h>
-
-static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t* event);
-const static rt_uint8_t right_arrow[] = {0x80, 0xc0, 0xe0, 0xf0, 0xe0, 0xc0, 0x80};
-
-static void _rtgui_menu_constructor(rtgui_menu_t *menu)
-{
- /* set window style */
- RTGUI_WIN(menu)->style = RTGUI_WIN_STYLE_NO_TITLE;
-
- /* set deactivate handler */
- rtgui_win_set_ondeactivate(RTGUI_WIN(menu), rtgui_menu_on_deactivate);
-
- /* set proper of control */
- menu->parent_menu = RT_NULL;
- menu->sub_menu = RT_NULL;
-
- menu->items = RT_NULL;
- menu->items_count = 0;
- menu->items_list = RT_NULL;
-
- menu->on_menupop = RT_NULL;
- menu->on_menuhide = RT_NULL;
-}
-
-static void _rtgui_menu_destructor(rtgui_menu_t* menu)
-{
- if (menu->sub_menu != RT_NULL)
- {
- rtgui_menu_destroy(menu->sub_menu);
- menu->sub_menu = RT_NULL;
- }
-
- rtgui_listctrl_destroy(menu->items_list);
- menu->items_list = RT_NULL;
-}
-
-static void _rtgui_menu_onitem(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_menu* menu;
-
- /* get menu */
- menu = RTGUI_MENU(rtgui_widget_get_toplevel(widget));
- if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
- {
- const rtgui_menu_item_t* items;
- rt_uint16_t count;
- rtgui_rect_t item_rect;
-
- items = (rtgui_menu_item_t*)menu->items[menu->items_list->current_item].submenu;
- count = menu->items[menu->items_list->current_item].submenu_count;
- if (menu->sub_menu != RT_NULL)
- {
- if (menu->sub_menu->items == items)
- {
- if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu)))
- {
- /* hide this sub menu */
- rtgui_win_hiden(RTGUI_WIN(menu->sub_menu));
- return;
- }
-
- /* show this sub menu */
- rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
- rtgui_menu_pop(menu->sub_menu, item_rect.x2, item_rect.y1);
- return;
- }
-
- /* delete sub menu */
- rtgui_menu_destroy(menu->sub_menu);
- menu->sub_menu = RT_NULL;
- }
-
- /* create sub menu */
- menu->sub_menu = rtgui_menu_create("submenu", menu, items, count);
-
- rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
- rtgui_menu_pop(menu->sub_menu, item_rect.x2 + 5, item_rect.y1);
- }
- else /* other menu item */
- {
- /* invoke action */
- if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL)
- menu->items[menu->items_list->current_item].on_menuaction(RTGUI_WIDGET(menu), RT_NULL);
-
- /* hide sub-menu */
- if (menu->sub_menu != RT_NULL)
- {
- rtgui_menu_hiden(menu->sub_menu);
- }
- rtgui_menu_hiden(menu);
- }
-}
-
-static void _rtgui_menu_item_ondraw(struct rtgui_listctrl *list, struct rtgui_dc* dc, rtgui_rect_t* rect, rt_uint16_t index)
-{
- rtgui_rect_t item_rect;
- struct rtgui_menu_item* item;
-
- item_rect = *rect;
- item_rect.x1 += 5;
-
- /* re-fill item */
- if (list->current_item == index)
- {
- rtgui_color_t bc;
-
- bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list));
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = blue;
- rtgui_dc_fill_rect(dc, rect);
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = bc;
- }
-
- /* get menu item */
- item = (rtgui_menu_item_t*)list->items;
- item = &item[index];
-
- if (item->type == RTGUI_ITEM_SUBMENU)
- {
- rtgui_rect_t r = {0, 0, 8, 8};
- rtgui_dc_draw_text(dc, item->label, &item_rect);
- item_rect.x1 = item_rect.x2 - 16; item_rect.x2 -= 8;
- rtgui_rect_moveto_align(&item_rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
- rtgui_dc_draw_byte(dc, r.x1, r.y1, 8, right_arrow);
- }
- else if (item->type == RTGUI_ITEM_SEPARATOR)
- {
- rtgui_dc_draw_horizontal_line(dc, item_rect.x1, item_rect.x2, (item_rect.y2 + item_rect.y1)/2);
- }
- else if (item->type == RTGUI_ITEM_CHECK)
- {
- /* not support right now */
- }
- else
- {
- /* normal menu item */
- rtgui_dc_draw_text(dc, item->label, &item_rect);
- if (item->image != RT_NULL)
- rtgui_image_blit(item->image, dc, &item_rect);
- }
-}
-
-DEFINE_CLASS_TYPE(menu, "menu",
- RTGUI_WIN_TYPE,
- _rtgui_menu_constructor,
- _rtgui_menu_destructor,
- sizeof(struct rtgui_menu));
-
-static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t* event)
-{
- rtgui_menu_t* menu = (rtgui_menu_t*) widget;
-
- if (menu->parent_menu != RT_NULL)
- {
- /* whether click on parent menu */
- if (rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_TRUE &&
- menu->parent_menu->items[menu->parent_menu->items_list->current_item].submenu == (struct rtgui_menu_item_t *)menu->items)
- return RT_TRUE;
- }
-
- /* submenu is activate */
- if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
- {
- /* if sub menu activated, not hide menu */
- if (menu->sub_menu != RT_NULL &&
- rtgui_win_is_activated(RTGUI_WIN(menu->sub_menu)) == RT_TRUE)
- return RT_TRUE;
- }
-
- rtgui_win_hiden(RTGUI_WIN(menu));
- if (menu->on_menuhide != RT_NULL)
- {
- menu->on_menuhide(RTGUI_WIDGET(menu), RT_NULL);
- }
-
- /* un-select item */
- menu->items_list->current_item = -1;
-
- /* if it's a submenu, try to hide parent menu */
- if (menu->parent_menu != RT_NULL &&
- rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_FALSE)
- {
- rtgui_menu_on_deactivate(RTGUI_WIDGET(menu->parent_menu), event);
- }
-
- return RT_TRUE;
-}
-
-struct rtgui_menu* rtgui_menu_create(const char* title, struct rtgui_menu* parent_menu,
- const struct rtgui_menu_item* items, rt_uint16_t count)
-{
- rtgui_rect_t rect = {0, 0, 100, 100};
- struct rtgui_menu* menu;
-
- menu = (struct rtgui_menu*) rtgui_widget_create ( RTGUI_MENU_TYPE );
- if (menu != RT_NULL)
- {
- rtgui_win_set_title(RTGUI_WIN(menu), title);
- menu->parent_menu = parent_menu;
- menu->items = items;
- menu->items_count = count;
-
- rtgui_widget_set_rect(RTGUI_WIDGET(menu), &rect);
- rtgui_rect_inflate(&rect, -1);
- /* create menu item list */
- menu->items_list = rtgui_listctrl_create((rt_uint32_t)items, count, &rect, _rtgui_menu_item_ondraw);
- RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(menu->items_list)) = rtgui_theme_default_bc();
- rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(menu->items_list));
- rtgui_listctrl_set_onitem(menu->items_list, _rtgui_menu_onitem);
- }
-
- return menu;
-}
-
-void rtgui_menu_destroy(struct rtgui_menu* menu)
-{
- rtgui_widget_destroy (RTGUI_WIDGET(menu));
-}
-
-void rtgui_menu_set_onmenupop(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
-{
- if (menu == RT_NULL) return;
-
- menu->on_menupop = handler;
-}
-
-void rtgui_menu_set_onmenuhide(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
-{
- if (menu == RT_NULL) return;
-
- menu->on_menuhide = handler;
-}
-
-void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y)
-{
- rtgui_rect_t rect;
- struct rtgui_event_resize eresize;
-
- if (menu == RT_NULL) return;
-
- /* set window extent */
- rect.x1 = 0; rect.y1 = 0;
- rect.x2 = 100; rect.y2 = menu->items_count * (rtgui_theme_get_selected_height() + 2) + 5;
- rtgui_rect_moveto(&rect, x, y);
- rtgui_win_set_rect(RTGUI_WIN(menu), &rect);
- rtgui_rect_inflate(&rect, -1);
- rtgui_widget_set_rect(RTGUI_WIDGET(menu->items_list), &rect);
-
- eresize.parent.type = RTGUI_EVENT_RESIZE;
- eresize.x = rect.x1; eresize.y = rect.y1;
- eresize.h = rect.y2 - rect.y1; eresize.w = rect.x2 - rect.x1;
- rtgui_listctrl_event_handler(RTGUI_WIDGET(menu->items_list), &(eresize.parent));
-
- /* on menu pop handler */
- if (menu->on_menupop != RT_NULL)
- {
- menu->on_menupop(RTGUI_WIDGET(menu), RT_NULL);
- }
-
- /* show menu window */
- rtgui_win_show(RTGUI_WIN(menu), RT_FALSE);
-}
-
-void rtgui_menu_hiden(struct rtgui_menu* menu)
-{
- rtgui_win_hiden(RTGUI_WIN(menu));
- /* un-select item */
- menu->items_list->current_item = -1;
-
- if (menu->parent_menu != RT_NULL)
- rtgui_menu_hiden(menu->parent_menu);
-}
-
+#include <rtgui/dc.h>
+#include <rtgui/widgets/menu.h>
+#include <rtgui/rtgui_theme.h>
+
+static rt_bool_t rtgui_menu_on_deactivate(struct rtgui_object* object, rtgui_event_t* event);
+const static rt_uint8_t right_arrow[] = {0x80, 0xc0, 0xe0, 0xf0, 0xe0, 0xc0, 0x80};
+
+static void _rtgui_menu_constructor(rtgui_menu_t *menu)
+{
+ /* set window style */
+ RTGUI_WIN(menu)->style = RTGUI_WIN_STYLE_NO_TITLE;
+
+ /* set deactivate handler */
+ rtgui_win_set_ondeactivate(RTGUI_WIN(menu), rtgui_menu_on_deactivate);
+
+ /* set proper of control */
+ menu->parent_menu = RT_NULL;
+ menu->sub_menu = RT_NULL;
+
+ menu->items = RT_NULL;
+ menu->items_count = 0;
+ menu->items_list = RT_NULL;
+
+ menu->on_menupop = RT_NULL;
+ menu->on_menuhide = RT_NULL;
+}
+
+static void _rtgui_menu_destructor(rtgui_menu_t* menu)
+{
+ if (menu->sub_menu != RT_NULL)
+ {
+ rtgui_menu_destroy(menu->sub_menu);
+ menu->sub_menu = RT_NULL;
+ }
+
+ rtgui_listctrl_destroy(menu->items_list);
+ menu->items_list = RT_NULL;
+}
+
+static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_menu* menu;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ /* get menu */
+ menu = RTGUI_MENU(rtgui_widget_get_toplevel(widget));
+ if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
+ {
+ const rtgui_menu_item_t* items;
+ rt_uint16_t count;
+ rtgui_rect_t item_rect;
+
+ items = (rtgui_menu_item_t*)menu->items[menu->items_list->current_item].submenu;
+ count = menu->items[menu->items_list->current_item].submenu_count;
+ if (menu->sub_menu != RT_NULL)
+ {
+ if (menu->sub_menu->items == items)
+ {
+ if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu)))
+ {
+ /* hide this sub menu */
+ rtgui_win_hiden(RTGUI_WIN(menu->sub_menu));
+ return RT_FALSE;
+ }
+
+ /* show this sub menu */
+ rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
+ rtgui_menu_pop(menu->sub_menu, item_rect.x2, item_rect.y1);
+ return RT_FALSE;
+ }
+
+ /* delete sub menu */
+ rtgui_menu_destroy(menu->sub_menu);
+ menu->sub_menu = RT_NULL;
+ }
+
+ /* create sub menu */
+ menu->sub_menu = rtgui_menu_create("submenu", menu, items, count);
+
+ rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect);
+ rtgui_menu_pop(menu->sub_menu, item_rect.x2 + 5, item_rect.y1);
+ }
+ else /* other menu item */
+ {
+ /* invoke action */
+ if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL)
+ menu->items[menu->items_list->current_item].on_menuaction(RTGUI_WIDGET(menu), RT_NULL);
+
+ /* hide sub-menu */
+ if (menu->sub_menu != RT_NULL)
+ {
+ rtgui_menu_hiden(menu->sub_menu);
+ }
+ rtgui_menu_hiden(menu);
+ }
+ return RT_FALSE;
+}
+
+static void _rtgui_menu_item_ondraw(struct rtgui_listctrl *list,
+ struct rtgui_dc* dc,
+ rtgui_rect_t* rect,
+ rt_uint16_t index)
+{
+ rtgui_rect_t item_rect;
+ struct rtgui_menu_item* item;
+
+ item_rect = *rect;
+ item_rect.x1 += 5;
+
+ /* re-fill item */
+ if (list->current_item == index)
+ {
+ rtgui_color_t bc;
+
+ bc = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list));
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = blue;
+ rtgui_dc_fill_rect(dc, rect);
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = bc;
+ }
+
+ /* get menu item */
+ item = (rtgui_menu_item_t*)list->items;
+ item = &item[index];
+
+ if (item->type == RTGUI_ITEM_SUBMENU)
+ {
+ rtgui_rect_t r = {0, 0, 8, 8};
+ rtgui_dc_draw_text(dc, item->label, &item_rect);
+ item_rect.x1 = item_rect.x2 - 16; item_rect.x2 -= 8;
+ rtgui_rect_moveto_align(&item_rect, &r, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
+ rtgui_dc_draw_byte(dc, r.x1, r.y1, 8, right_arrow);
+ }
+ else if (item->type == RTGUI_ITEM_SEPARATOR)
+ {
+ rtgui_dc_draw_horizontal_line(dc, item_rect.x1, item_rect.x2, (item_rect.y2 + item_rect.y1)/2);
+ }
+ else if (item->type == RTGUI_ITEM_CHECK)
+ {
+ /* not support right now */
+ }
+ else
+ {
+ /* normal menu item */
+ rtgui_dc_draw_text(dc, item->label, &item_rect);
+ if (item->image != RT_NULL)
+ rtgui_image_blit(item->image, dc, &item_rect);
+ }
+}
+
+DEFINE_CLASS_TYPE(menu, "menu",
+ RTGUI_WIN_TYPE,
+ _rtgui_menu_constructor,
+ _rtgui_menu_destructor,
+ sizeof(struct rtgui_menu));
+
+static rt_bool_t rtgui_menu_on_deactivate(struct rtgui_object *object, rtgui_event_t* event)
+{
+ rtgui_menu_t* menu;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ menu = RTGUI_MENU(object);
+ if (menu->parent_menu != RT_NULL)
+ {
+ /* whether click on parent menu */
+ if (rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_TRUE &&
+ menu->parent_menu->items[menu->parent_menu->items_list->current_item].submenu
+ == (struct rtgui_menu_item_t *)menu->items)
+ return RT_TRUE;
+ }
+
+ /* submenu is activate */
+ if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
+ {
+ /* if sub menu activated, not hide menu. But we cannot use the
+ * activated flag as criteria since the old window is deactivated
+ * before the new window got activated. But the window will be shown in
+ * this context, so use 'is not hide'. */
+ if (menu->sub_menu != RT_NULL &&
+ !RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu)))
+ return RT_TRUE;
+ }
+
+ rtgui_win_hiden(RTGUI_WIN(menu));
+ if (menu->on_menuhide != RT_NULL)
+ {
+ menu->on_menuhide(RTGUI_OBJECT(menu), RT_NULL);
+ }
+
+ /* un-select item */
+ menu->items_list->current_item = -1;
+
+ /* if it's a submenu, try to hide parent menu */
+ if (menu->parent_menu != RT_NULL &&
+ rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_FALSE)
+ {
+ rtgui_menu_on_deactivate(RTGUI_OBJECT(menu->parent_menu), event);
+ }
+
+ return RT_TRUE;
+}
+
+struct rtgui_menu* rtgui_menu_create(const char* title, struct rtgui_menu* parent_menu,
+ const struct rtgui_menu_item* items, rt_uint16_t count)
+{
+ rtgui_rect_t rect = {0, 0, 100, 100};
+ struct rtgui_menu* menu;
+
+ menu = (struct rtgui_menu*) rtgui_widget_create ( RTGUI_MENU_TYPE );
+ if (menu != RT_NULL)
+ {
+ rtgui_win_set_title(RTGUI_WIN(menu), title);
+ menu->parent_menu = parent_menu;
+ menu->items = items;
+ menu->items_count = count;
+
+ rtgui_widget_set_rect(RTGUI_WIDGET(menu), &rect);
+ rtgui_rect_inflate(&rect, -1);
+ /* create menu item list */
+ menu->items_list = rtgui_listctrl_create((rt_uint32_t)items, count, &rect, _rtgui_menu_item_ondraw);
+ RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(menu->items_list)) = rtgui_theme_default_bc();
+ rtgui_container_add_child(RTGUI_CONTAINER(menu), RTGUI_WIDGET(menu->items_list));
+ rtgui_listctrl_set_onitem(menu->items_list, _rtgui_menu_onitem);
+ }
+
+ return menu;
+}
+
+void rtgui_menu_destroy(struct rtgui_menu* menu)
+{
+ rtgui_widget_destroy (RTGUI_WIDGET(menu));
+}
+
+void rtgui_menu_set_onmenupop(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
+{
+ if (menu == RT_NULL) return;
+
+ menu->on_menupop = handler;
+}
+
+void rtgui_menu_set_onmenuhide(struct rtgui_menu* menu, rtgui_event_handler_ptr handler)
+{
+ if (menu == RT_NULL) return;
+
+ menu->on_menuhide = handler;
+}
+
+void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y)
+{
+ rtgui_rect_t rect;
+ struct rtgui_event_resize eresize;
+
+ if (menu == RT_NULL)
+ return;
+
+ /* set window extent */
+ rect.x1 = 0; rect.y1 = 0;
+ rect.x2 = 100; rect.y2 = menu->items_count * (rtgui_theme_get_selected_height() + 2) + 5;
+ rtgui_rect_moveto(&rect, x, y);
+ rtgui_win_set_rect(RTGUI_WIN(menu), &rect);
+ rtgui_rect_inflate(&rect, -1);
+ rtgui_widget_set_rect(RTGUI_WIDGET(menu->items_list), &rect);
+
+ eresize.parent.type = RTGUI_EVENT_RESIZE;
+ eresize.x = rect.x1; eresize.y = rect.y1;
+ eresize.h = rect.y2 - rect.y1; eresize.w = rect.x2 - rect.x1;
+ rtgui_listctrl_event_handler(RTGUI_OBJECT(menu->items_list), &(eresize.parent));
+
+ /* on menu pop handler */
+ if (menu->on_menupop != RT_NULL)
+ {
+ menu->on_menupop(RTGUI_OBJECT(menu), RT_NULL);
+ }
+
+ /* show menu window */
+ rtgui_win_show(RTGUI_WIN(menu), RT_FALSE);
+}
+
+void rtgui_menu_hiden(struct rtgui_menu* menu)
+{
+ rtgui_win_hiden(RTGUI_WIN(menu));
+ /* un-select item */
+ menu->items_list->current_item = -1;
+
+ if (menu->parent_menu != RT_NULL)
+ rtgui_menu_hiden(menu->parent_menu);
+}
+
diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c
index 667baa9ec2..c928cd268d 100644
--- a/components/rtgui/widgets/notebook.c
+++ b/components/rtgui/widgets/notebook.c
@@ -1,330 +1,356 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/notebook.h>
-
-#define RTGUI_NOTEBOOK_TAB_WIDTH 80
-
-static void _rtgui_notebook_get_bar_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect);
-static void _rtgui_notebook_get_page_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect);
-
-static void _rtgui_notebook_constructor(rtgui_notebook_t *notebook)
-{
- notebook->flag = 0;
- notebook->childs = RT_NULL;
- notebook->count = 0;
- notebook->current = RTGUI_NOT_FOUND;
-
- RTGUI_WIDGET(notebook)->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
- rtgui_widget_set_event_handler(RTGUI_WIDGET(notebook), rtgui_notebook_event_handler);
-}
-
-static void _rtgui_notebook_destructor(rtgui_notebook_t *notebook)
-{
- int index;
-
- if (notebook->childs != RT_NULL)
- {
- for (index = 0; index < notebook->count; index ++)
- {
- rtgui_widget_destroy(notebook->childs[index].widget);
- rt_free(notebook->childs[index].title);
- }
-
- rtgui_free(notebook->childs);
- }
-}
-
-/* Draw tab bars of @param notebook. @param dc should be initialized and
- * finished outside this function. Don't pass @param notebook or @param dc as
- * RT_NULL, it should be checked outside.
- */
-static void _rtgui_notebook_draw_bar(struct rtgui_notebook *notebook,
- struct rtgui_dc *dc)
-{
- struct rtgui_rect rect;
- int index;
-
- RT_ASSERT((notebook != RT_NULL) && (dc != RT_NULL));
-
- _rtgui_notebook_get_bar_rect(notebook, &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- rect.x2 = rect.x1 + RTGUI_NOTEBOOK_TAB_WIDTH;
- /* draw tab bar */
- for (index = 0; index < notebook->count; index++)
- {
- if (notebook->current == index)
- rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
- else
- rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX);
-
- rtgui_dc_draw_text(dc, notebook->childs[index].title, &rect);
- rect.x1 += RTGUI_NOTEBOOK_TAB_WIDTH;
- rect.x2 += RTGUI_NOTEBOOK_TAB_WIDTH;
- }
-
-}
-
-static void _rtgui_notebook_ondraw(rtgui_notebook_t *notebook)
-{
- struct rtgui_dc* dc;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
- if (dc == RT_NULL) return;
-
- if (notebook->count == 0)
- {
- rtgui_rect_t rect;
- rtgui_widget_get_rect(RTGUI_WIDGET(notebook), &rect);
- rtgui_dc_fill_rect(dc, &rect);
- }
- else
- {
- if (notebook->current == RTGUI_NOT_FOUND)
- notebook->current = 0;
-
- _rtgui_notebook_draw_bar(notebook, dc);
-
- /* draw current tab */
- rtgui_widget_update(notebook->childs[notebook->current].widget);
- }
- rtgui_dc_end_drawing(dc);
-}
-
-static void _rtgui_notebook_onmouse(rtgui_notebook_t *notebook, struct rtgui_event_mouse* emouse)
-{
- rtgui_rect_t rect;
-
- /* handle notebook bar */
- _rtgui_notebook_get_bar_rect(notebook, &rect);
- rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
- if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
- {
- int index;
- struct rtgui_dc* dc;
-
- index = (emouse->x - rect.x1) / RTGUI_NOTEBOOK_TAB_WIDTH;
- if (index < notebook->count && index != notebook->current)
- {
- /* update tab bar */
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
- if (dc == RT_NULL) return;
-
- rtgui_notebook_set_current_by_index(notebook, index);
-
- _rtgui_notebook_draw_bar(notebook, dc);
-
- rtgui_dc_end_drawing(dc);
- }
- }
- else
- {
- /* handle on page */
- if (notebook->childs[notebook->current].widget->event_handler != RT_NULL)
- notebook->childs[notebook->current].widget->event_handler(
- notebook->childs[notebook->current].widget,
- &(emouse->parent));
- }
-}
-
-static void _rtgui_notebook_get_page_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect)
-{
- RT_ASSERT(notebook != RT_NULL);
- RT_ASSERT(rect != RT_NULL);
-
- rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
-
- if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return;
- else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
- rect->y1 = rect->y1 + 25;
- else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
- rect->y2 = rect->y2 - 25;
-}
-
-static void _rtgui_notebook_get_bar_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect)
-{
- RT_ASSERT(notebook != RT_NULL);
- RT_ASSERT(rect != RT_NULL);
-
- rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
- if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return;
- else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
- rect->y2 = rect->y1 + 25;
- else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
- rect->y1 = rect->y2 - 25;
-}
-
-DEFINE_CLASS_TYPE(notebook, "notebook",
- RTGUI_CONTAINER_TYPE,
- _rtgui_notebook_constructor,
- _rtgui_notebook_destructor,
- sizeof(struct rtgui_notebook));
-
-rtgui_notebook_tab_t *tabs;
-struct rtgui_notebook *_notebook;
-rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style)
-{
- struct rtgui_notebook* notebook;
-
- notebook = (struct rtgui_notebook*) rtgui_widget_create (RTGUI_NOTEBOOK_TYPE);
- if (notebook != RT_NULL)
- {
- notebook->flag = style;
- rtgui_widget_set_rect(RTGUI_WIDGET(notebook), rect);
- }
-
- _notebook = notebook;
- return notebook;
-}
-
-void rtgui_notebook_destroy(rtgui_notebook_t* notebook)
-{
- rtgui_widget_destroy(RTGUI_WIDGET(notebook));
-}
-
-void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_widget_t* child)
-{
- rtgui_rect_t rect;
- RT_ASSERT(notebook != RT_NULL);
-
- notebook->count += 1;
- notebook->childs = (struct rtgui_notebook_tab*) rtgui_realloc(notebook->childs,
- sizeof(struct rtgui_notebook_tab) * notebook->count);
-
- notebook->childs[notebook->count - 1].title = rt_strdup(label);
- notebook->childs[notebook->count - 1].widget = child;
-
- tabs = notebook->childs;
-
- /* set parent */
- rtgui_widget_set_parent(child, RTGUI_WIDGET(notebook));
-
- _rtgui_notebook_get_page_rect(notebook, &rect);
- rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
- rtgui_widget_set_rect(child, &rect);
-}
-
-void rtgui_notebook_remove(rtgui_notebook_t* notebook, rt_uint16_t index)
-{
- struct rtgui_notebook_tab tab;
- RT_ASSERT(notebook != RT_NULL);
-
- if (index < notebook->count)
- {
- if (notebook->count == 1)
- {
- tab = notebook->childs[0];
- rtgui_free(notebook->childs);
- notebook->childs = RT_NULL;
- notebook->count = 0;
- }
- else
- {
- tab = notebook->childs[index];
- for (;index < notebook->count - 1; index ++)
- {
- notebook->childs[index] = notebook->childs[index + 1];
- }
-
- notebook->count -= 1;
- notebook->childs = (struct rtgui_notebook_tab*) rtgui_realloc(notebook->childs,
- sizeof(struct rtgui_notebook_tab) * notebook->count);
- }
-
- rtgui_widget_destroy(tab.widget);
- rtgui_free(tab.title);
-
- if (notebook->current == index)
- {
- /* update tab */
- if (notebook->current > notebook->count - 1)
- notebook->current = notebook->count - 1;
- rtgui_widget_update(RTGUI_WIDGET(notebook));
- }
- }
-}
-
-int rtgui_notebook_get_count(rtgui_notebook_t* notebook)
-{
- return notebook->count;
-}
-
-rtgui_widget_t* rtgui_notebook_get_current(rtgui_notebook_t* notebook)
-{
- RT_ASSERT(notebook != RT_NULL);
- if (notebook->current != RTGUI_NOT_FOUND)
- return notebook->childs[notebook->current].widget;
-
- return RT_NULL;
-}
-void rtgui_notebook_set_current(rtgui_notebook_t* notebook, rtgui_widget_t* widget)
-{
- rt_int16_t index;
-
- RT_ASSERT(notebook != RT_NULL);
-
- for (index = 0; index < notebook->count; index ++)
- {
- if (widget == notebook->childs[index].widget)
- {
- rtgui_notebook_set_current_by_index(notebook, index);
- return;
- }
- }
-}
-
-void rtgui_notebook_set_current_by_index(rtgui_notebook_t* notebook, rt_uint16_t index)
-{
- RT_ASSERT(notebook != RT_NULL);
-
- if ((index < notebook->count) && (notebook->current != index))
- {
- if (notebook->current != RTGUI_NOT_FOUND)
- rtgui_widget_hide(notebook->childs[notebook->current].widget);
-
- notebook->current = index;
- rtgui_widget_show(notebook->childs[notebook->current].widget);
- rtgui_widget_update(notebook->childs[notebook->current].widget);
- }
-}
-
-rtgui_widget_t* rtgui_notebook_get_index(rtgui_notebook_t* notebook, rt_uint16_t index)
-{
- RT_ASSERT(notebook != RT_NULL);
- if (index < notebook->count)
- return notebook->childs[index].widget;
-
- return RT_NULL;
-}
-
-rt_bool_t rtgui_notebook_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_notebook* notebook;
-
- notebook = RTGUI_NOTEBOOK(widget);
- if (event->type == RTGUI_EVENT_PAINT)
- {
- _rtgui_notebook_ondraw(notebook);
- }
- else if (event->type == RTGUI_EVENT_MOUSE_BUTTON)
- {
- _rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event);
- }
- else if (event->type == RTGUI_EVENT_KBD)
- {
- if (notebook->current != RTGUI_NOT_FOUND)
- {
- if (notebook->childs[notebook->current].widget->event_handler != RT_NULL)
- return notebook->childs[notebook->current].widget->event_handler(notebook->childs[notebook->current].widget,
- event);
- }
- }
- else
- {
- /* use parent event handler */
- return rtgui_widget_event_handler(widget, event);
- }
-
- return RT_FALSE;
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/notebook.h>
+
+#define RTGUI_NOTEBOOK_TAB_WIDTH 80
+
+struct rtgui_notebook_tab
+{
+ struct rtgui_widget *widget;
+ char *title;
+};
+
+static void _rtgui_notebook_get_bar_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect);
+static void _rtgui_notebook_get_page_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect);
+
+static void _rtgui_notebook_constructor(struct rtgui_notebook *notebook)
+{
+ notebook->flag = 0;
+ notebook->childs = RT_NULL;
+ notebook->count = 0;
+ notebook->current = 0;
+
+ RTGUI_WIDGET(notebook)->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
+ rtgui_object_set_event_handler(RTGUI_OBJECT(notebook), rtgui_notebook_event_handler);
+}
+
+static void _rtgui_notebook_destructor(struct rtgui_notebook *notebook)
+{
+ int index;
+
+ if (notebook->childs != RT_NULL)
+ {
+ for (index = 0; index < notebook->count; index ++)
+ {
+ rtgui_widget_destroy(notebook->childs[index].widget);
+ rt_free(notebook->childs[index].title);
+ }
+
+ rtgui_free(notebook->childs);
+ }
+}
+
+DEFINE_CLASS_TYPE(notebook, "notebook",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_notebook_constructor,
+ _rtgui_notebook_destructor,
+ sizeof(struct rtgui_notebook));
+
+/* Draw tab bars of @param notebook. @param dc should be initialized and
+ * finished outside this function. Don't pass @param notebook or @param dc as
+ * RT_NULL, it should be checked outside.
+ */
+static void _rtgui_notebook_draw_bar(struct rtgui_notebook *notebook,
+ struct rtgui_dc *dc)
+{
+ struct rtgui_rect rect;
+ int index;
+
+ RT_ASSERT((notebook != RT_NULL) && (dc != RT_NULL));
+
+ if (notebook->flag & RTGUI_NOTEBOOK_NOTAB)
+ return;
+
+ _rtgui_notebook_get_bar_rect(notebook, &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ rect.x2 = rect.x1 + RTGUI_NOTEBOOK_TAB_WIDTH;
+ /* draw tab bar */
+ for (index = 0; index < notebook->count; index++)
+ {
+ if (notebook->current == index)
+ rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN);
+ else
+ rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX);
+
+ rtgui_dc_draw_text(dc, notebook->childs[index].title, &rect);
+ rect.x1 += RTGUI_NOTEBOOK_TAB_WIDTH;
+ rect.x2 += RTGUI_NOTEBOOK_TAB_WIDTH;
+ }
+
+}
+
+static void _rtgui_notebook_ondraw(struct rtgui_notebook *notebook)
+{
+ struct rtgui_dc* dc;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
+ if (dc == RT_NULL) return;
+
+ if (notebook->count == 0)
+ {
+ rtgui_rect_t rect;
+ rtgui_widget_get_rect(RTGUI_WIDGET(notebook), &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+ }
+ else
+ {
+ if (notebook->current == RTGUI_NOT_FOUND)
+ notebook->current = 0;
+
+ _rtgui_notebook_draw_bar(notebook, dc);
+
+ /* draw current tab */
+ rtgui_widget_update(notebook->childs[notebook->current].widget);
+ }
+ rtgui_dc_end_drawing(dc);
+}
+
+static void _rtgui_notebook_onmouse(struct rtgui_notebook *notebook, struct rtgui_event_mouse* emouse)
+{
+ rtgui_rect_t rect;
+
+ /* handle notebook bar */
+ _rtgui_notebook_get_bar_rect(notebook, &rect);
+ rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
+ if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK)
+ {
+ int index;
+ struct rtgui_dc* dc;
+
+ index = (emouse->x - rect.x1) / RTGUI_NOTEBOOK_TAB_WIDTH;
+ if (index < notebook->count && index != notebook->current)
+ {
+ /* update tab bar */
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook));
+ if (dc == RT_NULL) return;
+
+ rtgui_notebook_set_current_by_index(notebook, index);
+
+ _rtgui_notebook_draw_bar(notebook, dc);
+
+ rtgui_dc_end_drawing(dc);
+ }
+ }
+ else
+ {
+ /* handle on page */
+ if (RTGUI_OBJECT(notebook->childs[notebook->current].widget)->event_handler != RT_NULL)
+ RTGUI_OBJECT(notebook->childs[notebook->current].widget)->event_handler(
+ RTGUI_OBJECT(notebook->childs[notebook->current].widget),
+ &(emouse->parent));
+ }
+}
+
+static void _rtgui_notebook_get_page_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect)
+{
+ RT_ASSERT(notebook != RT_NULL);
+ RT_ASSERT(rect != RT_NULL);
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
+
+ if (notebook->flag == RTGUI_NOTEBOOK_NOTAB)
+ return;
+ else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
+ rect->y1 = rect->y1 + 25;
+ else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
+ rect->y2 = rect->y2 - 25;
+}
+
+static void _rtgui_notebook_get_bar_rect(struct rtgui_notebook *notebook, struct rtgui_rect* rect)
+{
+ RT_ASSERT(notebook != RT_NULL);
+ RT_ASSERT(rect != RT_NULL);
+
+ rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect);
+ if (notebook->flag == RTGUI_NOTEBOOK_NOTAB)
+ {
+ rect->x1 = rect->y1 = rect->x2 = rect->y2 = 0;
+ }
+ else if (notebook->flag == RTGUI_NOTEBOOK_TOP)
+ rect->y2 = rect->y1 + 25;
+ else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM)
+ rect->y1 = rect->y2 - 25;
+}
+
+struct rtgui_notebook* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style)
+{
+ struct rtgui_notebook* notebook;
+
+ notebook = (struct rtgui_notebook*) rtgui_widget_create(RTGUI_NOTEBOOK_TYPE);
+ if (notebook != RT_NULL)
+ {
+ notebook->flag = style;
+ rtgui_widget_set_rect(RTGUI_WIDGET(notebook), rect);
+ }
+
+ return notebook;
+}
+
+void rtgui_notebook_destroy(struct rtgui_notebook* notebook)
+{
+ rtgui_widget_destroy(RTGUI_WIDGET(notebook));
+}
+
+void rtgui_notebook_add(struct rtgui_notebook* notebook, const char* label, struct rtgui_widget* child)
+{
+ rtgui_rect_t rect;
+ RT_ASSERT(notebook != RT_NULL);
+
+ notebook->count += 1;
+ notebook->childs = (struct rtgui_notebook_tab*)
+ rtgui_realloc(notebook->childs,
+ sizeof(struct rtgui_notebook_tab) * notebook->count);
+
+ notebook->childs[notebook->count - 1].title = rt_strdup(label);
+ notebook->childs[notebook->count - 1].widget = child;
+
+ /* set parent */
+ rtgui_widget_set_parent(child, RTGUI_WIDGET(notebook));
+
+ _rtgui_notebook_get_page_rect(notebook, &rect);
+ rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect);
+ rtgui_widget_set_rect(child, &rect);
+
+ if (notebook->count - 1 != notebook->current)
+ rtgui_widget_hide(child);
+}
+
+void rtgui_notebook_remove(struct rtgui_notebook* notebook, rt_uint16_t index)
+{
+ struct rtgui_notebook_tab tab;
+ RT_ASSERT(notebook != RT_NULL);
+
+ if (index < notebook->count)
+ {
+ if (notebook->count == 1)
+ {
+ tab = notebook->childs[0];
+ rtgui_free(notebook->childs);
+ notebook->childs = RT_NULL;
+ notebook->count = 0;
+ }
+ else
+ {
+ tab = notebook->childs[index];
+ for (;index < notebook->count - 1; index ++)
+ {
+ notebook->childs[index] = notebook->childs[index + 1];
+ }
+
+ notebook->count -= 1;
+ notebook->childs = (struct rtgui_notebook_tab*) rtgui_realloc(notebook->childs,
+ sizeof(struct rtgui_notebook_tab) * notebook->count);
+ }
+
+ // FIXME: do we really want to destroy it?
+ rtgui_widget_destroy(tab.widget);
+ rtgui_free(tab.title);
+
+ if (notebook->current == index)
+ {
+ /* update tab */
+ if (notebook->current > notebook->count - 1)
+ notebook->current = notebook->count - 1;
+ rtgui_widget_update(RTGUI_WIDGET(notebook));
+ }
+ }
+}
+
+int rtgui_notebook_get_count(struct rtgui_notebook* notebook)
+{
+ RT_ASSERT(notebook != RT_NULL);
+ return notebook->count;
+}
+
+struct rtgui_widget* rtgui_notebook_get_current(struct rtgui_notebook* notebook)
+{
+ RT_ASSERT(notebook != RT_NULL);
+ if (notebook->current != RTGUI_NOT_FOUND)
+ return notebook->childs[notebook->current].widget;
+
+ return RT_NULL;
+}
+
+rt_int16_t rtgui_notebook_get_current_index(struct rtgui_notebook* notebook)
+{
+ RT_ASSERT(notebook != RT_NULL);
+ return notebook->current;
+}
+
+void rtgui_notebook_set_current(struct rtgui_notebook* notebook, struct rtgui_widget* widget)
+{
+ rt_int16_t index;
+
+ RT_ASSERT(notebook != RT_NULL);
+
+ for (index = 0; index < notebook->count; index ++)
+ {
+ if (widget == notebook->childs[index].widget)
+ {
+ rtgui_notebook_set_current_by_index(notebook, index);
+ return;
+ }
+ }
+}
+
+void rtgui_notebook_set_current_by_index(struct rtgui_notebook* notebook, rt_uint16_t index)
+{
+ RT_ASSERT(notebook != RT_NULL);
+
+ if ((index < notebook->count) && (notebook->current != index))
+ {
+ if (notebook->current != RTGUI_NOT_FOUND)
+ rtgui_widget_hide(notebook->childs[notebook->current].widget);
+
+ notebook->current = index;
+ rtgui_widget_show(notebook->childs[notebook->current].widget);
+ rtgui_widget_update(notebook->childs[notebook->current].widget);
+ }
+}
+
+struct rtgui_widget* rtgui_notebook_get_widget_at(struct rtgui_notebook* notebook, rt_uint16_t index)
+{
+ RT_ASSERT(notebook != RT_NULL);
+ if (index < notebook->count)
+ return notebook->childs[index].widget;
+
+ return RT_NULL;
+}
+
+rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_notebook* notebook;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ notebook = RTGUI_NOTEBOOK(object);
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ _rtgui_notebook_ondraw(notebook);
+ break;
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ _rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event);
+ break;
+ case RTGUI_EVENT_KBD:
+ if (notebook->current != RTGUI_NOT_FOUND)
+ {
+ if (RTGUI_OBJECT(notebook->childs[notebook->current].widget
+ )->event_handler != RT_NULL)
+ return RTGUI_OBJECT(notebook->childs[notebook->current].widget
+ )->event_handler(
+ RTGUI_OBJECT(notebook->childs[notebook->current].widget),
+ event);
+ }
+ break;
+ default:
+ /* use parent event handler */
+ return rtgui_widget_event_handler(object, event);
+ }
+
+ return RT_FALSE;
+}
diff --git a/components/rtgui/widgets/progressbar.c b/components/rtgui/widgets/progressbar.c
index 84e2adea1d..c42f2a3688 100644
--- a/components/rtgui/widgets/progressbar.c
+++ b/components/rtgui/widgets/progressbar.c
@@ -1,101 +1,104 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/progressbar.h>
-
-#define RTGUI_PROGRESSBAR_DEFAULT_RANGE 100
-
-static void _rtgui_progressbar_constructor(rtgui_progressbar_t *bar)
-{
- rtgui_rect_t rect = {0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT};
-
- rtgui_widget_set_event_handler(RTGUI_WIDGET(bar), rtgui_progressbar_event_handler);
- rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
-
- bar->orient = RTGUI_HORIZONTAL;
- bar->range = RTGUI_PROGRESSBAR_DEFAULT_RANGE;
- bar->position = 0;
-
- /* set gc */
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
-}
-
-DEFINE_CLASS_TYPE(progressbar, "progressbar",
- RTGUI_WIDGET_TYPE,
- _rtgui_progressbar_constructor,
- RT_NULL,
- sizeof(struct rtgui_progressbar));
-
-rt_bool_t rtgui_progressbar_event_handler(struct rtgui_widget* widget,
- struct rtgui_event* event)
-{
- struct rtgui_progressbar* bar = (struct rtgui_progressbar*)widget;
-
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- rtgui_theme_draw_progressbar(bar);
- break;
- }
-
- return RT_FALSE;
-}
-
-struct rtgui_progressbar* rtgui_progressbar_create(int orientation, int range,
- rtgui_rect_t* r)
-{
- struct rtgui_progressbar* bar;
-
- bar = (struct rtgui_progressbar*) rtgui_widget_create (RTGUI_PROGRESSBAR_TYPE);
- if (bar != RT_NULL)
- {
- if (r != RT_NULL)
- rtgui_widget_set_rect(RTGUI_WIDGET(bar), r);
-
- bar->orient = orientation;
- bar->range = range;
- }
-
- return bar;
-}
-
-void rtgui_progressbar_destroy(struct rtgui_progressbar* bar)
-{
- rtgui_widget_destroy(RTGUI_WIDGET(bar));
-}
-
-void rtgui_progressbar_set_value(struct rtgui_progressbar *bar, int value)
-{
- RT_ASSERT(bar != RT_NULL);
-
- if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) return;
-
- bar->position = value;
-
- rtgui_theme_draw_progressbar(bar);
- return;
-}
-
-int rtgui_progressbar_get_value(struct rtgui_progressbar *bar)
-{
- RT_ASSERT(bar != RT_NULL);
-
- return bar->position;
-}
-
-void rtgui_progressbar_set_range(struct rtgui_progressbar *bar, int range)
-{
- RT_ASSERT(bar != RT_NULL);
-
- bar->range = range;
-
- rtgui_theme_draw_progressbar(bar);
- return;
-}
-
-int rtgui_progressbar_get_range(struct rtgui_progressbar *bar)
-{
- RT_ASSERT(bar != RT_NULL);
-
- return bar->range;
-}
-
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/progressbar.h>
+
+#define RTGUI_PROGRESSBAR_DEFAULT_RANGE 100
+
+static void _rtgui_progressbar_constructor(rtgui_progressbar_t *bar)
+{
+ rtgui_rect_t rect = {0, 0, DEFAULT_WIDTH, DEFAULT_HEIGHT};
+
+ rtgui_object_set_event_handler(RTGUI_OBJECT(bar), rtgui_progressbar_event_handler);
+ rtgui_widget_set_rect(RTGUI_WIDGET(bar), &rect);
+
+ bar->orient = RTGUI_HORIZONTAL;
+ bar->range = RTGUI_PROGRESSBAR_DEFAULT_RANGE;
+ bar->position = 0;
+
+ /* set gc */
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(bar)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+DEFINE_CLASS_TYPE(progressbar, "progressbar",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_progressbar_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_progressbar));
+
+rt_bool_t rtgui_progressbar_event_handler(struct rtgui_object* object,
+ struct rtgui_event* event)
+{
+ struct rtgui_progressbar* bar;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ bar = RTGUI_PROGRESSBAR(object);
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ rtgui_theme_draw_progressbar(bar);
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+struct rtgui_progressbar* rtgui_progressbar_create(int orientation, int range,
+ rtgui_rect_t* r)
+{
+ struct rtgui_progressbar* bar;
+
+ bar = (struct rtgui_progressbar*) rtgui_widget_create (RTGUI_PROGRESSBAR_TYPE);
+ if (bar != RT_NULL)
+ {
+ if (r != RT_NULL)
+ rtgui_widget_set_rect(RTGUI_WIDGET(bar), r);
+
+ bar->orient = orientation;
+ bar->range = range;
+ }
+
+ return bar;
+}
+
+void rtgui_progressbar_destroy(struct rtgui_progressbar* bar)
+{
+ rtgui_widget_destroy(RTGUI_WIDGET(bar));
+}
+
+void rtgui_progressbar_set_value(struct rtgui_progressbar *bar, int value)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ if (!RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(bar))) return;
+
+ bar->position = value;
+
+ rtgui_theme_draw_progressbar(bar);
+ return;
+}
+
+int rtgui_progressbar_get_value(struct rtgui_progressbar *bar)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ return bar->position;
+}
+
+void rtgui_progressbar_set_range(struct rtgui_progressbar *bar, int range)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ bar->range = range;
+
+ rtgui_theme_draw_progressbar(bar);
+ return;
+}
+
+int rtgui_progressbar_get_range(struct rtgui_progressbar *bar)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ return bar->range;
+}
+
diff --git a/components/rtgui/widgets/radiobox.c b/components/rtgui/widgets/radiobox.c
index a4f1f7de94..b886c584c4 100644
--- a/components/rtgui/widgets/radiobox.c
+++ b/components/rtgui/widgets/radiobox.c
@@ -1,244 +1,246 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/radiobox.h>
-
-#define RTGUI_RADIOBOX_DEFAULT_WIDTH 100
-#define RTGUI_RADIOBOX_DEFAULT_HEIGHT 20
-
-static void _rtgui_radiobox_constructor(rtgui_radiobox_t *radiobox)
-{
- rtgui_rect_t rect = {0, 0, RTGUI_RADIOBOX_DEFAULT_WIDTH, RTGUI_RADIOBOX_DEFAULT_HEIGHT};
-
- /* init widget and set event handler */
- RTGUI_WIDGET(radiobox)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
- RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(radiobox)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
- rtgui_widget_set_rect(RTGUI_WIDGET(radiobox), &rect);
- rtgui_widget_set_event_handler(RTGUI_WIDGET(radiobox), rtgui_radiobox_event_handler);
-
- /* set proper of control */
- radiobox->items = RT_NULL;
- radiobox->item_count = 0;
- radiobox->item_selection = -1;
- radiobox->orient = RTGUI_HORIZONTAL;
-}
-
-DEFINE_CLASS_TYPE(radiobox, "radiobox",
- RTGUI_WIDGET_TYPE,
- _rtgui_radiobox_constructor,
- RT_NULL,
- sizeof(struct rtgui_radiobox));
-
-static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui_event_mouse* event)
-{
- RT_ASSERT(radiobox != RT_NULL);
- RT_ASSERT(event != RT_NULL);
-
- /* widget is hide, return */
- if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox)) ||
- !RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(radiobox))) return;
-
- if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
- event->button & RTGUI_MOUSE_BUTTON_LEFT)
- {
- int bord_size;
- struct rtgui_rect rect;
-
- /* focus widgets */
- rtgui_widget_focus(RTGUI_WIDGET(radiobox));
-
- /* get widget physical rect */
- rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
- rtgui_widget_rect_to_device(RTGUI_WIDGET(radiobox), &rect);
-
- /* get board size */
- if (radiobox->orient == RTGUI_VERTICAL)
- bord_size = radiobox->item_size;
- else
- {
- struct rtgui_rect bord_rect;
-
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &bord_rect);
- bord_size = rtgui_rect_height(bord_rect);
- }
- rtgui_rect_inflate(&rect, - bord_size);
- if (rtgui_rect_contains_point(&rect, event->x, event->y) != RT_EOK) return;
-
- if (radiobox->orient == RTGUI_VERTICAL)
- {
- int delta_y = event->y - rect.y1;
- rtgui_radiobox_set_selection(radiobox, delta_y / radiobox->item_size);
- }
- else
- {
- int delta_x = event->x - rect.x1;
- rtgui_radiobox_set_selection(radiobox, delta_x / radiobox->item_size);
- }
- }
-}
-
-rt_bool_t rtgui_radiobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_radiobox* radiobox = (struct rtgui_radiobox*)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_theme_draw_radiobox(radiobox);
- }
-
- break;
-
- case RTGUI_EVENT_KBD:
- if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox))) return RT_FALSE;
-
-#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_key != RT_NULL) widget->on_key(widget, event);
- else
-#endif
- {
- struct rtgui_event_kbd *e = (struct rtgui_event_kbd*)event;
-
- /* set focused */
- rtgui_widget_focus(RTGUI_WIDGET(radiobox));
- if (!(RTGUI_KBD_IS_UP(e))) return RT_FALSE;
-
- if (radiobox->orient == RTGUI_VERTICAL)
- {
- if (e->key == RTGUIK_UP)
- {
- if (radiobox->item_selection > 0)
- rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
- }
- else if (e->key == RTGUIK_DOWN)
- {
- if (radiobox->item_selection < radiobox->item_count - 1)
- rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
- }
- }
- else
- {
- if (e->key == RTGUIK_LEFT)
- {
- if (radiobox->item_selection > 0)
- rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
- }
- else if (e->key == RTGUIK_RIGHT)
- {
- if (radiobox->item_selection < radiobox->item_count - 1)
- rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
- }
- }
- }
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
-#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
- else
-#endif
- {
- rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event);
- }
- break;
- }
-
- return RT_FALSE;
-}
-
-struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char** radio_items, int number)
-{
- struct rtgui_radiobox* radiobox;
-
- radiobox = (struct rtgui_radiobox*) rtgui_widget_create (RTGUI_RADIOBOX_TYPE);
- if (radiobox != RT_NULL)
- {
- rt_uint8_t board_size;
- struct rtgui_rect rect;
-
- radiobox->items = radio_items;
- radiobox->item_count = number;
- radiobox->item_selection = -1;
- radiobox->text = rt_strdup(label);
-
- /* set proper of control */
- rtgui_radiobox_set_orientation(radiobox, orient);
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &rect);
- board_size = rtgui_rect_height(rect);
-
- if (orient == RTGUI_VERTICAL)
- {
- radiobox->item_size = board_size;
- }
- else
- {
- int index;
- struct rtgui_font* font;
- struct rtgui_rect rect;
-
- /* set init item size */
- radiobox->item_size = 0;
-
- font = RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox));
- for (index = 0; index < number; index ++)
- {
- rtgui_font_get_metrics(font, radio_items[index], &rect);
- if ( (board_size + 3 + rtgui_rect_width(rect)) > radiobox->item_size)
- radiobox->item_size = board_size + 3 + rtgui_rect_width(rect);
- }
- }
-
- if (radiobox->item_size < RADIO_BOX_H + 2)
- radiobox->item_size = RADIO_BOX_H + 2;
- }
-
- return radiobox;
-}
-
-void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation)
-{
- RT_ASSERT(radiobox != RT_NULL);
-
- /* set orientation */
- radiobox->orient = orientation;
-#ifndef RTGUI_USING_SMALL_SIZE
- if (radiobox->orient == RTGUI_HORIZONTAL)
- {
- /* HORIZONTAL */
- rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
- rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
- }
- else
- {
- /* VERTICAL */
- rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
- rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
- }
-#endif
-}
-
-void rtgui_radiobox_set_selection(struct rtgui_radiobox* radiobox, int selection)
-{
- rt_uint16_t old_item;
-
- if (selection == radiobox->item_selection) return;
-
- old_item = radiobox->item_selection;
- if (selection >= 0 && selection < radiobox->item_count)
- {
- radiobox->item_selection = selection;
- }
-
- /* update radiobox widget */
- rtgui_theme_draw_radiobutton(radiobox, old_item);
- rtgui_theme_draw_radiobutton(radiobox, radiobox->item_selection);
-}
-
-int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox)
-{
- return radiobox->item_selection;
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/radiobox.h>
+
+#define RTGUI_RADIOBOX_DEFAULT_WIDTH 100
+#define RTGUI_RADIOBOX_DEFAULT_HEIGHT 20
+
+static void _rtgui_radiobox_constructor(rtgui_radiobox_t *radiobox)
+{
+ rtgui_rect_t rect = {0, 0, RTGUI_RADIOBOX_DEFAULT_WIDTH, RTGUI_RADIOBOX_DEFAULT_HEIGHT};
+
+ /* init widget and set event handler */
+ RTGUI_WIDGET(radiobox)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(radiobox)) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
+ rtgui_widget_set_rect(RTGUI_WIDGET(radiobox), &rect);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(radiobox), rtgui_radiobox_event_handler);
+
+ /* set proper of control */
+ radiobox->items = RT_NULL;
+ radiobox->item_count = 0;
+ radiobox->item_selection = -1;
+ radiobox->orient = RTGUI_HORIZONTAL;
+}
+
+DEFINE_CLASS_TYPE(radiobox, "radiobox",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_radiobox_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_radiobox));
+
+static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui_event_mouse* event)
+{
+ RT_ASSERT(radiobox != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ /* widget is hide, return */
+ if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox)) ||
+ !RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(radiobox))) return;
+
+ if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
+ event->button & RTGUI_MOUSE_BUTTON_LEFT)
+ {
+ int bord_size;
+ struct rtgui_rect rect;
+
+ /* focus widgets */
+ rtgui_widget_focus(RTGUI_WIDGET(radiobox));
+
+ /* get widget physical rect */
+ rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect);
+ rtgui_widget_rect_to_device(RTGUI_WIDGET(radiobox), &rect);
+
+ /* get board size */
+ if (radiobox->orient == RTGUI_VERTICAL)
+ bord_size = radiobox->item_size;
+ else
+ {
+ struct rtgui_rect bord_rect;
+
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &bord_rect);
+ bord_size = rtgui_rect_height(bord_rect);
+ }
+ rtgui_rect_inflate(&rect, - bord_size);
+ if (rtgui_rect_contains_point(&rect, event->x, event->y) != RT_EOK) return;
+
+ if (radiobox->orient == RTGUI_VERTICAL)
+ {
+ int delta_y = event->y - rect.y1;
+ rtgui_radiobox_set_selection(radiobox, delta_y / radiobox->item_size);
+ }
+ else
+ {
+ int delta_x = event->x - rect.x1;
+ rtgui_radiobox_set_selection(radiobox, delta_x / radiobox->item_size);
+ }
+ }
+}
+
+rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_radiobox* radiobox;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ radiobox = RTGUI_RADIOBOX(object);
+ 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_theme_draw_radiobox(radiobox);
+ }
+
+ break;
+
+ case RTGUI_EVENT_KBD:
+ if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(radiobox))) return RT_FALSE;
+
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (widget->on_key != RT_NULL) widget->on_key(widget, event);
+ else
+#endif
+ {
+ struct rtgui_event_kbd *e = (struct rtgui_event_kbd*)event;
+
+ /* set focused */
+ rtgui_widget_focus(RTGUI_WIDGET(radiobox));
+ if (!(RTGUI_KBD_IS_UP(e))) return RT_FALSE;
+
+ if (radiobox->orient == RTGUI_VERTICAL)
+ {
+ if (e->key == RTGUIK_UP)
+ {
+ if (radiobox->item_selection > 0)
+ rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
+ }
+ else if (e->key == RTGUIK_DOWN)
+ {
+ if (radiobox->item_selection < radiobox->item_count - 1)
+ rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
+ }
+ }
+ else
+ {
+ if (e->key == RTGUIK_LEFT)
+ {
+ if (radiobox->item_selection > 0)
+ rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
+ }
+ else if (e->key == RTGUIK_RIGHT)
+ {
+ if (radiobox->item_selection < radiobox->item_count - 1)
+ rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
+ }
+ }
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
+ else
+#endif
+ {
+ rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event);
+ }
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+struct rtgui_radiobox* rtgui_radiobox_create(const char* label, int orient, char** radio_items, int number)
+{
+ struct rtgui_radiobox* radiobox;
+
+ radiobox = (struct rtgui_radiobox*) rtgui_widget_create (RTGUI_RADIOBOX_TYPE);
+ if (radiobox != RT_NULL)
+ {
+ rt_uint8_t board_size;
+ struct rtgui_rect rect;
+
+ radiobox->items = radio_items;
+ radiobox->item_count = number;
+ radiobox->item_selection = -1;
+ radiobox->text = rt_strdup(label);
+
+ /* set proper of control */
+ rtgui_radiobox_set_orientation(radiobox, orient);
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &rect);
+ board_size = rtgui_rect_height(rect);
+
+ if (orient == RTGUI_VERTICAL)
+ {
+ radiobox->item_size = board_size;
+ }
+ else
+ {
+ int index;
+ struct rtgui_font* font;
+ struct rtgui_rect rect;
+
+ /* set init item size */
+ radiobox->item_size = 0;
+
+ font = RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox));
+ for (index = 0; index < number; index ++)
+ {
+ rtgui_font_get_metrics(font, radio_items[index], &rect);
+ if ( (board_size + 3 + rtgui_rect_width(rect)) > radiobox->item_size)
+ radiobox->item_size = board_size + 3 + rtgui_rect_width(rect);
+ }
+ }
+
+ if (radiobox->item_size < RADIO_BOX_H + 2)
+ radiobox->item_size = RADIO_BOX_H + 2;
+ }
+
+ return radiobox;
+}
+
+void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation)
+{
+ RT_ASSERT(radiobox != RT_NULL);
+
+ /* set orientation */
+ radiobox->orient = orientation;
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (radiobox->orient == RTGUI_HORIZONTAL)
+ {
+ /* HORIZONTAL */
+ rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
+ rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
+ }
+ else
+ {
+ /* VERTICAL */
+ rtgui_widget_set_miniwidth(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_HEIGHT);
+ rtgui_widget_set_miniheight(RTGUI_WIDGET(radiobox), RTGUI_RADIOBOX_DEFAULT_WIDTH);
+ }
+#endif
+}
+
+void rtgui_radiobox_set_selection(struct rtgui_radiobox* radiobox, int selection)
+{
+ rt_uint16_t old_item;
+
+ if (selection == radiobox->item_selection) return;
+
+ old_item = radiobox->item_selection;
+ if (selection >= 0 && selection < radiobox->item_count)
+ {
+ radiobox->item_selection = selection;
+ }
+
+ /* update radiobox widget */
+ rtgui_theme_draw_radiobutton(radiobox, old_item);
+ rtgui_theme_draw_radiobutton(radiobox, radiobox->item_selection);
+}
+
+int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox)
+{
+ return radiobox->item_selection;
+}
diff --git a/components/rtgui/widgets/scrollbar.c b/components/rtgui/widgets/scrollbar.c
index 5581ba0560..58a3017b3c 100644
--- a/components/rtgui/widgets/scrollbar.c
+++ b/components/rtgui/widgets/scrollbar.c
@@ -1,415 +1,419 @@
-/*
- * File : scrollbar.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2010-08-09 Bernard first version
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.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->status = 0;
- bar->thumb_position = 0;
- bar->thumb_size = 16;
- bar->on_scroll = RT_NULL;
-
- bar->orient = RTGUI_HORIZONTAL;
- 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;
-}
-
-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;
- }
-}
-
-DEFINE_CLASS_TYPE(scrollbar, "scrollbar",
- RTGUI_WIDGET_TYPE,
- _rtgui_scrollbar_constructor,
- RT_NULL,
- sizeof(struct rtgui_scrollbar));
-
-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.y2 - widget->extent.y1);
- 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_theme_draw_scrollbar(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);
- }
-}
-
-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_theme_draw_scrollbar(bar);
- }
-
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(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;
-}
-
-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);
- if (orient == RTGUI_VERTICAL)
- bar->thumb_size = (r->x2 - r->x1);
- else
- bar->thumb_size = (r->y2 - r->y1);
- }
-
- 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;
-#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;
-}
+/*
+ * File : scrollbar.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2010-08-09 Bernard first version
+ */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.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_object_set_event_handler(RTGUI_OBJECT(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->status = 0;
+ bar->thumb_position = 0;
+ bar->thumb_size = 16;
+ bar->on_scroll = RT_NULL;
+
+ bar->orient = RTGUI_HORIZONTAL;
+ 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;
+}
+
+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;
+ }
+}
+
+DEFINE_CLASS_TYPE(scrollbar, "scrollbar",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_scrollbar_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_scrollbar));
+
+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.y2 - widget->extent.y1);
+ 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_theme_draw_scrollbar(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(RTGUI_OBJECT(widget), RT_NULL);
+ }
+}
+
+rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_object *object,
+ struct rtgui_event *event)
+{
+ struct rtgui_scrollbar* bar;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ bar = RTGUI_SCROLLBAR(object);
+
+ 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_theme_draw_scrollbar(bar);
+ }
+
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if (RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(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;
+}
+
+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);
+ if (orient == RTGUI_VERTICAL)
+ bar->thumb_size = (r->x2 - r->x1);
+ else
+ bar->thumb_size = (r->y2 - r->y1);
+ }
+
+ 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;
+#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;
+}
diff --git a/components/rtgui/widgets/slider.c b/components/rtgui/widgets/slider.c
index d44954f9b4..30d29d84f9 100644
--- a/components/rtgui/widgets/slider.c
+++ b/components/rtgui/widgets/slider.c
@@ -1,241 +1,266 @@
-/*
- * File : slider.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2009-10-16 Bernard first version
- * 2010-09-10 Bernard fix hide issue
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/slider.h>
-
-#define RTGUI_SLIDER_DEFAULT_WIDTH 100
-#define RTGUI_SLIDER_DEFAULT_HEIGHT 20
-#define RTGUI_SLIDER_DEFAULT_MIN 0
-#define RTGUI_SLIDER_DEFAULT_MAX 100
-
-static void _rtgui_slider_constructor(rtgui_slider_t *slider)
-{
- rtgui_rect_t rect = {0, 0, RTGUI_SLIDER_DEFAULT_WIDTH, RTGUI_SLIDER_DEFAULT_HEIGHT};
-
- /* init widget and set event handler */
- RTGUI_WIDGET(slider)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
- rtgui_widget_set_rect(RTGUI_WIDGET(slider), &rect);
- rtgui_widget_set_event_handler(RTGUI_WIDGET(slider), rtgui_slider_event_handler);
-
- /* set proper of control */
- slider->min = RTGUI_SLIDER_DEFAULT_MIN;
- slider->max = RTGUI_SLIDER_DEFAULT_MAX;
- slider->value = RTGUI_SLIDER_DEFAULT_MIN;
- slider->orient = RTGUI_HORIZONTAL;
-
- slider->ticks = 10;
- slider->thumb_width = 8;
- slider->on_changed = RT_NULL;
-}
-
-DEFINE_CLASS_TYPE(slider, "slider",
- RTGUI_WIDGET_TYPE,
- _rtgui_slider_constructor,
- RT_NULL,
- sizeof(struct rtgui_slider));
-
-static void rtgui_slider_onmouse(struct rtgui_slider* slider, struct rtgui_event_mouse* event)
-{
- RT_ASSERT(slider != RT_NULL);
- RT_ASSERT(event != RT_NULL);
-
- if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
- event->button & RTGUI_MOUSE_BUTTON_LEFT)
- {
- int sel;
- int range = slider->max - slider->min;
- int x0, xsize;
- int x;
- x0 = 1 + slider->thumb_width/2;
-
- if (slider->orient == RTGUI_VERTICAL)
- {
- x = event->y - RTGUI_WIDGET(slider)->extent.y1;
- x -= x0;
- xsize = rtgui_rect_height(RTGUI_WIDGET(slider)->extent) - 2 * x0;
- }
- else
- {
- x = event->x - RTGUI_WIDGET(slider)->extent.x1;
- x -= x0;
- xsize = rtgui_rect_width(RTGUI_WIDGET(slider)->extent) - 2 * x0;
- }
-
- if (x <= 0)
- {
- sel = slider->min;
- }
- else if (x >= xsize)
- {
- sel = slider->max;
- }
- else
- {
- sel = ((range * x) + xsize/2) / xsize;
- sel += slider->min;
- }
-
- rtgui_widget_focus(RTGUI_WIDGET(slider));
- rtgui_slider_set_value(slider, sel);
- if (slider->on_changed != RT_NULL) /* invoke callback function */
- slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
- }
-}
-
-static void rtgui_slider_onkey(struct rtgui_slider* slider, struct rtgui_event_kbd *event)
-{
- RT_ASSERT(slider != RT_NULL);
- RT_ASSERT(event != RT_NULL);
-
- if (!(RTGUI_KBD_IS_UP(event))) return;
-
- if (event->key == RTGUIK_LEFT)
- {
- if (slider->value > slider->min)
- slider->value ++;
- }
-
- if (event->key == RTGUIK_RIGHT)
- {
- if (slider->value < slider->max)
- slider->value --;
- }
-
- /* update widget */
- rtgui_widget_update(RTGUI_WIDGET(slider));
- if (slider->on_changed != RT_NULL) /* invoke callback function */
- slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
-}
-
-rt_bool_t rtgui_slider_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_slider* slider = (struct rtgui_slider*)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_theme_draw_slider(slider);
- }
-
- break;
-
- case RTGUI_EVENT_KBD:
- if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
-
-#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_key != RT_NULL) widget->on_key(widget, event);
- else
-#endif
- {
- rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event);
- }
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
-
-#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
- else
-#endif
- {
- rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event);
- }
- break;
- }
-
- return RT_FALSE;
-}
-
-struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient)
-{
- struct rtgui_slider* slider;
-
- slider = (struct rtgui_slider*) rtgui_widget_create (RTGUI_SLIDER_TYPE);
- if (slider != RT_NULL)
- {
- /* set proper of control */
- slider->min = min;
- slider->max = max;
- slider->value = min;
-
- slider->ticks = 10;
- slider->thumb_width = 8;
-
- rtgui_slider_set_orientation(slider, orient);
- }
-
- return slider;
-}
-
-void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max)
-{
- RT_ASSERT(slider != RT_NULL);
-
- slider->max = max;
- slider->min = min;
-}
-
-void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value)
-{
- RT_ASSERT(slider != RT_NULL);
-
- if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(slider)))
- {
- if (value < slider->min) value = slider->min;
- if (value > slider->max) value = slider->max;
-
- if (slider->value != value)
- {
- slider->value = value;
- rtgui_theme_draw_slider(slider);
- }
- }
-}
-
-void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation)
-{
- RT_ASSERT(slider != RT_NULL);
-
- /* set orientation */
- slider->orient = orientation;
-#ifndef RTGUI_USING_SMALL_SIZE
- if (slider->orient == RTGUI_HORIZONTAL)
- {
- /* HORIZONTAL */
- rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
- rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
- }
- else
- {
- /* VERTICAL */
- rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
- rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
- }
-#endif
-}
-
-rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider)
-{
- RT_ASSERT(slider != RT_NULL);
-
- return slider->value;
-}
+/*
+ * File : slider.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2010, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-10-16 Bernard first version
+ * 2010-09-10 Bernard fix hide issue
+ */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/slider.h>
+
+#define RTGUI_SLIDER_DEFAULT_WIDTH 100
+#define RTGUI_SLIDER_DEFAULT_HEIGHT 20
+#define RTGUI_SLIDER_DEFAULT_MIN 0
+#define RTGUI_SLIDER_DEFAULT_MAX 100
+
+static void _rtgui_slider_constructor(rtgui_slider_t *slider)
+{
+ rtgui_rect_t rect = {0, 0, RTGUI_SLIDER_DEFAULT_WIDTH, RTGUI_SLIDER_DEFAULT_HEIGHT};
+
+ /* init widget and set event handler */
+ RTGUI_WIDGET(slider)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ rtgui_widget_set_rect(RTGUI_WIDGET(slider), &rect);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(slider), rtgui_slider_event_handler);
+
+ /* set proper of control */
+ slider->min = RTGUI_SLIDER_DEFAULT_MIN;
+ slider->max = RTGUI_SLIDER_DEFAULT_MAX;
+ slider->value = RTGUI_SLIDER_DEFAULT_MIN;
+ slider->orient = RTGUI_HORIZONTAL;
+
+ slider->ticks = 10;
+ slider->thumb_width = 8;
+ slider->on_changed = RT_NULL;
+}
+
+DEFINE_CLASS_TYPE(slider, "slider",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_slider_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_slider));
+
+static void rtgui_slider_onmouse(struct rtgui_slider* slider, struct rtgui_event_mouse* event)
+{
+ RT_ASSERT(slider != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ if (event->button & RTGUI_MOUSE_BUTTON_DOWN &&
+ event->button & RTGUI_MOUSE_BUTTON_LEFT)
+ {
+ int sel;
+ int range = slider->max - slider->min;
+ int x0, xsize;
+ int x;
+ x0 = 1 + slider->thumb_width/2;
+
+ if (slider->orient == RTGUI_VERTICAL)
+ {
+ x = event->y - RTGUI_WIDGET(slider)->extent.y1;
+ x -= x0;
+ xsize = rtgui_rect_height(RTGUI_WIDGET(slider)->extent) - 2 * x0;
+ }
+ else
+ {
+ x = event->x - RTGUI_WIDGET(slider)->extent.x1;
+ x -= x0;
+ xsize = rtgui_rect_width(RTGUI_WIDGET(slider)->extent) - 2 * x0;
+ }
+
+ if (x <= 0)
+ {
+ sel = slider->min;
+ }
+ else if (x >= xsize)
+ {
+ sel = slider->max;
+ }
+ else
+ {
+ sel = ((range * x) + xsize/2) / xsize;
+ sel += slider->min;
+ }
+
+ rtgui_widget_focus(RTGUI_WIDGET(slider));
+ rtgui_slider_set_value(slider, sel);
+ if (slider->on_changed != RT_NULL) /* invoke callback function */
+ slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
+ }
+}
+
+static rt_bool_t rtgui_slider_onkey(struct rtgui_slider* slider, struct rtgui_event_kbd *event)
+{
+ RT_ASSERT(slider != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ if (!(RTGUI_KBD_IS_UP(event)))
+ return RT_TRUE;
+
+ if (slider->orient == RTGUI_HORIZONTAL)
+ {
+ if (event->key == RTGUIK_RIGHT)
+ {
+ if (slider->value > slider->min)
+ slider->value++;
+ }
+ else if (event->key == RTGUIK_LEFT)
+ {
+ if (slider->value < slider->max)
+ slider->value--;
+ }
+ }
+ else
+ {
+ if (event->key == RTGUIK_UP)
+ {
+ if (slider->value > slider->min)
+ slider->value--;
+ }
+ else if (event->key == RTGUIK_DOWN)
+ {
+ if (slider->value < slider->max)
+ slider->value++;
+ }
+ }
+
+ /* update widget */
+ rtgui_widget_update(RTGUI_WIDGET(slider));
+ if (slider->on_changed != RT_NULL) /* invoke callback function */
+ slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);
+
+ return RT_TRUE;
+}
+
+rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_event *event)
+{
+ struct rtgui_widget *widget;
+ struct rtgui_slider* slider;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ widget = RTGUI_WIDGET(object);
+ slider = RTGUI_SLIDER(object);
+
+ 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_theme_draw_slider(slider);
+ }
+
+ break;
+
+ case RTGUI_EVENT_KBD:
+ if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
+
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (widget->on_key != RT_NULL) widget->on_key(widget, event);
+ else
+#endif
+ {
+ return rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event);
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
+
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
+ else
+#endif
+ {
+ rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event);
+ }
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+struct rtgui_slider* rtgui_slider_create(rt_size_t min, rt_size_t max, int orient)
+{
+ struct rtgui_slider* slider;
+
+ slider = (struct rtgui_slider*) rtgui_widget_create (RTGUI_SLIDER_TYPE);
+ if (slider != RT_NULL)
+ {
+ /* set proper of control */
+ slider->min = min;
+ slider->max = max;
+ slider->value = min;
+
+ slider->ticks = 10;
+ slider->thumb_width = 8;
+
+ rtgui_slider_set_orientation(slider, orient);
+ }
+
+ return slider;
+}
+
+void rtgui_slider_set_range(struct rtgui_slider* slider, rt_size_t min, rt_size_t max)
+{
+ RT_ASSERT(slider != RT_NULL);
+
+ slider->max = max;
+ slider->min = min;
+}
+
+void rtgui_slider_set_value(struct rtgui_slider* slider, rt_size_t value)
+{
+ RT_ASSERT(slider != RT_NULL);
+
+ if (RTGUI_WIDGET_IS_ENABLE(RTGUI_WIDGET(slider)))
+ {
+ if (value < slider->min) value = slider->min;
+ if (value > slider->max) value = slider->max;
+
+ if (slider->value != value)
+ {
+ slider->value = value;
+ rtgui_theme_draw_slider(slider);
+ }
+ }
+}
+
+void rtgui_slider_set_orientation(struct rtgui_slider* slider, int orientation)
+{
+ RT_ASSERT(slider != RT_NULL);
+
+ /* set orientation */
+ slider->orient = orientation;
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (slider->orient == RTGUI_HORIZONTAL)
+ {
+ /* HORIZONTAL */
+ rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
+ rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
+ }
+ else
+ {
+ /* VERTICAL */
+ rtgui_widget_set_miniwidth(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_HEIGHT);
+ rtgui_widget_set_miniheight(RTGUI_WIDGET(slider), RTGUI_SLIDER_DEFAULT_WIDTH);
+ }
+#endif
+}
+
+rt_size_t rtgui_slider_get_value(struct rtgui_slider* slider)
+{
+ RT_ASSERT(slider != RT_NULL);
+
+ return slider->value;
+}
diff --git a/components/rtgui/widgets/staticline.c b/components/rtgui/widgets/staticline.c
index a1c38bbd20..19a1caed49 100644
--- a/components/rtgui/widgets/staticline.c
+++ b/components/rtgui/widgets/staticline.c
@@ -1,80 +1,80 @@
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_theme.h>
-#include <rtgui/widgets/staticline.h>
-
-static void _rtgui_staticline_constructor(rtgui_staticline_t *staticline)
-{
- /* init widget and set event handler */
- rtgui_rect_t rect = {0, 0, 100, 2};
-
- rtgui_widget_set_rect(RTGUI_WIDGET(staticline), &rect);
- staticline->orient= RTGUI_HORIZONTAL;
-
- rtgui_widget_set_event_handler(RTGUI_WIDGET(staticline), rtgui_staticline_event_handler);
-}
-
-
-DEFINE_CLASS_TYPE(staticline, "staticline",
- RTGUI_WIDGET_TYPE,
- _rtgui_staticline_constructor,
- RT_NULL,
- sizeof(struct rtgui_staticline));
-
-rt_bool_t rtgui_staticline_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_staticline* staticline;
- RT_ASSERT(widget != RT_NULL);
-
- staticline = (struct rtgui_staticline*) 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_theme_draw_staticline(staticline);
- break;
- }
-
- return RT_FALSE;
-}
-
-rtgui_staticline_t * rtgui_staticline_create(int orientation)
-{
- rtgui_staticline_t* staticline;
-
- staticline = (struct rtgui_staticline*) rtgui_widget_create(RTGUI_STATICLINE_TYPE);
- if (staticline!= RT_NULL)
- {
- rtgui_staticline_set_orientation(staticline, orientation);
- }
-
- return staticline;
-}
-
-void rtgui_staticline_destroy(rtgui_staticline_t* staticline)
-{
- rtgui_widget_destroy(RTGUI_WIDGET(staticline));
-}
-
-void rtgui_staticline_set_orientation(rtgui_staticline_t* staticline, int orientation)
-{
- RT_ASSERT(staticline != RT_NULL);
-
- staticline->orient = orientation;
-#ifndef RTGUI_USING_SMALL_SIZE
- if (orientation == RTGUI_HORIZONTAL)
- {
- /* HORIZONTAL */
- rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 2);
- rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 100);
- }
- else
- {
- /* VERTICAL */
- rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 2);
- rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 100);
- }
-#endif
-}
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/staticline.h>
+
+static void _rtgui_staticline_constructor(rtgui_staticline_t *staticline)
+{
+ /* init widget and set event handler */
+ rtgui_rect_t rect = {0, 0, 100, 2};
+
+ rtgui_widget_set_rect(RTGUI_WIDGET(staticline), &rect);
+ staticline->orient= RTGUI_HORIZONTAL;
+
+ rtgui_object_set_event_handler(RTGUI_OBJECT(staticline), rtgui_staticline_event_handler);
+}
+
+
+DEFINE_CLASS_TYPE(staticline, "staticline",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_staticline_constructor,
+ RT_NULL,
+ sizeof(struct rtgui_staticline));
+
+rt_bool_t rtgui_staticline_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_staticline* staticline;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ staticline = RTGUI_STATICLINE(object);
+ 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_theme_draw_staticline(staticline);
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+rtgui_staticline_t * rtgui_staticline_create(int orientation)
+{
+ rtgui_staticline_t* staticline;
+
+ staticline = (struct rtgui_staticline*) rtgui_widget_create(RTGUI_STATICLINE_TYPE);
+ if (staticline!= RT_NULL)
+ {
+ rtgui_staticline_set_orientation(staticline, orientation);
+ }
+
+ return staticline;
+}
+
+void rtgui_staticline_destroy(rtgui_staticline_t* staticline)
+{
+ rtgui_widget_destroy(RTGUI_WIDGET(staticline));
+}
+
+void rtgui_staticline_set_orientation(rtgui_staticline_t* staticline, int orientation)
+{
+ RT_ASSERT(staticline != RT_NULL);
+
+ staticline->orient = orientation;
+#ifndef RTGUI_USING_SMALL_SIZE
+ if (orientation == RTGUI_HORIZONTAL)
+ {
+ /* HORIZONTAL */
+ rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 2);
+ rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 100);
+ }
+ else
+ {
+ /* VERTICAL */
+ rtgui_widget_set_miniwidth(RTGUI_WIDGET(staticline), 2);
+ rtgui_widget_set_miniheight(RTGUI_WIDGET(staticline), 100);
+ }
+#endif
+}
diff --git a/components/rtgui/widgets/textbox.c b/components/rtgui/widgets/textbox.c
index 4bbaaed615..15f2bd44ef 100644
--- a/components/rtgui/widgets/textbox.c
+++ b/components/rtgui/widgets/textbox.c
@@ -25,13 +25,13 @@
#define RTGUI_TEXTBOX_MARGIN 3
static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event);
-static rt_bool_t rtgui_textbox_onfocus(struct rtgui_widget* widget, struct rtgui_event* event);
-static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_widget* widget, struct rtgui_event* event);
+static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event);
+static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event);
static void _rtgui_textbox_caret_timeout(struct rtgui_timer* timer, void* parameter)
{
rtgui_textbox_t* box;
-
+
box = (rtgui_textbox_t*)parameter;
/* set caret flag */
if (box->flag & RTGUI_TEXTBOX_CARET_SHOW)
@@ -51,7 +51,7 @@ static void _rtgui_textbox_constructor(rtgui_textbox_t *box)
rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
- rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_textbox_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_textbox_event_handler);
rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus);
rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus);
@@ -226,10 +226,12 @@ static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kb
rtgui_theme_draw_textbox(box);
}
-static rt_bool_t rtgui_textbox_onfocus(struct rtgui_widget* widget, struct rtgui_event* event)
+static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event)
{
- struct rtgui_textbox* box = (struct rtgui_textbox*)widget;
+ struct rtgui_textbox* box;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+ box = RTGUI_TEXTBOX(object);
/* set caret to show */
box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
/* start caret timer */
@@ -238,10 +240,12 @@ static rt_bool_t rtgui_textbox_onfocus(struct rtgui_widget* widget, struct rtgui
return RT_TRUE;
}
-static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_widget* widget, struct rtgui_event* event)
+static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event)
{
- struct rtgui_textbox* box = (struct rtgui_textbox*)widget;
+ struct rtgui_textbox* box;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+ box = RTGUI_TEXTBOX(object);
/* stop caret timer */
rtgui_timer_stop(box->caret_timer);
/* set caret to hide */
@@ -250,10 +254,12 @@ static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_widget* widget, struct rtg
return RT_TRUE;
}
-rt_bool_t rtgui_textbox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{
- struct rtgui_textbox* box = (struct rtgui_textbox*)widget;
+ struct rtgui_textbox* box;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+ box = RTGUI_TEXTBOX(object);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
diff --git a/components/rtgui/widgets/textview.c b/components/rtgui/widgets/textview.c
index 2bb7a41e1d..fe57b82ab2 100644
--- a/components/rtgui/widgets/textview.c
+++ b/components/rtgui/widgets/textview.c
@@ -1,352 +1,351 @@
-/*
- * File : textview.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2011-03-05 Bernard first version
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/textview.h>
-
-rt_inline char* _get_line_text(rtgui_textview_t *textview, rt_uint16_t index)
-{
- char* line;
- if (index < textview->line_count)
- {
- line = textview->lines + (index * textview->line_width);
- return line;
- }
-
- return RT_NULL;
-}
-
-static void _calc_line(rtgui_textview_t *textview, const char* text)
-{
- char* line;
- const unsigned char* ptr;
- rt_ubase_t line_index, line_position;
-
- if (textview->lines != RT_NULL)
- {
- rt_free(textview->lines);
- textview->lines = RT_NULL;
- textview->line_count = 0;
- }
-
- /* get line count */
- line_index = 0; line_position = 0;
- ptr = (const unsigned char*)text;
- if (*ptr == 0) return;
-
- while (*ptr != '\0')
- {
- if (*ptr == '\n')
- {
- line_index ++;
- line_position = 0;
- }
- else if (*ptr == '\r')
- {
- ptr ++;
- continue;
- }
- else if (*ptr == '\t')
- {
- line_position += 4;
- if (line_position >= textview->line_width - 1)
- {
- line_index ++;
- line_position = 0;
- }
- }
- else
- {
- if ((*ptr) >= 0x80)
- {
- /* fill cjk character */
- if (line_position + 1 >= (textview->line_width - 1))
- {
- /* split to next line */
- line_index ++;
- line_position = 0;
- }
-
- line_position ++;
- line_position ++;
- }
- else
- {
- line_position ++;
- }
-
- if (line_position >= textview->line_width - 1)
- {
- line_index ++;
- line_position = 0;
- }
- }
-
- ptr ++;
- }
-
- /* set line count */
- textview->line_count = line_index + 1;
-
- /* allocate lines */
- textview->lines = rt_malloc(textview->line_count * textview->line_width);
- rt_memset(textview->lines, 0, (textview->line_count * textview->line_width));
-
- /* fill lines */
- line_index = 0; line_position = 0;
- ptr = (const unsigned char*)text;
- line = _get_line_text(textview, line_index);
- while (*ptr)
- {
- if (*ptr == '\n')
- {
- line_index ++;
- line_position = 0;
- line = _get_line_text(textview, line_index);
- }
- else if (*ptr == '\r')
- {
- /* ignore '\r' */
- ptr ++;
- continue;
- }
- else if (*ptr == '\t')
- {
- line[line_position++] = ' ';
- line[line_position++] = ' ';
- line[line_position++] = ' ';
- line[line_position++] = ' ';
- if (line_position >= textview->line_width - 1)
- {
- line_index ++;
- line_position = 0;
- line = _get_line_text(textview, line_index);
- }
- }
- else
- {
- if ((*ptr) >= 0x80)
- {
- /* fill cjk character */
- if (line_position + 1 >= (textview->line_width - 1))
- {
- /* split to next line */
- line_index ++;
- line_position = 0;
- line = _get_line_text(textview, line_index);
- }
-
- line[line_position ++] = *ptr ++;
- line[line_position ++] = *ptr;
- }
- else
- {
- line[line_position ++] = *ptr;
- }
-
- if (line_position >= textview->line_width - 1)
- {
- line_index ++;
- line_position = 0;
- line = _get_line_text(textview, line_index);
- }
- }
-
- ptr ++;
- }
-
- textview->line_current = 0;
-}
-
-static void _calc_width(rtgui_textview_t *textview)
-{
- rtgui_rect_t rect;
- rt_uint16_t width, height;
-
- width = rtgui_rect_width(RTGUI_WIDGET(textview)->extent) - 6;
- height = rtgui_rect_height(RTGUI_WIDGET(textview)->extent);
-
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &rect);
- textview->line_width = width / rtgui_rect_width(rect) + 1;
- textview->line_page_count = height / (rtgui_rect_height(rect) + 3);
-
- /* set minimal value */
- if (textview->line_page_count == 0) textview->line_page_count = 1;
-}
-
-static void _draw_textview(rtgui_textview_t *textview)
-{
- struct rtgui_dc* dc;
- struct rtgui_rect rect, font_rect;
- char* line;
- rt_ubase_t line_index, item_height;
-
- rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &font_rect);
- item_height = rtgui_rect_height(font_rect) + 3;
-
- dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(textview));
- if (dc == RT_NULL) return ;
-
- /* fill rect */
- rtgui_widget_get_rect(RTGUI_WIDGET(textview), &rect);
- rtgui_dc_fill_rect(dc, &rect);
-
- rect.x1 += 3;
- rect.x2 -= 3;
-
- for (line_index = textview->line_current;
- (line_index < textview->line_current + textview->line_page_count) &&
- (line_index < textview->line_count);
- line_index ++)
- {
- line = (char* )_get_line_text(textview, line_index);
- rtgui_dc_draw_text(dc, line, &rect);
-
- rect.y1 += item_height;
- }
-
- rtgui_dc_end_drawing(dc);
-}
-
-static void _rtgui_textview_constructor(rtgui_textview_t *textview)
-{
- /* init widget and set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(textview), rtgui_textview_event_handler);
- RTGUI_WIDGET(textview)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
-
- /* set field */
- textview->line_count = 0;
- textview->lines = RT_NULL;
-
- textview->line_current = -1;
- textview->line_page_count = 1;
-}
-
-static void _rtgui_textview_destructor(rtgui_textview_t *textview)
-{
- /* release line memory */
- rt_free(textview->lines);
- textview->lines = RT_NULL;
-}
-
-DEFINE_CLASS_TYPE(textview, "textview",
- RTGUI_WIDGET_TYPE,
- _rtgui_textview_constructor,
- _rtgui_textview_destructor,
- sizeof(struct rtgui_textview));
-
-rt_bool_t rtgui_textview_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_textview* textview;
-
- RT_ASSERT(widget != RT_NULL);
-
- textview = (struct rtgui_textview*) widget;
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- _draw_textview(textview);
- break;
-
- case RTGUI_EVENT_KBD:
- {
- struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
- if (ekbd->type == RTGUI_KEYDOWN)
- {
- rt_int16_t line_current_update;
- line_current_update = textview->line_current;
- if (ekbd->key == RTGUIK_LEFT)
- {
- if (textview->line_current > textview->line_page_count)
- {
- line_current_update -= textview->line_page_count;
- }
- else if (textview->line_current > 0)
- {
- line_current_update = 0;
- }
- }
- else if (ekbd->key == RTGUIK_RIGHT)
- {
- if (textview->line_current + textview->line_page_count < textview->line_count - 1)
- {
- line_current_update += textview->line_page_count;
- }
- }
- else if (ekbd->key == RTGUIK_UP)
- {
- if (textview->line_current > 0)
- {
- line_current_update --;
- }
- }
- else if (ekbd->key == RTGUIK_DOWN)
- {
- if (textview->line_current + textview->line_page_count < textview->line_count - 1)
- {
- line_current_update ++;
- }
- }
-
- if (textview->line_current != line_current_update)
- {
- textview->line_current = line_current_update;
- rtgui_widget_update(widget);
- return RT_TRUE;
- }
- }
- break;
- }
- }
-
- return RT_FALSE;
-}
-
-rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect)
-{
- struct rtgui_textview* textview;
-
- textview = (struct rtgui_textview*) rtgui_widget_create(RTGUI_TEXTVIEW_TYPE);
- if (textview != RT_NULL)
- {
- rtgui_widget_set_rect(RTGUI_WIDGET(textview), rect);
-
- /* calculate line width and line page count */
- _calc_width(textview);
-
- /* set text */
- _calc_line(textview, text);
- }
-
- return textview;
-}
-
-void rtgui_textview_destroy(rtgui_textview_t* textview)
-{
- rtgui_widget_destroy(RTGUI_WIDGET(textview));
-}
-
-void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text)
-{
- RT_ASSERT(textview != RT_NULL);
-
- /* calculate line width and line page count */
- _calc_width(textview);
-
- /* set text */
- _calc_line(textview, text);
-
- /* update widget */
- rtgui_widget_update(RTGUI_WIDGET(textview));
-}
+/*
+ * File : textview.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2011, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2011-03-05 Bernard first version
+ */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/textview.h>
+
+rt_inline char* _get_line_text(rtgui_textview_t *textview, rt_uint16_t index)
+{
+ char* line;
+ if (index < textview->line_count)
+ {
+ line = textview->lines + (index * textview->line_width);
+ return line;
+ }
+
+ return RT_NULL;
+}
+
+static void _calc_line(rtgui_textview_t *textview, const char* text)
+{
+ char* line;
+ const unsigned char* ptr;
+ rt_ubase_t line_index, line_position;
+
+ if (textview->lines != RT_NULL)
+ {
+ rt_free(textview->lines);
+ textview->lines = RT_NULL;
+ textview->line_count = 0;
+ }
+
+ /* get line count */
+ line_index = 0; line_position = 0;
+ ptr = (const unsigned char*)text;
+ if (*ptr == 0) return;
+
+ while (*ptr != '\0')
+ {
+ if (*ptr == '\n')
+ {
+ line_index ++;
+ line_position = 0;
+ }
+ else if (*ptr == '\r')
+ {
+ ptr ++;
+ continue;
+ }
+ else if (*ptr == '\t')
+ {
+ line_position += 4;
+ if (line_position >= textview->line_width - 1)
+ {
+ line_index ++;
+ line_position = 0;
+ }
+ }
+ else
+ {
+ if ((*ptr) >= 0x80)
+ {
+ /* fill cjk character */
+ if (line_position + 1 >= (textview->line_width - 1))
+ {
+ /* split to next line */
+ line_index ++;
+ line_position = 0;
+ }
+
+ line_position ++;
+ line_position ++;
+ }
+ else
+ {
+ line_position ++;
+ }
+
+ if (line_position >= textview->line_width - 1)
+ {
+ line_index ++;
+ line_position = 0;
+ }
+ }
+
+ ptr ++;
+ }
+
+ /* set line count */
+ textview->line_count = line_index + 1;
+
+ /* allocate lines */
+ textview->lines = rt_malloc(textview->line_count * textview->line_width);
+ rt_memset(textview->lines, 0, (textview->line_count * textview->line_width));
+
+ /* fill lines */
+ line_index = 0; line_position = 0;
+ ptr = (const unsigned char*)text;
+ line = _get_line_text(textview, line_index);
+ while (*ptr)
+ {
+ if (*ptr == '\n')
+ {
+ line_index ++;
+ line_position = 0;
+ line = _get_line_text(textview, line_index);
+ }
+ else if (*ptr == '\r')
+ {
+ /* ignore '\r' */
+ ptr ++;
+ continue;
+ }
+ else if (*ptr == '\t')
+ {
+ line[line_position++] = ' ';
+ line[line_position++] = ' ';
+ line[line_position++] = ' ';
+ line[line_position++] = ' ';
+ if (line_position >= textview->line_width - 1)
+ {
+ line_index ++;
+ line_position = 0;
+ line = _get_line_text(textview, line_index);
+ }
+ }
+ else
+ {
+ if ((*ptr) >= 0x80)
+ {
+ /* fill cjk character */
+ if (line_position + 1 >= (textview->line_width - 1))
+ {
+ /* split to next line */
+ line_index ++;
+ line_position = 0;
+ line = _get_line_text(textview, line_index);
+ }
+
+ line[line_position ++] = *ptr ++;
+ line[line_position ++] = *ptr;
+ }
+ else
+ {
+ line[line_position ++] = *ptr;
+ }
+
+ if (line_position >= textview->line_width - 1)
+ {
+ line_index ++;
+ line_position = 0;
+ line = _get_line_text(textview, line_index);
+ }
+ }
+
+ ptr ++;
+ }
+
+ textview->line_current = 0;
+}
+
+static void _calc_width(rtgui_textview_t *textview)
+{
+ rtgui_rect_t rect;
+ rt_uint16_t width, height;
+
+ width = rtgui_rect_width(RTGUI_WIDGET(textview)->extent) - 6;
+ height = rtgui_rect_height(RTGUI_WIDGET(textview)->extent);
+
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &rect);
+ textview->line_width = width / rtgui_rect_width(rect) + 1;
+ textview->line_page_count = height / (rtgui_rect_height(rect) + 3);
+
+ /* set minimal value */
+ if (textview->line_page_count == 0) textview->line_page_count = 1;
+}
+
+static void _draw_textview(rtgui_textview_t *textview)
+{
+ struct rtgui_dc* dc;
+ struct rtgui_rect rect, font_rect;
+ char* line;
+ rt_ubase_t line_index, item_height;
+
+ rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &font_rect);
+ item_height = rtgui_rect_height(font_rect) + 3;
+
+ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(textview));
+ if (dc == RT_NULL) return ;
+
+ /* fill rect */
+ rtgui_widget_get_rect(RTGUI_WIDGET(textview), &rect);
+ rtgui_dc_fill_rect(dc, &rect);
+
+ rect.x1 += 3;
+ rect.x2 -= 3;
+
+ for (line_index = textview->line_current;
+ (line_index < textview->line_current + textview->line_page_count) &&
+ (line_index < textview->line_count);
+ line_index ++)
+ {
+ line = (char* )_get_line_text(textview, line_index);
+ rtgui_dc_draw_text(dc, line, &rect);
+
+ rect.y1 += item_height;
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+static void _rtgui_textview_constructor(rtgui_textview_t *textview)
+{
+ /* init widget and set event handler */
+ rtgui_object_set_event_handler(RTGUI_OBJECT(textview), rtgui_textview_event_handler);
+ RTGUI_WIDGET(textview)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ /* set field */
+ textview->line_count = 0;
+ textview->lines = RT_NULL;
+
+ textview->line_current = -1;
+ textview->line_page_count = 1;
+}
+
+static void _rtgui_textview_destructor(rtgui_textview_t *textview)
+{
+ /* release line memory */
+ rt_free(textview->lines);
+ textview->lines = RT_NULL;
+}
+
+DEFINE_CLASS_TYPE(textview, "textview",
+ RTGUI_WIDGET_TYPE,
+ _rtgui_textview_constructor,
+ _rtgui_textview_destructor,
+ sizeof(struct rtgui_textview));
+
+rt_bool_t rtgui_textview_event_handler(struct rtgui_object* object, struct rtgui_event* event)
+{
+ struct rtgui_textview* textview;
+ RTGUI_WIDGET_EVENT_HANDLER_PREPARE
+
+ textview = RTGUI_TEXTVIEW(object);
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ _draw_textview(textview);
+ break;
+
+ case RTGUI_EVENT_KBD:
+ {
+ struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
+ if (ekbd->type == RTGUI_KEYDOWN)
+ {
+ rt_int16_t line_current_update;
+ line_current_update = textview->line_current;
+ if (ekbd->key == RTGUIK_LEFT)
+ {
+ if (textview->line_current > textview->line_page_count)
+ {
+ line_current_update -= textview->line_page_count;
+ }
+ else if (textview->line_current > 0)
+ {
+ line_current_update = 0;
+ }
+ }
+ else if (ekbd->key == RTGUIK_RIGHT)
+ {
+ if (textview->line_current + textview->line_page_count < textview->line_count - 1)
+ {
+ line_current_update += textview->line_page_count;
+ }
+ }
+ else if (ekbd->key == RTGUIK_UP)
+ {
+ if (textview->line_current > 0)
+ {
+ line_current_update --;
+ }
+ }
+ else if (ekbd->key == RTGUIK_DOWN)
+ {
+ if (textview->line_current + textview->line_page_count < textview->line_count - 1)
+ {
+ line_current_update ++;
+ }
+ }
+
+ if (textview->line_current != line_current_update)
+ {
+ textview->line_current = line_current_update;
+ rtgui_widget_update(widget);
+ return RT_TRUE;
+ }
+ }
+ break;
+ }
+ }
+
+ return RT_FALSE;
+}
+
+rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect)
+{
+ struct rtgui_textview* textview;
+
+ textview = (struct rtgui_textview*) rtgui_widget_create(RTGUI_TEXTVIEW_TYPE);
+ if (textview != RT_NULL)
+ {
+ rtgui_widget_set_rect(RTGUI_WIDGET(textview), rect);
+
+ /* calculate line width and line page count */
+ _calc_width(textview);
+
+ /* set text */
+ _calc_line(textview, text);
+ }
+
+ return textview;
+}
+
+void rtgui_textview_destroy(rtgui_textview_t* textview)
+{
+ rtgui_widget_destroy(RTGUI_WIDGET(textview));
+}
+
+void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text)
+{
+ RT_ASSERT(textview != RT_NULL);
+
+ /* calculate line width and line page count */
+ _calc_width(textview);
+
+ /* set text */
+ _calc_line(textview, text);
+
+ /* update widget */
+ rtgui_widget_update(RTGUI_WIDGET(textview));
+}
diff --git a/components/rtgui/widgets/toplevel.c b/components/rtgui/widgets/toplevel.c
index eeabcf09a8..b6882e7c3b 100644
--- a/components/rtgui/widgets/toplevel.c
+++ b/components/rtgui/widgets/toplevel.c
@@ -13,26 +13,25 @@
*/
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/toplevel.h>
-extern void rtgui_topwin_do_clip(rtgui_widget_t* widget);
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/title.h>
static void _rtgui_toplevel_constructor(rtgui_toplevel_t *toplevel)
{
/* set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(toplevel), rtgui_toplevel_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(toplevel), rtgui_toplevel_event_handler);
/* set toplevel to self */
- RTGUI_WIDGET(toplevel)->toplevel = RTGUI_WIDGET(toplevel);
+ if (RTGUI_IS_WINTITLE(toplevel))
+ RTGUI_WIDGET(toplevel)->toplevel = (struct rtgui_win*)toplevel;
+ else
+ RTGUI_WIDGET(toplevel)->toplevel = RTGUI_WIN(toplevel);
/* init toplevel property */
toplevel->drawing = 0;
/* hide toplevel default */
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(toplevel));
-
- /* set server as RT_NULL (no connected) */
- toplevel->server = RT_NULL;
- /* initialize last mouse event handled widget */
- toplevel->last_mevent_widget = RT_NULL;
}
static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)
@@ -41,51 +40,35 @@ static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel)
toplevel->drawing = 0;
}
-DEFINE_CLASS_TYPE(toplevel, "toplevel",
+DEFINE_CLASS_TYPE(toplevel, "toplevel",
RTGUI_CONTAINER_TYPE,
_rtgui_toplevel_constructor,
_rtgui_toplevel_destructor,
sizeof(struct rtgui_toplevel));
-rt_bool_t rtgui_toplevel_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_toplevel_event_handler(struct rtgui_object* object, rtgui_event_t* event)
{
- rtgui_toplevel_t* toplevel = (rtgui_toplevel_t*)widget;
+ struct rtgui_toplevel* toplevel;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ toplevel = RTGUI_TOPLEVEL(object);
switch (event->type)
{
- case RTGUI_EVENT_KBD:
- if (RTGUI_CONTAINER(toplevel)->focused != RT_NULL)
- {
- RTGUI_CONTAINER(toplevel)->focused->event_handler(RTGUI_CONTAINER(toplevel)->focused, event);
- }
- break;
-
case RTGUI_EVENT_CLIP_INFO:
/* update toplevel clip */
rtgui_toplevel_update_clip(toplevel);
break;
- case RTGUI_EVENT_TIMER:
- {
- struct rtgui_timer* timer;
- struct rtgui_event_timer* etimer = (struct rtgui_event_timer*) event;
-
- timer = etimer->timer;
- if (timer->timeout != RT_NULL)
- {
- /* call timeout function */
- timer->timeout(timer, timer->user_data);
- }
- }
- break;
-
case RTGUI_EVENT_COMMAND:
- if (rtgui_container_dispatch_event(RTGUI_CONTAINER(widget), event) != RT_TRUE)
+ if (rtgui_container_dispatch_event(RTGUI_CONTAINER(object), event) != RT_TRUE)
{
#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_command != RT_NULL)
+ if (RTGUI_WIDGET(object)->on_command != RT_NULL)
{
- widget->on_command(widget, event);
+ RTGUI_WIDGET(object)->on_command(object, event);
}
#endif
}
@@ -93,38 +76,23 @@ rt_bool_t rtgui_toplevel_event_handler(rtgui_widget_t* widget, rtgui_event_t* ev
break;
default :
- return rtgui_container_event_handler(widget, event);
+ return rtgui_container_event_handler(object, event);
}
return RT_FALSE;
}
-#include <rtgui/driver.h> /* to get screen rect */
-
void rtgui_toplevel_update_clip(rtgui_toplevel_t* top)
{
- rtgui_container_t* container;
+ rtgui_container_t* view;
struct rtgui_list_node* node;
- rtgui_rect_t screen_rect;
-
- if (top == RT_NULL) return;
-
- /* reset toplevel widget clip to extent */
- rtgui_region_reset(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->extent));
-
- /* subtract the screen rect */
- screen_rect.x1 = screen_rect.y1 = 0;
- screen_rect.x2 = rtgui_graphic_driver_get_default()->width;
- screen_rect.y2 = rtgui_graphic_driver_get_default()->height;
- rtgui_region_intersect_rect(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->clip),
- &screen_rect);
- /* subtract the external rect */
- rtgui_topwin_do_clip(RTGUI_WIDGET(top));
+ if (top == RT_NULL)
+ return;
/* update the clip info of each child */
- container = RTGUI_CONTAINER(top);
- rtgui_list_foreach(node, &(container->children))
+ view = RTGUI_CONTAINER(top);
+ rtgui_list_foreach(node, &(view->children))
{
rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
diff --git a/components/rtgui/widgets/view.c b/components/rtgui/widgets/view.c
deleted file mode 100644
index 0f35f42eb4..0000000000
--- a/components/rtgui/widgets/view.c
+++ /dev/null
@@ -1,214 +0,0 @@
-/*
- * File : view.c
- * This file is part of RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2009-10-16 Bernard first version
- * 2010-09-24 Bernard fix view destroy issue
- */
-#include <rtgui/dc.h>
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/view.h>
-#include <rtgui/widgets/workbench.h>
-
-static void _rtgui_view_constructor(rtgui_view_t *view)
-{
- /* init view */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(view),
- rtgui_view_event_handler);
-
- view->modal_show = RT_FALSE;
- view->title = RT_NULL;
-}
-
-static void _rtgui_view_destructor(rtgui_view_t *view)
-{
- /* remove view from workbench */
- if (RTGUI_WIDGET(view)->parent != RT_NULL)
- {
- rtgui_workbench_t *workbench;
-
- if (view->modal_show == RT_TRUE)
- rtgui_view_end_modal(view, RTGUI_MODAL_CANCEL);
-
- workbench = RTGUI_WORKBENCH(RTGUI_WIDGET(view)->parent);
- rtgui_workbench_remove_view(workbench, view);
- }
-
- if (view->title != RT_NULL)
- {
- rt_free(view->title);
- view->title = RT_NULL;
- }
-}
-
-DEFINE_CLASS_TYPE(view, "view",
- RTGUI_CONTAINER_TYPE,
- _rtgui_view_constructor,
- _rtgui_view_destructor,
- sizeof(struct rtgui_view));
-
-rt_bool_t rtgui_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
-{
- struct rtgui_view* view = (struct rtgui_view*) widget;
- RT_ASSERT(widget != RT_NULL);
-
- switch (event->type)
- {
- case RTGUI_EVENT_PAINT:
- {
- struct rtgui_dc* dc;
- struct rtgui_rect rect;
-
- dc = rtgui_dc_begin_drawing(widget);
- if (dc == RT_NULL) return RT_FALSE;
- rtgui_widget_get_rect(widget, &rect);
-
- /* fill view with background */
- rtgui_dc_fill_rect(dc, &rect);
-
- /* paint on each child */
- rtgui_container_dispatch_event(RTGUI_CONTAINER(view), event);
-
- rtgui_dc_end_drawing(dc);
- }
- break;
-
- default:
- return rtgui_container_event_handler(widget, event);
- }
-
- return RT_FALSE;
-}
-
-rtgui_view_t* rtgui_view_create(const char* title)
-{
- struct rtgui_view* view;
-
- /* allocate view */
- view = (struct rtgui_view*) rtgui_widget_create (RTGUI_VIEW_TYPE);
- if (view != RT_NULL)
- {
- if (title != RT_NULL)
- view->title = rt_strdup(title);
- }
-
- return view;
-}
-
-void rtgui_view_destroy(rtgui_view_t* view)
-{
- if (view->modal_show == RT_TRUE)
- rtgui_view_end_modal(view, RTGUI_MODAL_CANCEL);
- else
- {
- rtgui_view_hide(view);
- rtgui_widget_destroy(RTGUI_WIDGET(view));
- }
-}
-
-#ifndef RTGUI_USING_SMALL_SIZE
-void rtgui_view_set_box(rtgui_view_t* view, rtgui_box_t* box)
-{
- if (view == RT_NULL ||
- box == RT_NULL) return;
-
- rtgui_container_add_child(RTGUI_CONTAINER(view), RTGUI_WIDGET(box));
- rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(view)->extent));
-}
-#endif
-
-rtgui_modal_code_t rtgui_view_show(rtgui_view_t* view, rt_bool_t is_modal)
-{
- rtgui_workbench_t* workbench;
-
- /* parameter check */
- if (view == RT_NULL) return RTGUI_MODAL_CANCEL;
-
- if (RTGUI_WIDGET(view)->parent == RT_NULL)
- {
- RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(view));
- return RTGUI_MODAL_CANCEL;
- }
-
- workbench = RTGUI_WORKBENCH(RTGUI_WIDGET(view)->parent);
- rtgui_workbench_show_view(workbench, view);
- if (RTGUI_CONTAINER(view)->focused != RT_NULL)
- rtgui_widget_focus(RTGUI_CONTAINER(view)->focused);
- else
- {
- if (RTGUI_WIDGET_IS_FOCUSABLE(RTGUI_WIDGET(view)))
- rtgui_widget_focus(RTGUI_WIDGET(view));
- }
-
- view->modal_show = is_modal;
- if (is_modal == RT_TRUE)
- {
- /* set modal mode */
- workbench->flag |= RTGUI_WORKBENCH_FLAG_MODAL_MODE;
- workbench->modal_widget = RTGUI_WIDGET(view);
-
- /* perform workbench event loop */
- rtgui_workbench_event_loop(workbench);
-
- workbench->modal_widget = RT_NULL;
- return workbench->modal_code;
- }
-
- /* no modal mode, always return modal_ok */
- return RTGUI_MODAL_OK;
-}
-
-void rtgui_view_end_modal(rtgui_view_t* view, rtgui_modal_code_t modal_code)
-{
- rtgui_workbench_t* workbench;
-
- /* parameter check */
- if ((view == RT_NULL) || (RTGUI_WIDGET(view)->parent == RT_NULL))return ;
-
- workbench = RTGUI_WORKBENCH(RTGUI_WIDGET(view)->parent);
- workbench->modal_code = modal_code;
- workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
-
- /* remove modal mode */
- view->modal_show = RT_FALSE;
-}
-
-void rtgui_view_hide(rtgui_view_t* view)
-{
- if (view == RT_NULL) return;
-
- if (RTGUI_WIDGET(view)->parent == RT_NULL)
- {
- RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view));
- return;
- }
-
- rtgui_workbench_hide_view((rtgui_workbench_t*)(RTGUI_WIDGET(view)->parent), view);
-}
-
-char* rtgui_view_get_title(rtgui_view_t* view)
-{
- RT_ASSERT(view != RT_NULL);
-
- return view->title;
-}
-
-void rtgui_view_set_title(rtgui_view_t* view, const char *title)
-{
- RT_ASSERT(view != RT_NULL);
-
- if (view->title != RT_NULL)
- {
- rtgui_free(view->title);
-
- if (title != RT_NULL) view->title = rt_strdup(title);
- else view->title = RT_NULL;
- }
-}
diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c
index 91a14ac27e..e639eb8bed 100644
--- a/components/rtgui/widgets/widget.c
+++ b/components/rtgui/widgets/widget.c
@@ -14,10 +14,11 @@
*/
#include <rtgui/dc_client.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/widget.h>
#include <rtgui/widgets/window.h>
-#include <rtgui/widgets/view.h>
-extern void rtgui_topwin_do_clip(rtgui_widget_t* widget);
+#include <rtgui/widgets/container.h>
+#include <rtgui/widgets/notebook.h>
static void _rtgui_widget_constructor(rtgui_widget_t *widget)
{
@@ -40,23 +41,25 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
#endif
/* set parent and toplevel root */
- widget->parent = RT_NULL;
- widget->toplevel = RT_NULL;
+ widget->parent = RT_NULL;
+ widget->toplevel = RT_NULL;
/* some common event handler */
- widget->on_focus_in = RT_NULL;
- widget->on_focus_out = RT_NULL;
+ widget->on_focus_in = RT_NULL;
+ widget->on_focus_out = RT_NULL;
+ widget->on_show = RT_NULL;
+ widget->on_hide = RT_NULL;
#ifndef RTGUI_USING_SMALL_SIZE
- widget->on_draw = RT_NULL;
- widget->on_mouseclick = RT_NULL;
- widget->on_key = RT_NULL;
- widget->on_size = RT_NULL;
- widget->on_command = RT_NULL;
+ widget->on_draw = RT_NULL;
+ widget->on_mouseclick = RT_NULL;
+ widget->on_key = RT_NULL;
+ widget->on_size = RT_NULL;
+ widget->on_command = RT_NULL;
#endif
/* set default event handler */
- rtgui_widget_set_event_handler(widget,rtgui_widget_event_handler);
+ rtgui_object_set_event_handler(RTGUI_OBJECT(widget), rtgui_widget_event_handler);
/* init user data private to 0 */
widget->user_data = 0;
@@ -203,13 +206,6 @@ void rtgui_widget_move_to_logic(rtgui_widget_t* widget, int dx, int dy)
}
}
-void rtgui_widget_set_event_handler(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
-{
- RT_ASSERT(widget != RT_NULL);
-
- widget->event_handler = handler;
-}
-
void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect)
{
RT_ASSERT(widget != RT_NULL);
@@ -236,6 +232,20 @@ void rtgui_widget_set_onunfocus(rtgui_widget_t* widget, rtgui_event_handler_ptr
widget->on_focus_out = handler;
}
+void rtgui_widget_set_onshow(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
+{
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_show = handler;
+}
+
+void rtgui_widget_set_onhide(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
+{
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_hide = handler;
+}
+
#ifndef RTGUI_USING_SMALL_SIZE
void rtgui_widget_set_ondraw(rtgui_widget_t* widget, rtgui_event_handler_ptr handler)
{
@@ -280,35 +290,28 @@ void rtgui_widget_set_oncommand(rtgui_widget_t* widget, rtgui_event_handler_ptr
*/
void rtgui_widget_focus(rtgui_widget_t *widget)
{
- rtgui_container_t *parent;
+ struct rtgui_widget *old_focus;
RT_ASSERT(widget != RT_NULL);
- if (!widget->parent || !widget->toplevel) return;
if (!RTGUI_WIDGET_IS_FOCUSABLE(widget) || !RTGUI_WIDGET_IS_ENABLE(widget))
return;
- /* set widget as focused */
- widget->flag |= RTGUI_WIDGET_FLAG_FOCUS;
-
- /* get root parent container and old focused widget */
- parent = RTGUI_CONTAINER(widget->toplevel);
- if (parent->focused == widget) return ; /* it's the same focused widget */
+ old_focus = RTGUI_WIN(widget->toplevel)->focused_widget;
+ if (old_focus == widget)
+ return; /* it's the same focused widget */
/* unfocused the old widget */
- if (parent->focused != RT_NULL) rtgui_widget_unfocus(parent->focused);
+ if (old_focus != RT_NULL)
+ rtgui_widget_unfocus(old_focus);
- /* set widget as focused widget in parent link */
- parent = RTGUI_CONTAINER(widget->parent);
- do
- {
- parent->focused = widget;
- parent = RTGUI_CONTAINER(RTGUI_WIDGET(parent)->parent);
- } while ((parent != RT_NULL) && !RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(parent)));
+ /* set widget as focused */
+ widget->flag |= RTGUI_WIDGET_FLAG_FOCUS;
+ RTGUI_WIN(widget->toplevel)->focused_widget = widget;
/* invoke on focus in call back */
if (widget->on_focus_in != RT_NULL)
- widget->on_focus_in(widget, RT_NULL);
+ widget->on_focus_in(RTGUI_OBJECT(widget), RT_NULL);
}
/**
@@ -317,6 +320,7 @@ void rtgui_widget_focus(rtgui_widget_t *widget)
*/
void rtgui_widget_unfocus(rtgui_widget_t *widget)
{
+
RT_ASSERT(widget != RT_NULL);
if (!widget->toplevel || !RTGUI_WIDGET_IS_FOCUSED(widget))
@@ -325,7 +329,9 @@ void rtgui_widget_unfocus(rtgui_widget_t *widget)
widget->flag &= ~RTGUI_WIDGET_FLAG_FOCUS;
if (widget->on_focus_out != RT_NULL)
- widget->on_focus_out(widget, RT_NULL);
+ widget->on_focus_out(RTGUI_OBJECT(widget), RT_NULL);
+
+ RTGUI_WIN(widget->toplevel)->focused_widget = RT_NULL;
/* refresh widget */
rtgui_widget_update(widget);
@@ -381,47 +387,62 @@ void rtgui_widget_rect_to_logic(rtgui_widget_t* widget, rtgui_rect_t* rect)
}
}
-rtgui_widget_t* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
+struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
{
rtgui_widget_t* r;
RT_ASSERT(widget != RT_NULL);
- if (widget->toplevel) return widget->toplevel;
+ if (widget->toplevel)
+ return widget->toplevel;
+ rt_kprintf("widget->toplevel not properly set\n");
r = widget;
/* get the toplevel widget */
- while (r->parent != RT_NULL) r = r->parent;
+ while (r->parent != RT_NULL)
+ r = r->parent;
/* set toplevel */
- widget->toplevel = r;
+ widget->toplevel = RTGUI_WIN(r);
- return r;
+ return RTGUI_WIN(r);
}
-rt_bool_t rtgui_widget_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
+rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event)
{
#ifndef RTGUI_USING_SMALL_SIZE
+ struct rtgui_widget *widget;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ widget = RTGUI_WIDGET(object);
+
switch (event->type)
{
case RTGUI_EVENT_PAINT:
- if (widget->on_draw != RT_NULL) return widget->on_draw(widget, event);
+ if (widget->on_draw != RT_NULL)
+ return widget->on_draw(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_KBD:
- if (widget->on_key != RT_NULL) return widget->on_key(widget, event);
+ if (widget->on_key != RT_NULL)
+ return widget->on_key(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_MOUSE_BUTTON:
- if (widget->on_mouseclick != RT_NULL) return widget->on_mouseclick(widget, event);
+ if (widget->on_mouseclick != RT_NULL)
+ return widget->on_mouseclick(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_COMMAND:
- if (widget->on_command != RT_NULL) return widget->on_command(widget, event);
+ if (widget->on_command != RT_NULL)
+ return widget->on_command(RTGUI_OBJECT(widget), event);
break;
case RTGUI_EVENT_RESIZE:
- if (widget->on_size != RT_NULL) return widget->on_size(widget, event);
+ if (widget->on_size != RT_NULL)
+ return widget->on_size(RTGUI_OBJECT(widget), event);
break;
}
#endif
@@ -441,14 +462,9 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
if (widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
parent = widget->parent;
- /* if there is no parent, do not update clip (please use toplevel widget API) */
+ /* if there is no parent, there is no clip to update. */
if (parent == RT_NULL)
{
- if (RTGUI_IS_TOPLEVEL(widget))
- {
- /* if it's toplevel widget, update it by toplevel function */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(widget));
- }
return;
}
@@ -479,7 +495,7 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
* intersect.
*/
- /* if it's a container object, update the clip info of children */
+ /* if it's a view object, update the clip info of children */
if (RTGUI_IS_CONTAINER(widget))
{
rtgui_widget_t* child;
@@ -490,17 +506,25 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
rtgui_widget_update_clip(child);
}
}
+ else if (RTGUI_IS_NOTEBOOK(widget))
+ {
+ rtgui_widget_update_clip(rtgui_notebook_get_current(RTGUI_NOTEBOOK(widget)));
+ }
}
void rtgui_widget_show(rtgui_widget_t* widget)
{
/* there is no parent or the parent is hide, no show at all */
if (widget->parent == RT_NULL ||
- RTGUI_WIDGET_IS_HIDE(widget->parent)) return;
+ RTGUI_WIDGET_IS_HIDE(widget->parent))
+ return;
/* update the clip info of widget */
RTGUI_WIDGET_UNHIDE(widget);
rtgui_widget_update_clip(widget);
+
+ if (widget->on_show != RT_NULL)
+ widget->on_show(RTGUI_OBJECT(widget), RT_NULL);
}
void rtgui_widget_hide(rtgui_widget_t* widget)
@@ -521,10 +545,10 @@ void rtgui_widget_hide(rtgui_widget_t* widget)
/* union widget rect */
rtgui_region_union_rect(&(parent->clip), &(parent->clip), &(widget->extent));
-
- /* subtract the external rect */
- rtgui_topwin_do_clip(RTGUI_WIDGET(parent));
}
+
+ if (widget->on_hide != RT_NULL)
+ widget->on_hide(RTGUI_OBJECT(widget), RT_NULL);
}
rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget)
@@ -567,9 +591,11 @@ void rtgui_widget_update(rtgui_widget_t* widget)
RT_ASSERT(widget != RT_NULL);
- if (widget->event_handler != RT_NULL)
+ if (RTGUI_OBJECT(widget)->event_handler != RT_NULL)
{
- widget->event_handler(widget, &paint.parent);
+ RTGUI_OBJECT(widget)->event_handler(
+ RTGUI_OBJECT(widget),
+ &paint.parent);
}
}
@@ -617,11 +643,9 @@ void rtgui_widget_dump(rtgui_widget_t* widget)
obj = RTGUI_OBJECT(widget);
rt_kprintf("widget type: %s ", obj->type->name);
- if (RTGUI_IS_VIEW(widget) == RT_TRUE)
- rt_kprintf(":%s ", RTGUI_VIEW(widget)->title);
if (RTGUI_IS_WIN(widget) == RT_TRUE)
rt_kprintf(":%s ", RTGUI_WIN(widget)->title);
- if ((RTGUI_IS_LABEL(widget) == RT_TRUE) || (RTGUI_IS_BUTTON(widget) == RT_TRUE))
+ else if ((RTGUI_IS_LABEL(widget) == RT_TRUE) || (RTGUI_IS_BUTTON(widget) == RT_TRUE))
rt_kprintf(":%s ", RTGUI_LABEL(widget)->text);
rt_kprintf("extent(%d, %d) - (%d, %d)\n", widget->extent.x1,
diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c
index c1df9379ff..f8d5db3d24 100644
--- a/components/rtgui/widgets/window.c
+++ b/components/rtgui/widgets/window.c
@@ -15,27 +15,37 @@
#include <rtgui/color.h>
#include <rtgui/image.h>
#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_server.h>
+#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/window.h>
#include <rtgui/widgets/button.h>
-#include <rtgui/widgets/workbench.h>
static void _rtgui_win_constructor(rtgui_win_t *win)
{
+ RTGUI_WIDGET(win)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ win->parent_window = RT_NULL;
/* init window attribute */
- win->on_activate = RT_NULL;
- win->on_deactivate = RT_NULL;
- win->on_close = RT_NULL;
- win->title = RT_NULL;
- win->modal_code = RTGUI_MODAL_OK;
- win->modal_widget = RT_NULL;
+ win->on_activate = RT_NULL;
+ win->on_deactivate = RT_NULL;
+ win->on_close = RT_NULL;
+ win->on_key = RT_NULL;
+ win->title = RT_NULL;
+ win->modal_code = RTGUI_MODAL_OK;
+
+ /* initialize last mouse event handled widget */
+ win->last_mevent_widget = RT_NULL;
+ win->focused_widget = RT_NULL;
/* set window hide */
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
/* set window style */
win->style = RTGUI_WIN_STYLE_DEFAULT;
- rtgui_widget_set_event_handler(RTGUI_WIDGET(win), rtgui_win_event_handler);
+
+ win->flag = RTGUI_WIN_FLAG_INIT;
+
+ rtgui_object_set_event_handler(RTGUI_OBJECT(win), rtgui_win_event_handler);
/* init user data */
win->user_data = 0;
@@ -45,12 +55,12 @@ static void _rtgui_win_destructor(rtgui_win_t* win)
{
struct rtgui_event_win_destroy edestroy;
- if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
/* destroy in server */
RTGUI_EVENT_WIN_DESTROY_INIT(&edestroy);
edestroy.wid = win;
- if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&edestroy),
+ if (rtgui_server_post_event_sync(RTGUI_EVENT(&edestroy),
sizeof(struct rtgui_event_win_destroy)) != RT_EOK)
{
/* destroy in server failed */
@@ -62,225 +72,238 @@ static void _rtgui_win_destructor(rtgui_win_t* win)
rt_free(win->title);
}
-static rt_bool_t _rtgui_win_create_in_server(rtgui_win_t* win)
+static rt_bool_t _rtgui_win_create_in_server(struct rtgui_win *win)
{
- if (RTGUI_TOPLEVEL(win)->server == RT_NULL)
+ if (!(win->flag & RTGUI_WIN_FLAG_CONNECTED))
{
- rt_thread_t server;
struct rtgui_event_win_create ecreate;
RTGUI_EVENT_WIN_CREATE_INIT(&ecreate);
- /* get server thread id */
- server = rtgui_thread_get_server();
- if (server == RT_NULL)
- {
- rt_kprintf("RTGUI server is not running...\n");
- return RT_FALSE;
- }
-
/* send win create event to server */
- ecreate.wid = win;
- ecreate.parent.user = win->style;
+ ecreate.parent_window = win->parent_window;
+ ecreate.wid = win;
+ ecreate.parent.user = win->style;
#ifndef RTGUI_USING_SMALL_SIZE
- ecreate.extent = RTGUI_WIDGET(win)->extent;
+ ecreate.extent = RTGUI_WIDGET(win)->extent;
rt_strncpy((char*)ecreate.title, (char*)win->title, RTGUI_NAME_MAX);
#endif
- if (rtgui_thread_send_sync(server, RTGUI_EVENT(&ecreate),
- sizeof(struct rtgui_event_win_create)) != RT_EOK)
+ if (rtgui_server_post_event_sync(RTGUI_EVENT(&ecreate),
+ sizeof(struct rtgui_event_win_create)
+ ) != RT_EOK)
{
rt_kprintf("create win: %s failed\n", win->title);
return RT_FALSE;
}
- /* set server */
- RTGUI_TOPLEVEL(win)->server = server;
+ win->flag |= RTGUI_WIN_FLAG_CONNECTED;
}
return RT_TRUE;
}
-DEFINE_CLASS_TYPE(win, "win",
+DEFINE_CLASS_TYPE(win, "win",
RTGUI_TOPLEVEL_TYPE,
_rtgui_win_constructor,
_rtgui_win_destructor,
sizeof(struct rtgui_win));
-rtgui_win_t* rtgui_win_create(rtgui_toplevel_t* parent_toplevel, const char* title, rtgui_rect_t *rect, rt_uint8_t style)
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+static struct rtgui_win *the_desktop_window;
+#endif
+
+rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window,
+ const char* title,
+ rtgui_rect_t *rect,
+ rt_uint16_t style)
{
struct rtgui_win* win;
/* allocate win memory */
- win = (struct rtgui_win*) rtgui_widget_create (RTGUI_WIN_TYPE);
- if (win != RT_NULL)
+ win = RTGUI_WIN(rtgui_widget_create(RTGUI_WIN_TYPE));
+ if (win == RT_NULL)
+ return RT_NULL;
+
+ /* set parent toplevel */
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+ if (style & RTGUI_WIN_STYLE_DESKTOP)
{
- /* set parent toplevel */
- win->parent_toplevel = parent_toplevel;
+ RT_ASSERT(the_desktop_window == RT_NULL);
+ win->parent_window = RT_NULL;
+ the_desktop_window = win;
+ }
+ else if (parent_window == RT_NULL)
+ {
+ RT_ASSERT(the_desktop_window != RT_NULL);
+ win->parent_window = the_desktop_window;
+ }
+ else
+ win->parent_window = parent_window;
+#else
+ win->parent_window = parent_window;
+#endif
- /* set title, rect and style */
- if (title != RT_NULL) win->title = rt_strdup(title);
- else win->title = RT_NULL;
+ /* set title, rect and style */
+ if (title != RT_NULL)
+ win->title = rt_strdup(title);
+ else
+ win->title = RT_NULL;
- rtgui_widget_set_rect(RTGUI_WIDGET(win), rect);
- win->style = style;
+ rtgui_widget_set_rect(RTGUI_WIDGET(win), rect);
+ win->style = style;
- if (_rtgui_win_create_in_server(win) == RT_FALSE)
- {
- rtgui_widget_destroy(RTGUI_WIDGET(win));
- return RT_NULL;
- }
+ if (_rtgui_win_create_in_server(win) == RT_FALSE)
+ {
+ goto __on_err;
}
-
return win;
+
+__on_err:
+ rtgui_widget_destroy(RTGUI_WIDGET(win));
+ return RT_NULL;
}
void rtgui_win_destroy(struct rtgui_win* win)
{
- if (win->style & RTGUI_WIN_STYLE_MODAL)
+ if (win->flag & RTGUI_WIN_FLAG_MODAL)
{
- /* end modal */
+ /* set the RTGUI_WIN_STYLE_DESTROY_ON_CLOSE flag so the window will be
+ * destroyed after the event_loop */
+ win->style |= RTGUI_WIN_STYLE_DESTROY_ON_CLOSE;
rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
}
else
- {
rtgui_widget_destroy(RTGUI_WIDGET(win));
+}
+
+static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win,
+ struct rtgui_event *event)
+{
+ if (win->on_close != RT_NULL)
+ {
+ if (win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE)
+ return RT_FALSE;
+ }
+
+ rtgui_win_hiden(win);
+
+ win->flag |= RTGUI_WIN_FLAG_CLOSED;
+
+ if (win->flag & RTGUI_WIN_FLAG_MODAL)
+ {
+ rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
}
+ else if (win->style & RTGUI_WIN_STYLE_DESTROY_ON_CLOSE)
+ {
+ rtgui_win_destroy(win);
+ }
+
+ return RT_TRUE;
}
-void rtgui_win_close(struct rtgui_win* win)
+/* send a close event to myself to get a consistent behavior */
+rt_bool_t rtgui_win_close(struct rtgui_win* win)
{
- win->style |= RTGUI_WIN_STYLE_CLOSED;
+ struct rtgui_event_win_close eclose;
+
+ RTGUI_EVENT_WIN_CLOSE_INIT(&eclose);
+ eclose.wid = win;
+ return _rtgui_win_deal_close(win,
+ (struct rtgui_event*)&eclose);
}
-rtgui_modal_code_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
+rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
{
- rtgui_modal_code_t result;
+ struct rtgui_event_win_show eshow;
+ rt_base_t exit_code = -1;
- RT_ASSERT(win != RT_NULL);
- result = RTGUI_MODAL_CANCEL;
+ RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
+ eshow.wid = win;
+
+ if (win == RT_NULL)
+ return exit_code;
/* if it does not register into server, create it in server */
- if (RTGUI_TOPLEVEL(win)->server == RT_NULL)
+ if (!(win->flag & RTGUI_WIN_FLAG_CONNECTED))
{
if (_rtgui_win_create_in_server(win) == RT_FALSE)
- return result;
+ return exit_code;
}
- if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)))
+ if (rtgui_server_post_event_sync(RTGUI_EVENT(&eshow),
+ sizeof(struct rtgui_event_win_show)
+ ) != RT_EOK)
{
- /* send show message to server */
- struct rtgui_event_win_show eshow;
- RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
- eshow.wid = win;
+ rt_kprintf("show win failed\n");
+ return exit_code;
+ }
- if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&eshow),
- sizeof(struct rtgui_event_win_show)) != RT_EOK)
- {
- /* hide window failed */
- return result;
- }
+ /* set window unhidden */
+ RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
- /* set window unhidden */
- RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
- }
- else rtgui_widget_update(RTGUI_WIDGET(win));
+ if (win->focused_widget == RT_NULL)
+ rtgui_widget_focus(RTGUI_WIDGET(win));
- if (is_modal == RT_TRUE)
- {
- if (win->parent_toplevel != RT_NULL)
- {
- rtgui_widget_t *parent_widget;
+ if (is_modal == RT_TRUE)
+ {
+ struct rtgui_application *app;
+ struct rtgui_event_win_modal_enter emodal;
- /* set style */
- win->style |= RTGUI_WIN_STYLE_MODAL;
+ RTGUI_EVENT_WIN_MODAL_ENTER_INIT(&emodal);
+ emodal.wid = win;
- /* get root toplevel */
- parent_widget = RTGUI_WIDGET(win->parent_toplevel);
- if (RTGUI_IS_WORKBENCH(parent_widget))
- {
- rtgui_workbench_t* workbench;
- workbench = RTGUI_WORKBENCH(win->parent_toplevel);
- workbench->flag |= RTGUI_WORKBENCH_FLAG_MODAL_MODE;
- workbench->modal_widget = RTGUI_WIDGET(win);
+ app = rtgui_application_self();
+ RT_ASSERT(app != RT_NULL);
- rtgui_workbench_event_loop(workbench);
- result = workbench->modal_code;
- workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
- workbench->modal_widget = RT_NULL;
- }
- else if (RTGUI_IS_WIN(parent_widget))
- {
- rtgui_win_t* parent_win;
- parent_win = RTGUI_WIN(win->parent_toplevel);
- parent_win->style |= RTGUI_WIN_STYLE_UNDER_MODAL;
- parent_win->modal_widget = RTGUI_WIDGET(win);
+ win->flag |= RTGUI_WIN_FLAG_MODAL;
- rtgui_win_event_loop(parent_win);
- result = parent_win->modal_code;
- parent_win->style &= ~RTGUI_WIN_STYLE_UNDER_MODAL;
- parent_win->modal_widget = RT_NULL;
- }
- }
- else
- {
- /* which is a root window */
- win->style |= RTGUI_WIN_STYLE_MODAL;
- rtgui_win_event_loop(win);
+ if (rtgui_server_post_event_sync((struct rtgui_event*)&emodal,
+ sizeof(emodal)) != RT_EOK)
+ return exit_code;
- result = win->modal_code;
- win->style &= ~RTGUI_WIN_STYLE_MODAL;
+ app->modal_object = RTGUI_OBJECT(win);
+
+ exit_code = rtgui_application_run(app);
+
+ app->modal_object = RT_NULL;
+ win->flag &= ~RTGUI_WIN_FLAG_MODAL;
+
+ if (win->style & RTGUI_WIN_STYLE_DESTROY_ON_CLOSE)
+ {
+ rtgui_win_destroy(win);
}
- }
+ }
- return result;
+ return exit_code;
}
void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code)
{
- if (win->parent_toplevel != RT_NULL)
- {
- if (RTGUI_IS_WORKBENCH(win->parent_toplevel))
- {
- rtgui_workbench_t* workbench;
+ if (win == RT_NULL || !(win->flag & RTGUI_WIN_FLAG_MODAL))
+ return;
- /* which is shown under workbench */
- workbench = RTGUI_WORKBENCH(win->parent_toplevel);
- workbench->modal_code = modal_code;
- workbench->flag &= ~RTGUI_WORKBENCH_FLAG_MODAL_MODE;
- }
- else if (RTGUI_IS_WIN(win->parent_toplevel))
- {
- rtgui_win_t* parent_win;
-
- /* which is shown under win */
- parent_win = RTGUI_WIN(win->parent_toplevel);
- parent_win->modal_code = modal_code;
- parent_win->style &= ~RTGUI_WIN_STYLE_UNDER_MODAL;
- }
- }
- else
- {
- /* which is a stand alone window */
- win->modal_code = modal_code;
- }
+ rtgui_application_exit(rtgui_application_self(), modal_code);
/* remove modal mode */
- win->style &= ~RTGUI_WIN_STYLE_MODAL;
+ win->flag &= ~RTGUI_WIN_FLAG_MODAL;
}
void rtgui_win_hiden(struct rtgui_win* win)
{
RT_ASSERT(win != RT_NULL);
+#ifdef RTGUI_USING_DESKTOP_WINDOW
+ RT_ASSERT(win != the_desktop_window);
+#endif
if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) &&
- RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
/* send hidden message to server */
struct rtgui_event_win_hide ehide;
RTGUI_EVENT_WIN_HIDE_INIT(&ehide);
ehide.wid = win;
- if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&ehide),
+ if (rtgui_server_post_event_sync(RTGUI_EVENT(&ehide),
sizeof(struct rtgui_event_win_hide)) != RT_EOK)
{
rt_kprintf("hide win: %s failed\n", win->title);
@@ -289,7 +312,7 @@ void rtgui_win_hiden(struct rtgui_win* win)
/* set window hide and deactivated */
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
- win->style &= ~RTGUI_WIN_STYLE_ACTIVATE;
+ win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE;
}
}
@@ -297,7 +320,7 @@ rt_bool_t rtgui_win_is_activated(struct rtgui_win* win)
{
RT_ASSERT(win != RT_NULL);
- if (win->style & RTGUI_WIN_STYLE_ACTIVATE) return RT_TRUE;
+ if (win->flag & RTGUI_WIN_FLAG_ACTIVATE) return RT_TRUE;
return RT_FALSE;
}
@@ -307,28 +330,29 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y)
struct rtgui_event_win_move emove;
RTGUI_EVENT_WIN_MOVE_INIT(&emove);
- if (win == RT_NULL) return;
+ if (win == RT_NULL)
+ return;
+
+ /* move window to logic position */
+ rtgui_widget_move_to_logic(RTGUI_WIDGET(win),
+ x - RTGUI_WIDGET(win)->extent.x1,
+ y - RTGUI_WIDGET(win)->extent.y1);
- if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
/* set win hide firstly */
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
- emove.wid = win;
+ emove.wid = win;
emove.x = x;
emove.y = y;
- if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&emove),
+ if (rtgui_server_post_event_sync(RTGUI_EVENT(&emove),
sizeof(struct rtgui_event_win_move)) != RT_EOK)
{
return;
}
}
- /* move window to logic position */
- rtgui_widget_move_to_logic(RTGUI_WIDGET(win),
- x - RTGUI_WIDGET(win)->extent.x1,
- y - RTGUI_WIDGET(win)->extent.y1);
-
/* set window visible */
RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
return;
@@ -342,7 +366,8 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win* win)
/* begin drawing */
dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(win));
- if (dc == RT_NULL) return RT_FALSE;
+ if (dc == RT_NULL)
+ return RT_FALSE;
/* get window rect */
rtgui_widget_get_rect(RTGUI_WIDGET(win), &rect);
@@ -352,18 +377,22 @@ static rt_bool_t rtgui_win_ondraw(struct rtgui_win* win)
/* paint each widget */
RTGUI_EVENT_PAINT_INIT(&event);
event.wid = RT_NULL;
- rtgui_container_dispatch_event(RTGUI_CONTAINER(win), (rtgui_event_t*)&event);
+ rtgui_container_dispatch_event(RTGUI_CONTAINER(win),
+ (rtgui_event_t*)&event);
rtgui_dc_end_drawing(dc);
return RT_FALSE;
}
-rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{
- struct rtgui_win* win = (struct rtgui_win*)widget;
+ struct rtgui_win* win;
+
+ RT_ASSERT(object != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
- RT_ASSERT((win != RT_NULL) && (event != RT_NULL));
+ win = RTGUI_WIN(object);
switch (event->type)
{
@@ -376,22 +405,8 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
break;
case RTGUI_EVENT_WIN_CLOSE:
- if (win->on_close != RT_NULL)
- {
- if (win->on_close(widget, event) == RT_FALSE) return RT_TRUE;
- }
-
- if (win->style & RTGUI_WIN_STYLE_MODAL)
- {
- rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
- }
- else
- {
- /* destroy window */
- rtgui_win_destroy(win);
- }
-
- /* exit event loop */
+ _rtgui_win_deal_close(win, event);
+ /* don't broadcast WIN_CLOSE event to others */
return RT_TRUE;
case RTGUI_EVENT_WIN_MOVE:
@@ -410,49 +425,54 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
return RT_TRUE;
}
- win->style |= RTGUI_WIN_STYLE_ACTIVATE;
+ win->flag |= RTGUI_WIN_FLAG_ACTIVATE;
#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
- else
+ if (RTGUI_WIDGET(object)->on_draw != RT_NULL)
+ RTGUI_WIDGET(object)->on_draw(object, event);
+ else
#endif
rtgui_widget_update(RTGUI_WIDGET(win));
if (win->on_activate != RT_NULL)
{
- win->on_activate(widget, event);
+ win->on_activate(RTGUI_OBJECT(object), event);
}
break;
case RTGUI_EVENT_WIN_DEACTIVATE:
- if (win->style & RTGUI_WIN_STYLE_MODAL)
+ if (win->flag & RTGUI_WIN_FLAG_MODAL)
{
- /* do not deactivate a modal win, re-send win-show event */
- struct rtgui_event_win_show eshow;
- RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
- eshow.wid = win;
-
- rtgui_thread_send(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&eshow),
- sizeof(struct rtgui_event_win_show));
+ /* FIXME: make modal concept clear and easy. See the comment of
+ * rtgui_topwin_modal_enter. */
+ /* There are various reason that a modal window got deactivated:
+ * 1, it has child windows and the user activate one of them.
+ * 2, the application has more than one root window and the
+ * user switched to one of the others.
+ *
+ * In any of the cases, we have nothing to do here.
+ */
}
else
{
- win->style &= ~RTGUI_WIN_STYLE_ACTIVATE;
+ win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE;
#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
- else
+ if (RTGUI_WIDGET(object)->on_draw != RT_NULL)
+ RTGUI_WIDGET(object)->on_draw(object, event);
+ else
#endif
- rtgui_win_ondraw(win);
+ rtgui_widget_update(RTGUI_WIDGET(win));
if (win->on_deactivate != RT_NULL)
{
- win->on_deactivate(widget, event);
+ win->on_deactivate(RTGUI_OBJECT(object), event);
}
}
break;
case RTGUI_EVENT_PAINT:
#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+ if (RTGUI_WIDGET(object)->on_draw != RT_NULL)
+ RTGUI_WIDGET(object)->on_draw(object, event);
else
#endif
rtgui_win_ondraw(win);
@@ -460,36 +480,22 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
case RTGUI_EVENT_MOUSE_BUTTON:
/* check whether has widget which handled mouse event before */
- if (RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) != RT_NULL)
+ if (win->last_mevent_widget != RT_NULL)
{
- struct rtgui_event_mouse* emouse;
-
- emouse = (struct rtgui_event_mouse*)event;
-
- RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win)->event_handler(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win), event);
- if (rtgui_rect_contains_point(&(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win)->extent),
- emouse->x, emouse->y) == RT_EOK)
- {
- RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) = RT_NULL;
- break; /* mouse event is inside of widget, do not handle it anymore */
- }
+ RTGUI_OBJECT(win->last_mevent_widget)->event_handler(
+ RTGUI_OBJECT(win->last_mevent_widget),
+ event);
/* clean last mouse event handled widget */
- RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(win) = RT_NULL;
+ win->last_mevent_widget = RT_NULL;
}
-
- if (win->style & RTGUI_WIN_STYLE_UNDER_MODAL)
- {
- if (win->modal_widget != RT_NULL)
- return win->modal_widget->event_handler(win->modal_widget, event);
- }
- else if (rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
+ else if (rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),
(struct rtgui_event_mouse*)event) == RT_FALSE)
{
#ifndef RTGUI_USING_SMALL_SIZE
- if (widget->on_mouseclick != RT_NULL)
+ if (RTGUI_WIDGET(object)->on_mouseclick != RT_NULL)
{
- return widget->on_mouseclick(widget, event);
+ return RTGUI_WIDGET(object)->on_mouseclick(object, event);
}
#endif
}
@@ -512,101 +518,45 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
#endif
break;
- case RTGUI_EVENT_KBD:
- if (win->style & RTGUI_WIN_STYLE_UNDER_MODAL)
+ case RTGUI_EVENT_KBD:
+ /* we should dispatch key event firstly */
+ if (!(win->flag & RTGUI_WIN_FLAG_HANDLE_KEY))
{
- if (win->modal_widget != RT_NULL)
- return win->modal_widget->event_handler(win->modal_widget, event);
+ rt_bool_t res = RT_FALSE;
+ /* we should dispatch the key event just once. Once entered the
+ * dispatch mode, we should swtich to key handling mode. */
+ win->flag |= RTGUI_WIN_FLAG_HANDLE_KEY;
+
+ /* dispatch the key event */
+ if (win->focused_widget != RT_NULL &&
+ RTGUI_OBJECT(win->focused_widget)->event_handler != RT_NULL)
+ res = RTGUI_OBJECT(win->focused_widget)->event_handler(
+ RTGUI_OBJECT(win->focused_widget), event);
+
+ /* if the focused widget doesn't handle it, I will handle it. */
+ if (res != RT_TRUE && win->on_key != RT_NULL)
+ res = win->on_key(RTGUI_OBJECT(win), event);
+
+ win->flag &= ~RTGUI_WIN_FLAG_HANDLE_KEY;
+ return res;
}
- else if (RTGUI_CONTAINER(win)->focused != widget &&
- RTGUI_CONTAINER(win)->focused != RT_NULL)
+ else
{
- RTGUI_CONTAINER(win)->focused->event_handler(RTGUI_CONTAINER(win)->focused, event);
+ /* in key handling mode(it may reach here in
+ * win->focused_widget->event_handler call) */
+ if (win->on_key != RT_NULL)
+ return win->on_key(RTGUI_OBJECT(win), event);
}
- break;
+ break;
default:
/* call parent event handler */
- return rtgui_toplevel_event_handler(widget, event);
+ return rtgui_toplevel_event_handler(object, event);
}
return RT_FALSE;
}
-/* windows event loop */
-void rtgui_win_event_loop(rtgui_win_t* wnd)
-{
- rt_err_t result;
- rtgui_thread_t* tid;
- struct rtgui_event* event;
-
- tid = rtgui_thread_self();
- RT_ASSERT(tid != RT_NULL);
-
- /* point to event buffer */
- event = (struct rtgui_event*)tid->event_buffer;
-
- if (wnd->style & RTGUI_WIN_STYLE_UNDER_MODAL)
- {
- while (wnd->style & RTGUI_WIN_STYLE_UNDER_MODAL)
- {
- if (tid->on_idle != RT_NULL)
- {
- result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- {
- /* perform event handler */
- RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
- }
- else if (result == -RT_ETIMEOUT)
- {
- tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
- }
- }
- else
- {
- result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- {
- /* perform event handler */
- RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
- }
- }
- }
- }
- else
- {
- while (!(wnd->style & RTGUI_WIN_STYLE_CLOSED))
- {
- if (tid->on_idle != RT_NULL)
- {
- result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- {
- /* perform event handler */
- RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
- }
- else if (result == -RT_ETIMEOUT)
- {
- tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
- }
- }
- else
- {
- result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- {
- /* perform event handler */
- RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
- }
- }
- }
- }
-
- /* destroy window */
- rtgui_widget_destroy(RTGUI_WIDGET(wnd));
-}
-
void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
{
struct rtgui_event_win_resize event;
@@ -615,14 +565,14 @@ void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
RTGUI_WIDGET(win)->extent = *rect;
- if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
/* set window resize event to server */
RTGUI_EVENT_WIN_RESIZE_INIT(&event);
event.wid = win;
event.rect = *rect;
- rtgui_thread_send(RTGUI_TOPLEVEL(win)->server, &(event.parent), sizeof(struct rtgui_event_win_resize));
+ rtgui_server_post_event(&(event.parent), sizeof(struct rtgui_event_win_resize));
}
}
@@ -660,10 +610,18 @@ void rtgui_win_set_onclose(rtgui_win_t* win, rtgui_event_handler_ptr handler)
}
}
+void rtgui_win_set_onkey(rtgui_win_t* win, rtgui_event_handler_ptr handler)
+{
+ if (win != RT_NULL)
+ {
+ win->on_key = handler;
+ }
+}
+
void rtgui_win_set_title(rtgui_win_t* win, const char *title)
{
/* send title to server */
- if (RTGUI_TOPLEVEL(win)->server != RT_NULL)
+ if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{
}
diff --git a/components/rtgui/widgets/workbench.c b/components/rtgui/widgets/workbench.c
deleted file mode 100644
index 4dd3f7e6e8..0000000000
--- a/components/rtgui/widgets/workbench.c
+++ /dev/null
@@ -1,581 +0,0 @@
-/*
- * File : workbench.c
- * This file is part of RTGUI in RT-Thread RTOS
- * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
- *
- * The license and distribution terms for this file may be
- * found in the file LICENSE in this distribution or at
- * http://www.rt-thread.org/license/LICENSE
- *
- * Change Logs:
- * Date Author Notes
- * 2009-10-04 Bernard first version
- * 2010-09-24 Bernard fix workbench destroy issue
- */
-#include <rtgui/rtgui_system.h>
-#include <rtgui/widgets/window.h>
-#include <rtgui/widgets/workbench.h>
-
-static void _rtgui_workbench_constructor(rtgui_workbench_t *workbench)
-{
- /* set event handler */
- rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), rtgui_workbench_event_handler);
-
- /* set attributes */
- workbench->flag = RTGUI_WORKBENCH_FLAG_DEFAULT;
- workbench->panel = RT_NULL;
- workbench->title = RT_NULL;
- workbench->current_view = RT_NULL;
- workbench->modal_code = RTGUI_MODAL_OK;
- workbench->modal_widget = RT_NULL;
-}
-
-static void _rtgui_workbench_destructor(rtgui_workbench_t *workbench)
-{
- RT_ASSERT(workbench != RT_NULL);
-
- if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
- {
- struct rtgui_event_panel_detach edetach;
- RTGUI_EVENT_PANEL_DETACH_INIT(&edetach);
-
- /* detach from panel */
- edetach.panel = workbench->panel;
-
- /* send PANEL DETACH to server */
- if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server,
- RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK)
- return;
-
- RTGUI_TOPLEVEL(workbench)->server = RT_NULL;
- }
-
- /* release title */
- rt_free(workbench->title);
- workbench->title = RT_NULL;
-}
-
-DEFINE_CLASS_TYPE(workbench, "workbench",
- RTGUI_TOPLEVEL_TYPE,
- _rtgui_workbench_constructor,
- _rtgui_workbench_destructor,
- sizeof(struct rtgui_workbench));
-
-rtgui_workbench_t *rtgui_workbench_create(const char* panel_name, const unsigned char* title)
-{
- struct rtgui_workbench* workbench;
-
- /* the server thread id */
- rt_thread_t server = rtgui_thread_get_server();
- if (server == RT_NULL)
- {
- rt_kprintf("can't find rtgui server\n");
- return RT_NULL;
- }
-
- /* create workbench */
- workbench = (rtgui_workbench_t*) rtgui_widget_create (RTGUI_WORKBENCH_TYPE);
- if (workbench != RT_NULL)
- {
- /* the buffer uses to receive event */
- union
- {
- struct rtgui_event_panel_attach ecreate;
- struct rtgui_event_panel_info epanel;
-
- char buffer[256]; /* use to recv other information */
- } event;
-
- /* set workbench title */
- workbench->title = (unsigned char*)rt_strdup((char*)title);
-
- /* create application in server */
- RTGUI_EVENT_PANEL_ATTACH_INIT(&(event.ecreate));
-
- /* set the panel name and workbench */
- rt_strncpy(event.ecreate.panel_name, panel_name, RTGUI_NAME_MAX);
- event.ecreate.workbench = workbench;
-
- /* send PANEL ATTACH to server */
- if (rtgui_thread_send_sync(server,
- &(event.ecreate.parent), sizeof(struct rtgui_event_panel_attach)) != RTGUI_STATUS_OK)
- {
- return RT_NULL;
- }
-
- /* get PANEL INFO */
- rtgui_thread_recv_filter(RTGUI_EVENT_PANEL_INFO, &(event.epanel.parent), sizeof(event));
-
- /* set panel */
- workbench->panel = (struct rtgui_panel*)event.epanel.panel;
-
- /* connected */
- RTGUI_TOPLEVEL(workbench)->server = server;
-
- /* set extent of workbench */
- rtgui_widget_set_rect(RTGUI_WIDGET(workbench), &(event.epanel.extent));
-
- /* set workbench in thread */
- rtgui_thread_set_widget(RTGUI_WIDGET(workbench));
- }
-
- return workbench;
-}
-
-void rtgui_workbench_destroy(rtgui_workbench_t* workbench)
-{
- RT_ASSERT(workbench != RT_NULL);
-
- if (workbench->flag & RTGUI_WORKBENCH_FLAG_CLOSED)
- {
- rtgui_widget_destroy(RTGUI_WIDGET(workbench));
- }
- else
- {
- /* just close workbench */
- rtgui_workbench_close(workbench);
- }
-}
-
-void rtgui_workbench_close(rtgui_workbench_t* workbench)
-{
- /* detach workbench in server */
- if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
- {
- struct rtgui_event_panel_detach edetach;
- RTGUI_EVENT_PANEL_DETACH_INIT(&edetach);
-
- /* detach from panel */
- edetach.panel = workbench->panel;
- edetach.workbench = workbench;
-
- /* send PANEL DETACH to server */
- if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server,
- RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK)
- return;
-
- RTGUI_TOPLEVEL(workbench)->server = RT_NULL;
- }
-
- /* set status to close */
- workbench->flag |= RTGUI_WORKBENCH_FLAG_CLOSED;
-}
-
-void rtgui_workbench_set_flag(rtgui_workbench_t* workbench, rt_uint8_t flag)
-{
- RT_ASSERT(workbench != RT_NULL);
-
- workbench->flag = flag;
-}
-
-rt_bool_t rtgui_workbench_event_loop(rtgui_workbench_t* workbench)
-{
- rt_err_t result;
- rtgui_thread_t* tid;
- struct rtgui_event* event;
-
- tid = rtgui_thread_self();
- RT_ASSERT(tid != RT_NULL);
-
- /* point to event buffer */
- event = (struct rtgui_event*)tid->event_buffer;
-
- if (workbench->flag & RTGUI_WORKBENCH_FLAG_MODAL_MODE)
- {
- /* event loop for modal mode shown view */
- while (workbench->flag & RTGUI_WORKBENCH_FLAG_MODAL_MODE)
- {
- if (tid->on_idle != RT_NULL)
- {
- result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
- else if (result == -RT_ETIMEOUT)
- tid->on_idle(RTGUI_WIDGET(workbench), RT_NULL);
- }
- else
- {
- result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
- }
- }
- }
- else
- {
- /* show workbench firstly */
- rtgui_workbench_show(workbench);
-
- while (!(workbench->flag & RTGUI_WORKBENCH_FLAG_CLOSED))
- {
- if (tid->on_idle != RT_NULL)
- {
- result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
- else if (result == -RT_ETIMEOUT)
- tid->on_idle(RTGUI_WIDGET(workbench), RT_NULL);
- }
- else
- {
- result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
- if (result == RT_EOK)
- RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
- }
- }
- }
-
- return RT_TRUE;
-}
-
-rt_err_t rtgui_workbench_show(rtgui_workbench_t* workbench)
-{
- RT_ASSERT(workbench != RT_NULL);
-
- if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
- {
- struct rtgui_event_panel_show eraise;
- RTGUI_EVENT_PANEL_SHOW_INIT(&eraise);
- eraise.workbench = workbench;
-
- eraise.panel = workbench->panel;
- if (rtgui_thread_send_sync(workbench->parent.server, RTGUI_EVENT(&eraise),
- sizeof(struct rtgui_event_panel_show)) != RT_EOK)
- return -RT_ERROR;
-
- RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(workbench));
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
- }
- else return -RT_ERROR;
-
- return RT_EOK;
-}
-
-rt_err_t rtgui_workbench_hide(rtgui_workbench_t* workbench)
-{
- if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL)
- {
- struct rtgui_event_panel_hide ehide;
- RTGUI_EVENT_PANEL_HIDE_INIT(&ehide);
-
- RT_ASSERT(workbench != RT_NULL);
- if (workbench->parent.server == RT_NULL) return -RT_ERROR;
-
- ehide.panel = workbench->panel;
- if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, RTGUI_EVENT(&ehide),
- sizeof(struct rtgui_event_panel_hide)) != RT_EOK)
- return -RT_ERROR;
-
- RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench));
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
- }
-
- return RT_EOK;
-}
-
-rt_bool_t rtgui_workbench_event_handler(rtgui_widget_t* widget, rtgui_event_t* event)
-{
- struct rtgui_workbench* workbench = (struct rtgui_workbench*)widget;
-
- switch (event->type)
- {
- case RTGUI_EVENT_PANEL_DETACH:
- RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench));
- RTGUI_TOPLEVEL(workbench)->server = RT_NULL;
- return RT_TRUE;
-
- case RTGUI_EVENT_PANEL_SHOW:
- /* show workbench in server */
- rtgui_workbench_show(workbench);
- break;
-
- case RTGUI_EVENT_PANEL_HIDE:
- /* hide widget */
- RTGUI_WIDGET_HIDE(widget);
- break;
-
- case RTGUI_EVENT_MOUSE_MOTION:
- {
- struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
- struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid);
-
- /* check the destination window */
- if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
- }
- else
- {
- /* let viewer to handle it */
- rtgui_view_t* view = workbench->current_view;
- if (view != RT_NULL &&
- RTGUI_WIDGET(view)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event);
- }
- }
- }
- break;
-
- case RTGUI_EVENT_MOUSE_BUTTON:
- {
- struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event;
- struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid);
-
- /* check whether has widget which handled mouse event before */
- if (RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) != RT_NULL)
- {
- struct rtgui_event_mouse* emouse;
-
- emouse = (struct rtgui_event_mouse*)event;
-
- RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench)->event_handler(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench), event);
- if (rtgui_rect_contains_point(&(RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench)->extent),
- emouse->x, emouse->y) == RT_EOK)
- {
- RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) = RT_NULL;
- break; /* mouse event is inside of widget, do not handle it anymore */
- }
-
- /* clean last mouse event handled widget */
- RTGUI_TOPLEVEL_LAST_MEVENT_WIDGET(workbench) = RT_NULL;
- }
-
- /* check the destination window */
- if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
- }
- else
- {
- if (RTGUI_WORKBENCH_IS_MODAL_MODE(workbench))
- {
- /* let modal widget to handle it */
- if (workbench->modal_widget != RT_NULL &&
- workbench->modal_widget->event_handler != RT_NULL)
- {
- workbench->modal_widget->event_handler(workbench->modal_widget, event);
- }
- }
- else
- {
- /* let viewer to handle it */
- rtgui_view_t* view = workbench->current_view;
- if (view != RT_NULL &&
- RTGUI_WIDGET(view)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event);
- }
- }
- }
- }
- break;
-
- case RTGUI_EVENT_KBD:
- {
- struct rtgui_event_kbd* kbd = (struct rtgui_event_kbd*)event;
- struct rtgui_toplevel* top = RTGUI_TOPLEVEL(kbd->wid);
-
- /* check the destination window */
- if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
- }
- else
- {
- if (RTGUI_WORKBENCH_IS_MODAL_MODE(workbench))
- {
- /* let modal widget to handle it */
- if (workbench->modal_widget != RT_NULL &&
- workbench->modal_widget->event_handler != RT_NULL)
- {
- workbench->modal_widget->event_handler(workbench->modal_widget, event);
- }
- }
- else
- {
- if (RTGUI_CONTAINER(widget)->focused == widget)
- {
- /* set focused widget to the current view */
- if (workbench->current_view != RT_NULL)
- rtgui_widget_focus(RTGUI_WIDGET(RTGUI_CONTAINER(workbench->current_view)->focused));
- }
-
- return rtgui_toplevel_event_handler(widget, event);
- }
- }
- }
- break;
-
- case RTGUI_EVENT_PAINT:
- {
- struct rtgui_event_paint* epaint = (struct rtgui_event_paint*)event;
- struct rtgui_toplevel* top = RTGUI_TOPLEVEL(epaint->wid);
-
- /* check the destination window */
- if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
- }
- else
- {
- rtgui_view_t* view;
-
- /* un-hide workbench */
- RTGUI_WIDGET_UNHIDE(widget);
-
- /* paint a view */
- view = workbench->current_view;
- if (view != RT_NULL)
- {
- /* remake a paint event */
- RTGUI_EVENT_PAINT_INIT(epaint);
- epaint->wid = RT_NULL;
-
- /* send this event to the view */
- if (RTGUI_WIDGET(view)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event);
- }
- }
- else
- {
- struct rtgui_dc* dc;
- struct rtgui_rect rect;
-
- dc = rtgui_dc_begin_drawing(widget);
- rtgui_widget_get_rect(widget, &rect);
- rtgui_dc_fill_rect(dc, &rect);
- rtgui_dc_end_drawing(dc);
- }
- }
- }
- break;
-
- case RTGUI_EVENT_CLIP_INFO:
- {
- struct rtgui_event_clip_info* eclip = (struct rtgui_event_clip_info*)event;
- struct rtgui_widget* dest_widget = RTGUI_WIDGET(eclip->wid);
-
- if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL)
- {
- dest_widget->event_handler(dest_widget, event);
- }
- else
- {
- return rtgui_toplevel_event_handler(widget, event);
- }
- }
- break;
-
- case RTGUI_EVENT_WIN_CLOSE:
- case RTGUI_EVENT_WIN_ACTIVATE:
- case RTGUI_EVENT_WIN_DEACTIVATE:
- {
- struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
- struct rtgui_widget* dest_widget = RTGUI_WIDGET(wevent->wid);
- if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL)
- {
- dest_widget->event_handler(dest_widget, event);
- }
- }
- break;
-
- case RTGUI_EVENT_WIN_MOVE:
- {
- struct rtgui_event_win_move* wevent = (struct rtgui_event_win_move*)event;
- struct rtgui_toplevel* top = RTGUI_TOPLEVEL(wevent->wid);
- if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL)
- {
- RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event);
- }
- }
- break;
-
- default:
- return rtgui_toplevel_event_handler(widget, event);
- }
-
- return RT_TRUE;
-}
-
-/*
- *
- * view on workbench
- *
- */
-
-void rtgui_workbench_add_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
- rtgui_container_add_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view));
- /* hide view in default */
- RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view));
-
- /* reset view extent */
- rtgui_widget_set_rect(RTGUI_WIDGET(view), &(RTGUI_WIDGET(workbench)->extent));
-}
-
-void rtgui_workbench_remove_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
- if (view == workbench->current_view)
- rtgui_workbench_hide_view(workbench, view);
-
- rtgui_container_remove_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view));
-}
-
-void rtgui_workbench_show_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
- RT_ASSERT(workbench != RT_NULL);
- RT_ASSERT(view != RT_NULL);
-
- /* already shown */
- if (workbench->current_view == view) return;
-
- if (workbench->current_view != RT_NULL)
- {
- /* hide old view */
- RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench->current_view));
- }
-
- /* show view */
- RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(view));
- workbench->current_view = view;
-
- /* update workbench clip */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
-
- if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(workbench)))
- {
- rtgui_widget_update(RTGUI_WIDGET(view));
- }
-}
-
-void rtgui_workbench_hide_view(rtgui_workbench_t* workbench, rtgui_view_t* view)
-{
- RT_ASSERT(workbench != RT_NULL);
- RT_ASSERT(view != RT_NULL);
-
- /* hide view */
- RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view));
-
- if (view == workbench->current_view)
- {
- rtgui_view_t *next_view;
-
- workbench->current_view = RT_NULL;
-
- next_view = RTGUI_VIEW(rtgui_widget_get_next_sibling(RTGUI_WIDGET(view)));
- if (next_view == RT_NULL)
- next_view = RTGUI_VIEW(rtgui_widget_get_prev_sibling(RTGUI_WIDGET(view)));
-
- if (next_view != RT_NULL)
- {
- rtgui_view_show(next_view, RT_FALSE);
- }
- else
- {
- /* update workbench clip */
- rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench));
- }
- }
-}