summaryrefslogtreecommitdiff
path: root/components/rtgui/widgets
diff options
context:
space:
mode:
author[email protected] <[email protected]>2012-04-18 15:06:12 +0000
committer[email protected] <[email protected]>2012-04-18 15:06:12 +0000
commitdb0646020812efc16ff0beebe35f9049dcc2bfed (patch)
tree5e949e9ba679a07b0198745853e900a016a3834e /components/rtgui/widgets
parent06d45f0c42f2aa3678d509403fcf9cd82be106e6 (diff)
merge new RTGUI in to trunk
The full log is at https://github.com/RTGUI/RTGUI/commits/merge_1 and it's difficult to merge the new tree commit by commit. I also converted all the file into unix eol so there are many fake diff. Big changes are noted in rtgui/doc/road_map.txt and rtgui/doc/attention.txt. Keep an eye on them if you want to migrate your old code. Note that the work is still in progress and the bsp is not prepared in trunk so far. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2092 bbd45198-f89e-11dd-88c7-29a3b14d5316
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));
- }
- }
-}