summaryrefslogtreecommitdiff
path: root/components/rtgui_win/widgets
diff options
context:
space:
mode:
author[email protected] <[email protected]>2011-03-24 14:00:19 +0000
committer[email protected] <[email protected]>2011-03-24 14:00:19 +0000
commit0e93e6809c7beac4597148edc1dc09bcdf9a2ab3 (patch)
tree113765e7f8351d84226a3de04f13daf86ddd82f9 /components/rtgui_win/widgets
parent96c53b49571adadd957df804f4f5e6698c14e3b3 (diff)
add rtgui_win subfield,Highlight the ease of use
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1345 bbd45198-f89e-11dd-88c7-29a3b14d5316
Diffstat (limited to 'components/rtgui_win/widgets')
-rw-r--r--components/rtgui_win/widgets/button.c238
-rw-r--r--components/rtgui_win/widgets/checkbox.c211
-rw-r--r--components/rtgui_win/widgets/combobox.c326
-rw-r--r--components/rtgui_win/widgets/container.c321
-rw-r--r--components/rtgui_win/widgets/file.xpm43
-rw-r--r--components/rtgui_win/widgets/file_hdc.h155
-rw-r--r--components/rtgui_win/widgets/filelist_view.c799
-rw-r--r--components/rtgui_win/widgets/folder.xpm142
-rw-r--r--components/rtgui_win/widgets/iconbox.c221
-rw-r--r--components/rtgui_win/widgets/label.c135
-rw-r--r--components/rtgui_win/widgets/list_view.c667
-rw-r--r--components/rtgui_win/widgets/listbox.c728
-rw-r--r--components/rtgui_win/widgets/menu.c476
-rw-r--r--components/rtgui_win/widgets/progressbar.c128
-rw-r--r--components/rtgui_win/widgets/radiobox.c206
-rw-r--r--components/rtgui_win/widgets/scrollbar.c666
-rw-r--r--components/rtgui_win/widgets/slider.c229
-rw-r--r--components/rtgui_win/widgets/staticline.c96
-rw-r--r--components/rtgui_win/widgets/textbox.c547
-rw-r--r--components/rtgui_win/widgets/view.c193
-rw-r--r--components/rtgui_win/widgets/widget.c757
-rw-r--r--components/rtgui_win/widgets/window.c726
22 files changed, 8010 insertions, 0 deletions
diff --git a/components/rtgui_win/widgets/button.c b/components/rtgui_win/widgets/button.c
new file mode 100644
index 0000000000..93e6863869
--- /dev/null
+++ b/components/rtgui_win/widgets/button.c
@@ -0,0 +1,238 @@
+/*
+ * File : button.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
+ */
+#include <rtgui/dc.h>
+#include <rtgui/widgets/button.h>
+#include <rtgui/widgets/container.h>
+#include <rtgui/rtgui_theme.h>
+
+static rt_bool_t rtgui_button_onunfocus(PVOID wdt, rtgui_event_t* event);
+
+static void _rtgui_button_constructor(rtgui_button_t *button)
+{
+ /* init widget and set event handler */
+ RTGUI_WIDGET_FLAG(button) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ rtgui_widget_set_event_handler(button, rtgui_button_event_handler);
+ rtgui_widget_set_onunfocus(button, rtgui_button_onunfocus);
+ /* un-press button */
+ button->flag = 0;
+ rtgui_widget_set_style(button,RTGUI_BORDER_UP);
+
+ /* set flag and on_button event handler */
+ button->image = RT_NULL;
+ button->on_button = RT_NULL;
+
+ /* set gc */
+ RTGUI_WIDGET_FOREGROUND(button) = default_foreground;
+ RTGUI_WIDGET_BACKGROUND(button) = default_background;
+ RTGUI_WIDGET_TEXTALIGN(button) = RTGUI_ALIGN_CENTER_HORIZONTAL|RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+static void _rtgui_button_destructor(rtgui_button_t *button)
+{
+ if(button->image != RT_NULL)
+ {
+ rtgui_image_destroy(button->image);
+ button->image = RT_NULL;
+ }
+}
+
+rtgui_type_t *rtgui_button_type_get(void)
+{
+ static rtgui_type_t *button_type = RT_NULL;
+
+ if(!button_type)
+ {
+ button_type = rtgui_type_create("button", RTGUI_LABEL_TYPE,
+ sizeof(rtgui_button_t),
+ RTGUI_CONSTRUCTOR(_rtgui_button_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_button_destructor));
+ }
+
+ return button_type;
+}
+
+rtgui_button_t* rtgui_button_create(PVOID parent, char* text,int left, int top, int w, int h)
+{
+ rtgui_button_t* btn;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ btn = rtgui_widget_create(RTGUI_BUTTON_TYPE);
+ if(btn != RT_NULL)
+ {
+ rtgui_rect_t rect;
+ /* set default rect */
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(btn), text, &rect);
+
+ rtgui_label_set_text(RTGUI_LABEL(btn), text);
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(btn, &rect);
+
+ rtgui_container_add_child(parent, btn);
+ }
+
+ return btn;
+}
+
+void rtgui_button_destroy(rtgui_button_t* btn)
+{
+ rtgui_widget_destroy(btn);
+}
+
+rt_bool_t rtgui_button_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_button_t* btn = (rtgui_button_t*) widget;
+
+ if(btn == RT_NULL)return RT_FALSE;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL )
+ widget->on_draw(widget, event);
+ else
+ rtgui_theme_draw_button(btn);
+ break;
+
+ case RTGUI_EVENT_KBD:
+ {
+ rtgui_event_kbd_t* ekbd = (rtgui_event_kbd_t*) event;
+
+ if((ekbd->key == RTGUIK_RETURN) || (ekbd->key == RTGUIK_SPACE))
+ {
+ if(RTGUI_KBD_IS_DOWN(ekbd))
+ {
+ btn->flag |= RTGUI_BUTTON_FLAG_PRESS;
+ }
+ else
+ {
+ btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
+ }
+
+ /* draw button */
+ rtgui_theme_draw_button(btn);
+
+ if((btn->flag & RTGUI_BUTTON_FLAG_PRESS) && (btn->on_button != RT_NULL))
+ {
+ /* call on button handler */
+ btn->on_button(widget, event);
+ }
+ }
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_event_mouse_t* emouse = (rtgui_event_mouse_t*)event;
+
+ if(emouse->button & RTGUI_MOUSE_BUTTON_LEFT)
+ {
+ rtgui_widget_focus(widget);
+ /* it's a normal button */
+ if(emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ btn->flag |= RTGUI_BUTTON_FLAG_PRESS;
+ }
+ else
+ {
+ btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
+ }
+
+ /* draw button */
+ if(widget->on_draw != RT_NULL )
+ widget->on_draw(widget, event);
+ else
+ {
+ rtgui_theme_draw_button(btn);
+ }
+
+ /* invokes call back */
+ if(widget->on_mouseclick != RT_NULL && emouse->button & RTGUI_MOUSE_BUTTON_UP)
+ return widget->on_mouseclick(widget, event);
+
+ if(!(btn->flag & RTGUI_BUTTON_FLAG_PRESS) && (btn->on_button != RT_NULL))
+ {
+ /* call on button handler */
+ btn->on_button(widget, event);
+ }
+ }
+
+ return RT_TRUE;
+ }
+ default:
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+void rtgui_button_set_image(rtgui_button_t* btn, rtgui_image_t* image)
+{
+ if(btn == RT_NULL)return;
+
+ btn->image = image;
+}
+
+void rtgui_button_set_onbutton(rtgui_button_t* btn, rtgui_onbutton_func_t func)
+{
+ RT_ASSERT(btn != RT_NULL);
+
+ btn->on_button = func;
+}
+
+static rt_bool_t rtgui_button_onunfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_rect_t rect;
+ rtgui_button_t *btn = (rtgui_button_t*)wdt;
+ rtgui_dc_t *dc;
+
+ RT_ASSERT(wdt != RT_NULL);
+
+ dc = rtgui_dc_begin_drawing(wdt);
+ if(dc == RT_NULL)return RT_FALSE;
+
+ rtgui_widget_get_rect(btn, &rect);
+
+ if(!RTGUI_WIDGET_IS_FOCUSED(btn))
+ {//��������
+ rtgui_color_t color;
+ rtgui_rect_inflate(&rect, -2);
+ color = RTGUI_DC_FC(dc);
+ RTGUI_DC_FC(dc) = RTGUI_DC_BC(dc);
+ rtgui_dc_draw_focus_rect(dc,&rect);
+ RTGUI_DC_FC(dc) = color;
+ }
+
+ rtgui_dc_end_drawing(dc);
+
+ return RT_TRUE;
+}
+
+void rtgui_button_set_text(rtgui_button_t* btn, const char* text)
+{
+ if(btn == RT_NULL)return;
+
+ rtgui_label_set_text(RTGUI_LABEL(btn), text);
+
+ /* update widget */
+ rtgui_theme_draw_button(btn);
+}
diff --git a/components/rtgui_win/widgets/checkbox.c b/components/rtgui_win/widgets/checkbox.c
new file mode 100644
index 0000000000..6b97bf995d
--- /dev/null
+++ b/components/rtgui_win/widgets/checkbox.c
@@ -0,0 +1,211 @@
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/container.h>
+#include <rtgui/widgets/checkbox.h>
+
+static rt_bool_t rtgui_checkbox_onunfocus(PVOID wdt, rtgui_event_t* event);
+
+static void _rtgui_checkbox_constructor(rtgui_checkbox_t *checkbox)
+{
+ /* init widget and set event handler */
+ RTGUI_WIDGET_FLAG(checkbox) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ rtgui_widget_set_event_handler(checkbox, rtgui_checkbox_event_handler);
+
+ rtgui_widget_set_onunfocus(checkbox, rtgui_checkbox_onunfocus);
+ /* set status */
+ checkbox->value = 0;
+
+ /* set default gc */
+ RTGUI_WIDGET_TEXTALIGN(checkbox) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+static void _rtgui_checkbox_destructor(rtgui_checkbox_t *checkbox)
+{
+
+}
+
+rtgui_type_t *rtgui_checkbox_type_get(void)
+{
+ static rtgui_type_t *checkbox_type = RT_NULL;
+
+ if(!checkbox_type)
+ {
+ checkbox_type = rtgui_type_create("checkbox", RTGUI_LABEL_TYPE,
+ sizeof(rtgui_checkbox_t),
+ RTGUI_CONSTRUCTOR(_rtgui_checkbox_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_checkbox_destructor));
+ }
+
+ return checkbox_type;
+}
+
+rtgui_checkbox_t* rtgui_checkbox_create(PVOID parent,const char* text, rt_bool_t checked,rtgui_color_t fc,int left,int top)
+{
+ rtgui_checkbox_t* box;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ box = rtgui_widget_create (RTGUI_CHECKBOX_TYPE);
+ if(box != RT_NULL)
+ {
+ rtgui_rect_t rect,text_rect;
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ /* set default rect */
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(box), text, &text_rect);
+ text_rect.x2 += RTGUI_WIDGET_BORDER(box) + 5 + (RTGUI_WIDGET_BORDER(box) << 1);
+ text_rect.y2 += (RTGUI_WIDGET_BORDER(box) << 1);
+
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1 + CHECK_BOX_W + rtgui_rect_width(text_rect);
+ rect.y2 = rect.y1 + rtgui_rect_height(text_rect);
+
+ rtgui_widget_set_rect(box, &rect);
+
+ rtgui_checkbox_set_text(box, text);
+ RTGUI_WIDGET_FOREGROUND(box) = fc;
+ if(checked == RT_TRUE)
+ box->value = 1;
+ else
+ box->value = 0;
+ rtgui_container_add_child(parent, box);
+ }
+
+ return box;
+}
+
+void rtgui_checkbox_destroy(rtgui_checkbox_t* box)
+{
+ rtgui_widget_destroy(box);
+}
+
+rt_bool_t rtgui_checkbox_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_checkbox_t* box = (rtgui_checkbox_t*)widget;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ {
+ return widget->on_draw(widget, event);
+ }
+ else
+ rtgui_theme_draw_checkbox(box);
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(RTGUI_WIDGET_IS_ENABLE(widget) && !RTGUI_WIDGET_IS_HIDE(widget))
+ {
+ rtgui_event_mouse_t* emouse = (rtgui_event_mouse_t*)event;
+ if(emouse->button & RTGUI_MOUSE_BUTTON_LEFT && emouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ if(box->value)
+ {
+ /* check it */
+ box->value = 0;
+ }
+ else
+ {
+ /* un-check it */
+ box->value = 1;
+ }
+ }
+ else if(emouse->button & RTGUI_MOUSE_BUTTON_LEFT && emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ /* set focus */
+ rtgui_widget_focus(widget);
+ }
+ /* draw checkbox */
+ rtgui_theme_draw_checkbox(box);
+
+ /* call user callback */
+ if(widget->on_mouseclick != RT_NULL)
+ {
+ return widget->on_mouseclick(widget, event);
+ }
+ }
+
+ return RT_TRUE;
+ default:
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+void rtgui_checkbox_set_checked(rtgui_checkbox_t* checkbox, rt_bool_t checked)
+{
+ RT_ASSERT(checkbox != RT_NULL);
+ if(checked == RT_TRUE)
+ checkbox->value = 1;
+ else
+ checkbox->value = 0;
+
+}
+
+rt_bool_t rtgui_checkbox_get_checked(rtgui_checkbox_t* checkbox)
+{
+ RT_ASSERT(checkbox != RT_NULL);
+
+ if(checkbox->value)
+ return RT_TRUE;
+
+ return RT_FALSE;
+}
+
+static rt_bool_t rtgui_checkbox_onunfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_rect_t rect;
+ rtgui_checkbox_t* box = (rtgui_checkbox_t*)wdt;
+ rtgui_dc_t *dc;
+
+ RT_ASSERT(box != RT_NULL);
+
+ dc = rtgui_dc_begin_drawing(box);
+ if(dc == RT_NULL)return RT_FALSE;
+
+ rtgui_widget_get_rect(box, &rect);
+
+ if(!RTGUI_WIDGET_IS_FOCUSED(box))
+ {//��������
+ rtgui_rect_t tmp_rect;
+ rtgui_color_t color;
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(box), rtgui_label_get_text(RTGUI_LABEL(box)), &tmp_rect);
+
+ rtgui_rect_moveto(&tmp_rect,rect.x1+CHECK_BOX_W+7, rect.y1);
+ tmp_rect.x1 -= 1;
+ tmp_rect.x2 += 2;
+ tmp_rect.y2 = rect.y2-1;
+
+ /* draw focused border */
+ color = RTGUI_DC_FC(dc);
+ RTGUI_DC_FC(dc) = RTGUI_DC_BC(dc);
+ rtgui_dc_draw_focus_rect(dc,&tmp_rect);
+ RTGUI_DC_FC(dc) = color;
+ }
+
+ rtgui_dc_end_drawing(dc);
+
+ return RT_TRUE;
+}
+
+void rtgui_checkbox_set_text(rtgui_checkbox_t *box, const char* text)
+{
+ RT_ASSERT(box != RT_NULL);
+
+ if(RTGUI_LABEL(box)->text != RT_NULL)
+ {
+ /* release old text memory */
+ rt_free(RTGUI_LABEL(box)->text);
+ RTGUI_LABEL(box)->text = RT_NULL;
+ }
+
+ if(text != RT_NULL)
+ RTGUI_LABEL(box)->text = rt_strdup(text);
+ else
+ RTGUI_LABEL(box)->text = RT_NULL;
+}
diff --git a/components/rtgui_win/widgets/combobox.c b/components/rtgui_win/widgets/combobox.c
new file mode 100644
index 0000000000..07805c6d92
--- /dev/null
+++ b/components/rtgui_win/widgets/combobox.c
@@ -0,0 +1,326 @@
+//��Ͽ�ؼ�
+
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/combobox.h>
+
+static rt_uint32_t rtgui_combo_get_count(rtgui_combo_t* cbo);
+static void rtgui_combo_add_string(rtgui_combo_t* cbo, char* string);
+
+static void _rtgui_combobox_constructor(rtgui_combo_t *cbo)
+{
+ RTGUI_WIDGET_FLAG(cbo) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ cbo->style = RTGUI_COMBO_STYLE_DOWNARROW_UP;
+ cbo->lbox = RT_NULL;
+ cbo->tbox = RT_NULL;
+
+ rtgui_widget_set_event_handler(cbo, rtgui_combo_event_handler);
+
+ RTGUI_WIDGET_BACKGROUND(cbo) = white;
+ /* set default text align */
+ RTGUI_WIDGET_TEXTALIGN(cbo) = RTGUI_ALIGN_CENTER_VERTICAL;
+ rtgui_widget_set_style(cbo, RTGUI_BORDER_SUNKEN);
+ cbo->on_selected = RT_NULL;
+ cbo->get_count = rtgui_combo_get_count;
+ cbo->add_string = rtgui_combo_add_string;
+}
+
+static void _rtgui_combobox_destructor(rtgui_combo_t *cbo)
+{
+
+}
+
+rtgui_type_t *rtgui_combo_type_get(void)
+{
+ static rtgui_type_t *combo_type = RT_NULL;
+
+ if(!combo_type)
+ {
+ combo_type = rtgui_type_create("combobox", RTGUI_CONTAINER_TYPE,
+ sizeof(rtgui_combo_t),
+ RTGUI_CONSTRUCTOR(_rtgui_combobox_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_combobox_destructor));
+ }
+
+ return combo_type;
+}
+
+rtgui_combo_t* rtgui_combo_create(PVOID parent,const char* text,int left,int top,int w,int h)
+{
+ rtgui_combo_t* cbo;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ cbo = rtgui_widget_create(RTGUI_COMBOBOX_TYPE);
+ if(cbo != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+RTGUI_COMBOBOX_HEIGHT;
+ rtgui_widget_set_rect(cbo,&rect);
+
+ rtgui_container_add_child(parent, cbo);
+
+ if(cbo->tbox == RT_NULL)
+ {
+ cbo->tbox = rtgui_textbox_create(cbo,text,
+ RTGUI_WIDGET_BORDER(cbo),
+ RTGUI_WIDGET_BORDER(cbo),
+ w-RTGUI_COMBOBOX_BUTTON_WIDTH-RTGUI_WIDGET_BORDER(cbo)*2,
+ h-RTGUI_WIDGET_BORDER(cbo)*2,RTGUI_TEXTBOX_NONE);
+
+ if(cbo->tbox == RT_NULL) return RT_NULL;
+ rtgui_widget_set_style(cbo->tbox,RTGUI_BORDER_NONE);
+ cbo->tbox->isedit = RT_FALSE;//ȱʡcombo�ı༭�򲻿ɱ༭
+ }
+ if(cbo->lbox == RT_NULL)
+ {//���������������б�
+ rtgui_point_t point;
+ rt_uint32_t mleft,mtop,mwidth;
+
+ rtgui_widget_get_position(cbo, &point);
+ mleft = point.x;
+ mtop = point.y+RTGUI_COMBOBOX_HEIGHT;
+ mwidth = rtgui_widget_get_width(cbo);
+
+ //���������б�
+ cbo->lbox = rtgui_listbox_create(parent,mleft,mtop,mwidth,4,RTGUI_BORDER_SIMPLE);
+ if(cbo->lbox == RT_NULL)return RT_NULL;
+ cbo->lbox->ispopup = RT_TRUE;
+ cbo->lbox->widgetlnk = cbo;
+ rtgui_listbox_set_onitem(cbo->lbox,rtgui_combo_onitem);
+
+ RTGUI_WIDGET_HIDE(cbo->lbox);
+ }
+ }
+
+ return cbo;
+}
+
+void rtgui_combo_destroy(rtgui_combo_t* cbo)
+{
+ rtgui_widget_destroy(cbo);
+}
+
+void rtgui_combo_set_onitem(rtgui_combo_t* cbo, rtgui_event_handler_ptr func)
+{
+ if(cbo == RT_NULL) return;
+
+ if(cbo->lbox != RT_NULL)
+ {
+ rtgui_listbox_set_onitem(cbo->lbox,func);
+ }
+}
+
+rt_uint32_t rtgui_combo_get_select(rtgui_combo_t* cbo)
+{
+ return cbo->lbox->now_aloc;
+}
+
+char* rtgui_combo_get_string(rtgui_combo_t* cbo)
+{
+ if(cbo->lbox->items != RT_NULL)
+ {
+ return cbo->lbox->items[cbo->lbox->now_aloc].name;
+ }
+
+ return RT_NULL;
+}
+
+//������Ŀ�ı��
+rt_bool_t rtgui_combo_onitem(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_listbox_t* box = (rtgui_listbox_t*)wdt;
+
+ if(box != RT_NULL && box->ispopup)
+ {
+ char *str;
+ rtgui_combo_t* cbo=box->widgetlnk;
+ if(cbo==RT_NULL)return RT_FALSE;
+
+ str = rtgui_combo_get_string(cbo);
+
+ rtgui_textbox_set_value(cbo->tbox,str);
+ }
+
+ return RT_TRUE;
+}
+
+void rtgui_combo_get_downarrow_rect(rtgui_combo_t* cbo, rtgui_rect_t* rect)
+{
+ rtgui_widget_get_rect(cbo, rect);
+ rect->x1 = rect->x2 - RTGUI_COMBOBOX_BUTTON_WIDTH;
+}
+
+static rt_uint32_t rtgui_combo_get_count(rtgui_combo_t* cbo)
+{
+ if(cbo->lbox)
+ {
+ return cbo->lbox->get_count(cbo->lbox);
+ }
+ return 0;
+}
+
+static void rtgui_combo_add_string(rtgui_combo_t* cbo,char* string)
+{
+ if(cbo->lbox != RT_NULL)
+ {
+ rtgui_listbox_item_t item;
+ rtgui_rect_t rect;
+ rt_uint32_t h,count;
+
+ item.name = string;
+ item.image = RT_NULL;
+ cbo->lbox->add_item(cbo->lbox,&item);
+
+ rtgui_widget_get_rect(cbo->lbox, &rect);
+ count = cbo->get_count(cbo);
+
+ h = 2+(SELECTED_HEIGHT + 2)*count;
+
+ if(h>rtgui_rect_height(rect))//������Ҫ���Ŀؼ���extent
+ {
+ if(cbo->lbox->item_per_page<5)//ÿҳ��ʾ����С��5���Ż����
+ {
+ rect.y2 = rect.y1+h;
+ rtgui_widget_rect_to_device(cbo->lbox,&rect);
+ rtgui_widget_set_rect(cbo->lbox,&rect);//����lbox�Ĵ�С
+ cbo->lbox->item_per_page = rtgui_rect_height(rect) / (SELECTED_HEIGHT+2);
+
+ if(cbo->lbox->sbar != RT_NULL)//ͬʱ����sbar��extent
+ {
+ rtgui_widget_get_rect(cbo->lbox->sbar, &rect);
+ rect.y2 = rect.y1+h-RTGUI_WIDGET_BORDER(cbo->lbox)*2;
+ rtgui_widget_rect_to_device(cbo->lbox->sbar,&rect);
+ rtgui_widget_set_rect(cbo->lbox->sbar,&rect);
+
+ if(cbo->lbox->item_count > cbo->lbox->item_per_page)
+ {
+ RTGUI_WIDGET_UNHIDE(cbo->lbox->sbar);
+ rtgui_scrollbar_set_line_step(cbo->lbox->sbar, 1);
+ rtgui_scrollbar_set_page_step(cbo->lbox->sbar, cbo->lbox->item_per_page);
+ rtgui_scrollbar_set_range(cbo->lbox->sbar, cbo->lbox->item_count);
+ }
+ else
+ {
+ RTGUI_WIDGET_HIDE(cbo->lbox->sbar);
+ }
+ rtgui_widget_update_clip(cbo->lbox);
+ }
+ }
+ }
+ }
+}
+
+void rtgui_combo_set_items(rtgui_combo_t* cbo, rtgui_listbox_item_t* items, rt_uint32_t count)
+{
+ if(cbo != RT_NULL && cbo->lbox != RT_NULL)
+ {
+ rtgui_listbox_set_items(cbo->lbox,items,count);
+ }
+}
+
+rt_bool_t rtgui_combo_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_combo_t* cbo = (rtgui_combo_t*) widget;
+
+
+ RT_ASSERT(widget != RT_NULL);
+
+ switch(event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL )
+ widget->on_draw(widget, event);
+ else
+ rtgui_theme_draw_combo(cbo);
+ break;
+
+ case RTGUI_EVENT_KBD:
+ if(widget->on_key != RT_NULL)
+ widget->on_key(widget, event);
+
+ return RT_TRUE;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_rect_t rect;
+ rtgui_event_mouse_t* emouse = (rtgui_event_mouse_t*)event;
+ rt_bool_t inclip=RT_EOK;
+
+ if(cbo->tbox->isedit == RT_TRUE)
+ {//�༭��ɱ༭ʱ,ֻ���������ť����
+ inclip = rtgui_region_contains_point(&RTGUI_WIDGET_CLIP(cbo),emouse->x,emouse->y,&rect);
+ }
+ else
+ {//���ȫ������
+ inclip = (rtgui_region_contains_point(&RTGUI_WIDGET_CLIP(cbo),emouse->x,emouse->y,&rect) &&
+ rtgui_region_contains_point(&RTGUI_WIDGET_CLIP(cbo->tbox),emouse->x,emouse->y,&rect));
+ }
+
+ if(inclip == RT_EOK)
+ {
+ rtgui_combo_get_downarrow_rect(cbo,&rect);
+ if(emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ if(rtgui_rect_contains_point(&rect,emouse->x,emouse->y) == RT_EOK)
+ {//��������ť��
+ cbo->style = RTGUI_COMBO_STYLE_DOWNARROW_DOWN;
+ rtgui_theme_draw_combo_downarrow(cbo);
+ }
+
+ if(cbo->lbox != RT_NULL)
+ {
+ if(RTGUI_WIDGET_IS_HIDE(cbo->lbox))
+ {//��ʾ�����б�
+ RTGUI_WIDGET_UNHIDE(cbo->lbox);
+ rtgui_widget_focus(cbo->lbox);
+ rtgui_widget_update_clip_pirate(RTGUI_WIDGET_PARENT(cbo->lbox),cbo->lbox);
+ //�б���λ����Ϊ0
+ cbo->lbox->frist_aloc=0;
+ cbo->lbox->now_aloc = 0;
+ if(cbo->lbox->sbar != RT_NULL)
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(cbo->lbox->sbar))
+ {//��������λ����Ϊ0
+ rtgui_scrollbar_set_value(cbo->lbox->sbar,cbo->lbox->frist_aloc);
+ }
+ }
+ rtgui_widget_update(RTGUI_WIDGET_PARENT(cbo->lbox));
+ }
+ else
+ {//���ص����б�
+ RTGUI_WIDGET_HIDE(cbo->lbox);
+ rtgui_widget_unfocus(cbo->lbox);
+ }
+ }
+ }
+ else if(emouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ if(rtgui_region_contains_point(&RTGUI_WIDGET_CLIP(cbo),emouse->x,emouse->y,&rect) == RT_EOK)
+ {//��������ť��
+ cbo->style = RTGUI_COMBO_STYLE_DOWNARROW_UP;
+ rtgui_theme_draw_combo_downarrow(cbo);
+ }
+ }
+ }
+ else
+ rtgui_view_event_handler(widget,event);
+
+ break;
+ }
+
+ default:
+ return rtgui_view_event_handler(widget,event);
+ }
+
+ return RT_FALSE;
+}
+
+
diff --git a/components/rtgui_win/widgets/container.c b/components/rtgui_win/widgets/container.c
new file mode 100644
index 0000000000..61f65a9cd3
--- /dev/null
+++ b/components/rtgui_win/widgets/container.c
@@ -0,0 +1,321 @@
+/*
+ * File : box.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
+ */
+
+#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(container, rtgui_container_event_handler);
+ rtgui_list_init(&(container->children));
+
+ /* set focused widget to itself */
+ container->focused = RTGUI_WIDGET(container);
+ /* set box as focusable widget */
+ RTGUI_WIDGET_FLAG(container) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+}
+
+static void _rtgui_container_destructor(rtgui_container_t *container)
+{
+ /* destroy child of box */
+ rtgui_container_destroy_children(container);
+}
+
+static void _rtgui_container_update_toplevel(rtgui_container_t* container)
+{
+ rtgui_list_t* node;
+
+ rtgui_list_foreach(node, &(container->children))
+ {
+ rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ /* set child top */
+ child->toplevel = RTGUI_WIDGET(rtgui_widget_get_toplevel(container));
+
+ if(RTGUI_IS_CONTAINER(child))
+ {
+ _rtgui_container_update_toplevel(RTGUI_CONTAINER(child));
+ }
+ }
+}
+
+rtgui_type_t *rtgui_container_type_get(void)
+{
+ static rtgui_type_t *container_type = RT_NULL;
+
+ if(!container_type)
+ {
+ container_type = rtgui_type_create("container", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_container_t),
+ RTGUI_CONSTRUCTOR(_rtgui_container_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_container_destructor));
+ }
+
+ return container_type;
+}
+
+rt_bool_t rtgui_container_dispatch_event(rtgui_container_t *container, rtgui_event_t* event)
+{
+ /* handle in child widget */
+ rtgui_list_t* node;
+
+ rtgui_list_foreach(node, &(container->children))
+ {
+ rtgui_widget_t* w;
+ w = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if(RTGUI_WIDGET_IS_HIDE(w)) continue; //�ؼ������ص��򲻻�����
+ //if(RTGUI_IS_WIN(w)) continue;
+ if(RTGUI_WIDGET_EVENT_HANDLE(w) != RT_NULL)
+ RTGUI_WIDGET_EVENT_CALL(w, event);
+ }
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_container_dispatch_mouse_event(rtgui_container_t *container, rtgui_event_mouse_t* event)
+{
+ /* handle in child widget */
+ rtgui_list_t* node;
+ rtgui_widget_t *focus;
+
+ /* get focus widget on toplevel */
+ focus = RTGUI_CONTAINER(RTGUI_WIDGET(container)->toplevel)->focused;
+ rtgui_list_foreach(node, &(container->children))
+ {
+ rtgui_widget_t* w;
+ w = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if(RTGUI_WIDGET_IS_HIDE(w))continue;//���صĿؼ�������
+
+ if(rtgui_rect_contains_point(&(w->extent), event->x, event->y) == RT_EOK)
+ {//��⵽��ǰ����ij���ؼ���
+ if ((focus != w) && RTGUI_WIDGET_IS_FOCUSABLE(w))
+ rtgui_widget_focus(w);
+ if(RTGUI_WIDGET_EVENT_HANDLE(w) != RT_NULL)
+ return RTGUI_WIDGET_EVENT_CALL(w,(rtgui_event_t*)event);
+ }
+ }
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_container_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_container_t *container = RTGUI_CONTAINER(widget);
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_KBD:
+ if(widget->on_key != RT_NULL)
+ {
+ return widget->on_key(widget, event);
+ }
+ else
+ {
+ /* let parent to handle keyboard event */
+ if(widget->parent != RT_NULL && widget->parent != widget->toplevel)
+ {
+ if(RTGUI_WIDGET_EVENT_HANDLE(widget->parent) != RT_NULL)
+ return RTGUI_WIDGET_EVENT_CALL(widget->parent, event);
+ }
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ /* handle in child widget */
+ if(rtgui_container_dispatch_mouse_event(container,(rtgui_event_mouse_t*)event) == RT_FALSE)
+ {
+ /* handle event in current widget */
+ if(widget->on_mouseclick != RT_NULL)
+ {
+ return widget->on_mouseclick(widget, event);
+ }
+ }
+ else return RT_TRUE;
+ break;
+
+ case RTGUI_EVENT_MOUSE_MOTION:
+ if(rtgui_container_dispatch_mouse_event(container,(rtgui_event_mouse_t*)event) == RT_FALSE)
+ {
+ #if 0
+ /* handle event in current widget */
+ if(widget->on_mousemotion != RT_NULL)
+ {
+ return widget->on_mousemotion(widget, event);
+ }
+ #endif
+ }
+ else
+ return RT_TRUE;
+ break;
+
+ case RTGUI_EVENT_TIMER:
+ {
+ rtgui_timer_t* timer;
+ rtgui_event_timer_t* etimer = (rtgui_event_timer_t*) 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(container, event) == RT_FALSE)
+ {
+ if(widget->on_command != RT_NULL)
+ {
+ return widget->on_command(widget, event);
+ }
+ }
+ else
+ return RT_TRUE;
+ break;
+
+ case RTGUI_EVENT_RESIZE:
+ if(rtgui_container_dispatch_event(container, event) == RT_FALSE)
+ {
+ if(widget->on_size != RT_NULL)
+ return widget->on_size(widget, event);
+ }
+ else return RT_TRUE;
+ break;
+
+ default:
+ /* call parent widget event handler */
+ return rtgui_widget_event_handler(widget, event);
+ }
+
+ return RT_FALSE;
+}
+
+/*
+ * This function will add a child to a box widget
+ * Note: this function will not change the widget layout
+ * the layout is the responsibility of layout widget, such as box.
+ */
+void rtgui_container_add_child(PVOID cbox, PVOID wdt)
+{
+ rtgui_container_t *container = (rtgui_container_t*)cbox;
+ rtgui_widget_t* child = (rtgui_widget_t*)wdt;
+
+ RT_ASSERT(container != RT_NULL);
+ RT_ASSERT(child != RT_NULL);
+ RT_ASSERT(RTGUI_IS_CONTAINER(container));
+
+ /* set parent and toplevel widget */
+ child->parent = RTGUI_WIDGET(container);
+ /* put widget to parent's child list */
+ rtgui_list_append(&(container->children), &(child->sibling));
+
+ /* update child toplevel */
+ if(RTGUI_WIDGET(container)->toplevel != RT_NULL && RTGUI_IS_CONTAINER(RTGUI_WIDGET(container)->toplevel))
+ {
+ child->toplevel = RTGUI_WIDGET(rtgui_widget_get_toplevel(container));
+
+ /* update all child toplevel */
+ if(RTGUI_IS_CONTAINER(child))
+ {
+ _rtgui_container_update_toplevel(RTGUI_CONTAINER(child));
+ }
+ }
+
+ rtgui_widget_update_clip(child);
+}
+
+/* remove a child to widget */
+void rtgui_container_remove_child(rtgui_container_t *container, PVOID wdt)
+{
+ rtgui_widget_t *child = (rtgui_widget_t*)wdt;
+
+ 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(container);
+ }
+
+ /* remove widget from parent's child list */
+ rtgui_list_remove(&(container->children), &(child->sibling));
+
+ /* set parent and top widget */
+ child->parent = RT_NULL;
+ child->toplevel = RT_NULL;
+ rtgui_widget_update_clip(container);
+}
+
+/* destroy all child of box */
+void rtgui_container_destroy_children(rtgui_container_t *container)
+{
+ rtgui_list_t* node;
+
+ if(container == RT_NULL) return;
+
+ node = container->children.next;
+ while(node != RT_NULL)
+ {
+ rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+
+ if(RTGUI_IS_CONTAINER(child))
+ {
+ /* break parent firstly */
+ child->parent = RT_NULL;
+
+ /* destroy child of child */
+ rtgui_container_destroy_children(RTGUI_CONTAINER(child));
+ }
+
+ /* remove widget from parent's child list */
+ rtgui_list_remove(&(container->children), &(child->sibling));
+
+ /* set parent and top widget */
+ child->parent = RT_NULL;
+
+ /* destroy object and remove from parent */
+ rtgui_object_destroy(RTGUI_OBJECT(child));
+
+ //node = box->child.next;
+ node = node->next;
+ }
+
+ container->children.next = RT_NULL;
+ container->focused = RTGUI_WIDGET(container);
+ if(RTGUI_WIDGET_PARENT(container) != RT_NULL)
+ rtgui_widget_focus(container);
+
+ /* update widget clip */
+ rtgui_widget_update_clip(RTGUI_WIDGET(container)->toplevel);
+}
+
+rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container)
+{
+ rtgui_widget_t* child = RT_NULL;
+
+ if(container->children.next != RT_NULL)
+ {
+ child = rtgui_list_entry(container->children.next, rtgui_widget_t, sibling);
+ }
+
+ return child;
+}
+
+
+
diff --git a/components/rtgui_win/widgets/file.xpm b/components/rtgui_win/widgets/file.xpm
new file mode 100644
index 0000000000..60e323cc82
--- /dev/null
+++ b/components/rtgui_win/widgets/file.xpm
@@ -0,0 +1,43 @@
+/* XPM */
+static const 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",
+".++++++++++++ ",
+"+@@@@@@@@@@@@+ ",
+"+@#$$%%%##&*@+ ",
+"+@$=--;;;;>*@+ ",
+"+@$%%###&&,*@+ ",
+"+@%-;;;;;;>*@+ ",
+"+@%%##&&'#,*@+ ",
+"+@%;;;;,,),*@+ ",
+"+@##&&,,!!!*@+ ",
+"+@#;;;>>~~~*@+ ",
+"+@#&,,!!*{{{@+ ",
+"+@&;>>~~~{{]@+ ",
+"+@&&,!!**{]]@+ ",
+"+@@@@@@@@@@@@+ ",
+"^++++++++++++^ ",
+" "
+};
+
diff --git a/components/rtgui_win/widgets/file_hdc.h b/components/rtgui_win/widgets/file_hdc.h
new file mode 100644
index 0000000000..2bdc0694c5
--- /dev/null
+++ b/components/rtgui_win/widgets/file_hdc.h
@@ -0,0 +1,155 @@
+#ifndef __FILE_HDC_H__
+#define __FILE_HDC_H__
+
+
+
+//�ļ�ͼ��
+const unsigned char file_hdc[] =
+{
+0x48, 0x44, 0x43, 0x00,//HDC
+0x10, 0x00, 0x00, 0x00,//width
+0x10, 0x00, 0x00, 0x00,//height
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xDF, 0xFF, 0xD7, 0x4C,
+0xFA, 0x4D, 0x52, 0x33, 0x34, 0x3C, 0xFA, 0x4D,
+0xF2, 0x63, 0xFA, 0x4D, 0x70, 0x6B, 0x13, 0x5C,
+0xBA, 0xD6, 0x9E, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0x59, 0xE6, 0xCF, 0xC3,
+0x57, 0x95, 0x52, 0x33, 0x57, 0x95, 0xD1, 0x6B,
+0xB7, 0xD5, 0x95, 0x6C, 0xB7, 0xBD, 0x13, 0x5C,
+0x14, 0xA5, 0x1C, 0xE7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x38, 0xE6,
+0x50, 0x43, 0xBD, 0xF7, 0x50, 0x43, 0xBD, 0xF7,
+0x50, 0x43, 0xDE, 0xFF, 0x50, 0x43, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x77, 0xD6,
+0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7,
+0xDE, 0xF7, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x78, 0xD6,
+0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7,
+0xDE, 0xF7, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x77, 0xD6,
+0xBD, 0xF7, 0x1F, 0x00, 0x1F, 0x00, 0x1F, 0x00,
+0x1F, 0x00, 0xF7, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x77, 0xD6,
+0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7,
+0xDE, 0xF7, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x97, 0xD6,
+0xBD, 0xF7, 0x00, 0x04, 0x00, 0x04, 0x00, 0x04,
+0x00, 0x04, 0xF7, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x77, 0xD6,
+0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7,
+0xDE, 0xF7, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x57, 0xDE,
+0xBD, 0xF7, 0x00, 0xF8, 0x00, 0xF8, 0x00, 0xF8,
+0x00, 0xF8, 0xF7, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x78, 0xDE,
+0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7,
+0xDE, 0xF7, 0xDE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x77, 0xD6,
+0xBD, 0xF7, 0x1F, 0xF8, 0x1F, 0xF8, 0x1F, 0xF8,
+0x1F, 0xF8, 0xF7, 0xBD, 0xFF, 0xFF, 0xFF, 0xFF,
+0x8E, 0x73, 0xBA, 0xD6, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xCF, 0xC3, 0x56, 0xCE,
+0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7,
+0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7, 0xBD, 0xF7,
+0x8E, 0x73, 0xDB, 0xDE, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xDB, 0xDE, 0xF3, 0x9C,
+0x0F, 0x84, 0x0F, 0x84, 0x6D, 0x6B, 0x4D, 0x6B,
+0x4D, 0x6B, 0x4D, 0x6B, 0x71, 0x8C, 0xF3, 0x9C,
+0xF3, 0x9C, 0x5D, 0xEF, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7, 0xBE, 0xF7,
+};
+
+//�ļ���ͼ��
+const unsigned char folder_hdc[] =
+{
+0x48, 0x44, 0x43, 0x00,//HDC
+0x10, 0x00, 0x00, 0x00,//width
+0x10, 0x00, 0x00, 0x00,//height
+0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07, 0xFF, 0x07,
+0xFF, 0x07, 0xFF, 0x07, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+};
+
+#endif
+
diff --git a/components/rtgui_win/widgets/filelist_view.c b/components/rtgui_win/widgets/filelist_view.c
new file mode 100644
index 0000000000..8eb9a7db64
--- /dev/null
+++ b/components/rtgui_win/widgets/filelist_view.c
@@ -0,0 +1,799 @@
+/*
+ * File : fileview.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.h>
+#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/filelist_view.h>
+#include <rtgui/widgets/listbox.h>
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/dialog.h>
+#include <lcd.h>
+
+#include <uffs/uffs_fd.h>
+#include <uffs_ext.h>
+#include <dfs_posix.h>
+
+//·���ָ��
+#define PATH_SEPARATOR '/'
+
+#include <string.h>
+
+#include "file_hdc.h" //�ļ�ͼ��
+
+/* image for file and folder */
+static rtgui_image_t *file_image = RT_NULL;
+static rtgui_image_t *folder_image = RT_NULL;
+
+static rt_bool_t rtgui_fileview_onunfocus(PVOID wdt, rtgui_event_t* event);
+static rt_bool_t rtgui_fileview_sbar_handle(PVOID wdt, rtgui_event_t* event);
+
+static void _rtgui_fileview_constructor(rtgui_filelist_view_t *fview)
+{
+ /* set default widget rect and set event handler */
+ rtgui_widget_set_event_handler(fview, rtgui_filelist_view_event_handler);
+ rtgui_widget_set_onunfocus(fview, rtgui_fileview_onunfocus);
+
+ RTGUI_WIDGET_FLAG(fview) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ fview->frist_aloc = 0;
+ fview->now_aloc = 0;
+ fview->item_count = 0;
+ fview->item_per_page = 0;
+
+ fview->current_dir = RT_NULL;
+ fview->pattern = RT_NULL;
+ RTGUI_WIDGET_BACKGROUND(fview) = white;
+ RTGUI_WIDGET_TEXTALIGN(fview) = RTGUI_ALIGN_CENTER_VERTICAL;
+
+ if(file_image==RT_NULL)
+ file_image = rtgui_image_create_from_mem("hdc",file_hdc, sizeof(file_hdc), TRUE);
+ if(folder_image==RT_NULL)
+ folder_image = rtgui_image_create_from_mem("hdc",folder_hdc, sizeof(folder_hdc), TRUE);
+
+}
+
+static void _rtgui_fileview_destructor(rtgui_filelist_view_t *fview)
+{
+ rtgui_filelist_view_destroy(fview);
+}
+
+rtgui_type_t *rtgui_filelist_view_type_get(void)
+{
+ static rtgui_type_t *fileview_type = RT_NULL;
+
+ if(!fileview_type)
+ {
+ fileview_type = rtgui_type_create("fileview", RTGUI_CONTAINER_TYPE,
+ sizeof(rtgui_filelist_view_t),
+ RTGUI_CONSTRUCTOR(_rtgui_fileview_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_fileview_destructor));
+ }
+
+ return fileview_type;
+}
+
+
+rtgui_filelist_view_t* rtgui_filelist_view_create(PVOID parent, const char* directory, const char* pattern, int left, int top, int w, int h)
+{
+ rtgui_filelist_view_t* fview = RT_NULL;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ /* create a new view */
+ fview = rtgui_widget_create(RTGUI_FILELIST_VIEW_TYPE);
+
+ if(fview != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+
+ fview->items = RT_NULL;
+ fview->pattern = rt_strdup(pattern);
+ fview->item_per_page = rtgui_rect_height(rect) / (1 + SELECTED_HEIGHT);
+
+ rtgui_widget_set_rect(fview,&rect);
+
+ rtgui_container_add_child(parent, fview);
+
+ {//��������ؼ�
+ rt_uint32_t sLeft,sTop,sw=RTGUI_DEFAULT_SB_WIDTH,sLen;
+ sLeft = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER(fview)-sw;
+ sTop = RTGUI_WIDGET_BORDER(fview);
+
+ sLen = rect.y2-rect.y1-RTGUI_WIDGET_BORDER(fview)*2;
+ fview->sbar = rtgui_scrollbar_create(fview,sLeft,sTop,sw,sLen,RTGUI_VERTICAL);
+ if(fview->sbar != RT_NULL)
+ {
+ fview->sbar->widgetlnk = fview;
+ fview->sbar->on_scroll = rtgui_fileview_sbar_handle;
+ RTGUI_WIDGET_HIDE(fview->sbar);//Ĭ�����ع�����
+ }
+ }
+
+ rtgui_filelist_view_set_directory(fview, directory);
+ }
+
+ return fview;
+}
+
+static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view);
+
+void rtgui_filelist_view_destroy(rtgui_filelist_view_t* fview)
+{
+ /* delete all file items */
+ rtgui_filelist_view_clear(fview);
+
+ /* delete current directory and pattern */
+ if(fview->current_dir != RT_NULL)
+ rt_free(fview->current_dir);
+ fview->current_dir = RT_NULL;
+
+ if(fview->pattern != RT_NULL)
+ rt_free(fview->pattern);
+ fview->pattern = RT_NULL;
+
+ /* delete image */
+ rtgui_image_destroy(file_image);
+ file_image = RT_NULL;
+ rtgui_image_destroy(folder_image);
+ folder_image = RT_NULL;
+}
+
+static void rtgui_filelist_view_on_folder_item(rtgui_filelist_view_t *fview)
+{
+ char* dir_ptr;
+
+ dir_ptr = (char*)rt_malloc(256);
+ if(dir_ptr==RT_NULL)
+ {
+ return;
+ }
+ //û�����ļ��л����ļ������˳�
+ if(fview->items==RT_NULL)return;
+
+ rtgui_filelist_view_get_fullpath(fview, dir_ptr, 256);
+
+ rtgui_filelist_view_set_directory(fview, dir_ptr);
+ rt_free(dir_ptr);
+}
+
+void rtgui_filelist_view_ondraw(rtgui_filelist_view_t* fview)
+{
+ rt_uint16_t frist, i,rx2;
+ rtgui_filelist_view_item_t* item;
+ rtgui_rect_t rect, item_rect, image_rect;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(fview != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(fview);
+ if(dc == RT_NULL)return;
+
+ rtgui_widget_get_rect(fview, &rect);
+ rtgui_dc_draw_border(dc, &rect,RTGUI_WIDGET_BORDER_STYLE(fview));
+ rtgui_rect_inflate(&rect,-RTGUI_WIDGET_BORDER(fview));
+ RTGUI_DC_BC(dc) = white;
+ rtgui_dc_fill_rect(dc,&rect);
+ rtgui_rect_inflate(&rect,RTGUI_WIDGET_BORDER(fview));
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rect.x2 -= rtgui_rect_width(fview->sbar->parent.extent);
+
+ rect.x2 -=1; rect.y2 -= 1;
+
+ /* get item base rect */
+ item_rect = rect;
+ item_rect.x1 += RTGUI_WIDGET_BORDER(fview);
+ item_rect.x2 -= RTGUI_WIDGET_BORDER(fview); rx2 = item_rect.x2;
+ item_rect.y1 += RTGUI_WIDGET_BORDER(fview);
+ item_rect.y2 = item_rect.y1 + (1 + SELECTED_HEIGHT);
+
+ /* get image base rect */
+ image_rect.x1 = RTGUI_WIDGET_DEFAULT_MARGIN;
+ image_rect.y1 = 0;
+ image_rect.x2 = RTGUI_WIDGET_DEFAULT_MARGIN + file_image->w;
+ image_rect.y2 = file_image->h;
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+
+ //ȡ�õ�ǰҳ
+ frist = fview->frist_aloc;
+ for(i = 0; i < fview->item_per_page; i ++)
+ {
+ char str_size[16];
+
+ if(frist + i >= fview->item_count) break;
+
+ item = &(fview->items[frist + i]);
+
+ /* draw item image */
+ 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_WIDGET_DEFAULT_MARGIN + file_image->w + 2;
+ item_rect.x2 = item_rect.x1 + rtgui_font_get_string_width(RTGUI_DC_FONT(dc), item->name);
+ if(frist + i == fview->now_aloc)
+ {
+ if(RTGUI_WIDGET_IS_FOCUSED(fview))
+ {
+ RTGUI_DC_BC(dc) = selected_color;
+ RTGUI_DC_FC(dc) = white;
+ }
+ else
+ {
+ RTGUI_DC_BC(dc) = dark_grey;
+ RTGUI_DC_FC(dc) = black;
+ }
+ rtgui_dc_fill_rect(dc, &item_rect);
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+ else
+ {
+ /* draw background */
+ RTGUI_DC_BC(dc) = white;
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_fill_rect(dc,&item_rect);
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+
+
+ {//��ʾ�ļ���С��Ϣ
+ rtgui_rect_t rect=item_rect;
+ rect.x1 += 265;
+ rect.x2 = rect.x1+64;
+ if(item->type == RTGUI_FITEM_FILE)
+ rt_snprintf(str_size, 32, "%d",item->size);
+ else
+ rt_snprintf(str_size, 32, "%s","DIR");
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_draw_text(dc, str_size, &rect);
+ }
+
+ item_rect.x1 -= RTGUI_WIDGET_DEFAULT_MARGIN + file_image->w + 2;
+ item_rect.x2 = rx2;
+ /* move to next item position */
+ item_rect.y1 += (SELECTED_HEIGHT + 1);
+ item_rect.y2 += (SELECTED_HEIGHT + 1);
+
+ image_rect.y1 += (SELECTED_HEIGHT + 1);
+ image_rect.y2 += (SELECTED_HEIGHT + 1);
+ }
+
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ {
+ rtgui_theme_draw_scrollbar(fview->sbar);
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+//����FileView�Ľ���
+void rtgui_filelist_view_update_current(rtgui_filelist_view_t* fview)
+{
+ rtgui_filelist_view_item_t* item;
+ rtgui_rect_t rect, item_rect, image_rect;
+ rtgui_win_t* win;
+ struct OpenDlgSt *dlgst=RT_NULL;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(fview != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(fview);
+ if(dc == RT_NULL)return;
+
+ win = rtgui_win_get_win_by_widget(fview);
+ if(win == RT_NULL)return;
+ if(win->user_data != RT_NULL)
+ {
+ dlgst = (struct OpenDlgSt*)win->user_data;
+ }
+
+ //���ļ���Ϊ��ʱ��������
+ if(fview->items==RT_NULL)return;
+
+ rtgui_widget_get_rect(fview, &rect);
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rect.x2 -= rtgui_rect_width(fview->sbar->parent.extent);
+
+ if((fview->old_aloc >= fview->frist_aloc) &&
+ (fview->old_aloc < fview->frist_aloc+fview->item_per_page) &&
+ (fview->old_aloc != fview->now_aloc))
+ {//��Щ����,��������޶ȵļ��ٻ�ͼ��˸����
+ //ȡ�þɵ���Ŀ
+ item_rect = rect;
+ item_rect.x1 += RTGUI_WIDGET_BORDER(fview);
+ item_rect.x2 -= RTGUI_WIDGET_BORDER(fview);
+ item_rect.y1 += RTGUI_WIDGET_BORDER(fview);
+ item_rect.y1 += ((fview->old_aloc-fview->frist_aloc) % fview->item_per_page) * (1 + SELECTED_HEIGHT);
+ item_rect.y2 = item_rect.y1 + (1 + SELECTED_HEIGHT);
+
+ //ȡ��ͼ�����
+ image_rect.x1 = RTGUI_WIDGET_DEFAULT_MARGIN; image_rect.y1 = 0;
+ image_rect.x2 = RTGUI_WIDGET_DEFAULT_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ //���ƾɵ���Ŀ
+ item = &(fview->items[fview->old_aloc]);
+ 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_WIDGET_DEFAULT_MARGIN + file_image->w + 2;
+ item_rect.x2 = item_rect.x1 + rtgui_font_get_string_width(RTGUI_DC_FONT(dc), item->name);
+ RTGUI_DC_BC(dc) = white;
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_fill_rect(dc,&item_rect);
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+ //���Ƶ�ǰ��Ŀ
+ item_rect = rect;
+ item_rect.x1 += RTGUI_WIDGET_BORDER(fview);
+ item_rect.x2 -= RTGUI_WIDGET_BORDER(fview);
+ item_rect.y1 += RTGUI_WIDGET_BORDER(fview);
+ item_rect.y1 += ((fview->now_aloc-fview->frist_aloc) % fview->item_per_page) * (1 + SELECTED_HEIGHT);
+ item_rect.y2 = item_rect.y1 + (1 + SELECTED_HEIGHT);
+
+ /* get image base rect */
+ image_rect.x1 = RTGUI_WIDGET_DEFAULT_MARGIN; image_rect.y1 = 0;
+ image_rect.x2 = RTGUI_WIDGET_DEFAULT_MARGIN + file_image->w; image_rect.y2 = file_image->h;
+ rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
+
+ item = &(fview->items[fview->now_aloc]);
+ 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);
+
+ if(dlgst->filename) rt_free(dlgst->filename);
+ dlgst->filename = rt_strdup(item->name);
+ dlgst->type = item->type;
+ dlgst->size = item->size;
+
+ item_rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN + file_image->w + 2;
+ item_rect.x2 = item_rect.x1 + rtgui_font_get_string_width(RTGUI_DC_FONT(dc), item->name);
+
+ {
+ if(RTGUI_WIDGET_IS_FOCUSED(fview))
+ {
+ RTGUI_DC_BC(dc) = selected_color;
+ RTGUI_DC_FC(dc) = white;
+ }
+ else
+ {
+ RTGUI_DC_BC(dc) = dark_grey;
+ RTGUI_DC_FC(dc) = black;
+ }
+ rtgui_dc_fill_rect(dc, &item_rect);
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+ if(item->type == RTGUI_FITEM_FILE)
+ rtgui_textbox_set_value(dlgst->tbox_filename,dlgst->filename);
+ RTGUI_DC_FC(dc) = black;
+ rtgui_theme_draw_textbox(dlgst->tbox_filename);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_filelist_view_on_enter(rtgui_filelist_view_t* fview)
+{
+ if(fview->items==RT_NULL)return;
+ if(fview->item_count==0)return;
+
+ if(fview->items[fview->now_aloc].type == RTGUI_FITEM_DIR)
+ {//���
+ rtgui_filelist_view_on_folder_item(fview);
+ }
+ else
+ {//�ļ�
+
+ }
+}
+
+rt_bool_t rtgui_filelist_view_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_filelist_view_t* fview = RT_NULL;
+
+ fview = RTGUI_FILELIST_VIEW(widget);
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ rtgui_filelist_view_ondraw(fview);
+ return FALSE;
+
+ case RTGUI_EVENT_RESIZE:
+ {
+ rtgui_event_resize_t* resize;
+
+ resize = (rtgui_event_resize_t*)event;
+
+ /* recalculate page items */
+ if(file_image != RT_NULL)
+ fview->item_per_page = resize->h / (1 + SELECTED_HEIGHT);
+ else
+ fview->item_per_page = resize->h / (2 + 14);
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_rect_t rect;
+ rtgui_event_mouse_t* emouse;
+
+ emouse = (rtgui_event_mouse_t*)event;
+
+ //����ѡ�����Ŀλ��
+
+ rtgui_widget_focus(fview);
+ /* get physical extent information */
+ rtgui_widget_get_rect(fview, &rect);
+ rtgui_widget_rect_to_device(fview, &rect);
+
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rect.x2 -= rtgui_rect_width(fview->sbar->parent.extent);
+
+ if((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) && fview->item_count>0)
+ {
+ rt_uint16_t i;
+
+ i = (emouse->y - rect.y1) / (2 + SELECTED_HEIGHT);
+
+ /* set focus */
+ rtgui_widget_focus(fview);
+
+ if((i < fview->item_count) && (i < fview->item_per_page))
+ {
+ //����ѡ����
+ if(emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ fview->old_aloc = fview->now_aloc;
+ fview->now_aloc = fview->frist_aloc + i;
+ rtgui_filelist_view_update_current(fview);
+ }
+ else if(emouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ if(fview->now_aloc==fview->old_aloc) return FALSE;
+
+ rtgui_filelist_view_update_current(fview);
+ }
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rtgui_scrollbar_set_value(fview->sbar,fview->frist_aloc);
+ }
+ }
+ return TRUE;
+ }
+ }
+ break;
+
+ case RTGUI_EVENT_KBD:
+ {
+ rtgui_event_kbd_t* ekbd = (rtgui_event_kbd_t*)event;
+ if(RTGUI_KBD_IS_DOWN(ekbd))
+ {
+ switch (ekbd->key)
+ {
+ case RTGUIK_UP: //һ���Ϸ�һ��
+ if(fview->now_aloc > 0)
+ {
+ fview->old_aloc = fview->now_aloc;
+ fview->now_aloc --;
+
+ if(fview->now_aloc < fview->frist_aloc)
+ {//���Ϸ�ҳ��
+ fview->frist_aloc = fview->now_aloc;
+ rtgui_filelist_view_ondraw(fview);
+ }
+ else
+ {//��ǰҳ��
+ rtgui_filelist_view_update_current(fview);
+ }
+
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rtgui_scrollbar_set_value(fview->sbar,fview->frist_aloc);
+ }
+ }
+ return TRUE;
+
+ case RTGUIK_DOWN: //һ���·�һ��
+ if(fview->now_aloc < fview->item_count-1)
+ {
+ fview->old_aloc = fview->now_aloc;
+ fview->now_aloc ++;
+
+ if(fview->now_aloc >= fview->frist_aloc+fview->item_per_page)
+ {//��ҳ��
+ fview->frist_aloc++;
+ rtgui_filelist_view_ondraw(fview);
+ }
+ else
+ {//�ڵ�ǰҳ��
+ rtgui_filelist_view_update_current(fview);
+ }
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rtgui_scrollbar_set_value(fview->sbar,fview->frist_aloc);
+ }
+ }
+ return TRUE;
+
+ case RTGUIK_LEFT:
+ if(fview->item_count==0)return FALSE;
+ fview->old_aloc = fview->now_aloc;
+ fview->now_aloc -= fview->item_per_page;
+
+ if(fview->now_aloc < 0)
+ fview->now_aloc = 0;
+
+ if(fview->now_aloc < fview->frist_aloc)
+ {
+ fview->frist_aloc = fview->now_aloc;
+ rtgui_filelist_view_ondraw(fview);
+ }
+ else
+ {
+ rtgui_filelist_view_update_current(fview);
+ }
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rtgui_scrollbar_set_value(fview->sbar,fview->frist_aloc);
+ }
+ return TRUE;
+
+ case RTGUIK_RIGHT:
+ if(fview->item_count==0)return FALSE;
+ fview->old_aloc = fview->now_aloc;
+ fview->now_aloc += fview->item_per_page;
+
+ if(fview->now_aloc > fview->item_count-1)
+ fview->now_aloc = fview->item_count-1;
+
+ if(fview->now_aloc >= fview->frist_aloc+fview->item_per_page)
+ {
+ fview->frist_aloc += fview->item_per_page;
+ if(fview->frist_aloc >fview->item_count-fview->item_per_page)
+ {
+ fview->frist_aloc = fview->item_count-fview->item_per_page;
+ fview->now_aloc = fview->frist_aloc;
+ }
+ rtgui_filelist_view_ondraw(fview);
+ }
+ else
+ {
+ rtgui_filelist_view_update_current(fview);
+ }
+ if(fview->sbar && !RTGUI_WIDGET_IS_HIDE(fview))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(fview->sbar))
+ rtgui_scrollbar_set_value(fview->sbar,fview->frist_aloc);
+ }
+ return TRUE;
+
+ case RTGUIK_RETURN:
+ //GoToSubFolder(fview,RT_NULL);
+ return TRUE;
+ case RTGUIK_BACKSPACE:
+ //GoToTopFolder(fview,RT_NULL);
+ return TRUE;
+ default:
+ break;
+ }
+ }
+ }
+ return FALSE;
+ default:
+ return rtgui_container_event_handler(widget, event);
+ }
+
+ /* use view event handler */
+ return rtgui_container_event_handler(widget, event);
+}
+
+/* clear all file items */
+static void rtgui_filelist_view_clear(rtgui_filelist_view_t* fview)
+{
+ rt_uint32_t index;
+ rtgui_filelist_view_item_t* item;
+
+ if(fview->items == RT_NULL) return;
+
+ for(index = 0; index < fview->item_count; index ++)
+ {
+ item = &(fview->items[index]);
+
+ /* release item name */
+ if(item->name != RT_NULL)
+ {
+ rt_free(item->name);
+ item->name = RT_NULL;
+ }
+ }
+
+ /* release items */
+ rt_free(fview->items);
+ fview->items = RT_NULL;
+
+ fview->item_count = 0;
+ fview->now_aloc = 0;
+}
+
+void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* fview, const char* directory)
+{
+ char fullpath[256];
+ rtgui_filelist_view_item_t *item;
+ rtgui_win_t* win;
+ struct OpenDlgSt* dlgst=RT_NULL;
+
+ win = rtgui_win_get_win_by_widget(fview);
+ if(win == RT_NULL)return;
+ if(win->user_data != RT_NULL)
+ {
+ dlgst = (struct OpenDlgSt*)win->user_data;
+ }
+
+ fview->frist_aloc = 0;
+
+ //��������ļ���Ŀ
+ rtgui_filelist_view_clear(fview);
+ if(directory != RT_NULL)
+ {
+ DIR* dir;
+ struct stat s;
+ rt_uint32_t i;
+ struct dirent* dirent;
+
+ fview->item_count = 0;
+ //�����
+ dir = opendir(directory);
+ if(dir == RT_NULL) goto __return;
+
+ //���õ�ǰ�ļ���
+ if(fview->current_dir != RT_NULL)
+ rt_free(fview->current_dir);
+ fview->current_dir = rt_strdup(directory);
+
+ if(dlgst->path != RT_NULL) rt_free(dlgst->path);
+ dlgst->path = rt_strdup(fview->current_dir);
+
+ rtgui_textbox_set_value(dlgst->tbox_path,dlgst->path);
+ rtgui_theme_draw_textbox(dlgst->tbox_path);
+
+ do{
+ dirent = readdir(dir);
+ if(dirent == RT_NULL) break;
+ fview->item_count ++;
+ }while (dirent != RT_NULL);
+ closedir(dir);
+
+ if((fview->item_count > fview->item_per_page) && fview->sbar!=RT_NULL)
+ {
+ RTGUI_WIDGET_UNHIDE(fview->sbar);
+ rtgui_scrollbar_set_line_step(fview->sbar,1);
+ rtgui_scrollbar_set_page_step(fview->sbar, fview->item_per_page);
+ rtgui_scrollbar_set_range(fview->sbar, fview->item_count);
+ }
+ else
+ {
+ RTGUI_WIDGET_HIDE(fview->sbar);
+ }
+ rtgui_widget_update_clip(fview);
+
+ //����һ�����Է���������Ŀ�Ŀռ�
+ fview->items = (rtgui_filelist_view_item_t*) rt_malloc(sizeof(rtgui_filelist_view_item_t) * fview->item_count);
+
+ if(fview->items == RT_NULL) goto __return; /*under the folder has not sub files. */
+
+ //���´��ļ���
+ dir = opendir(directory);
+ if(dir == RT_NULL) goto __return;
+
+ for(i=0; i < fview->item_count; i ++)
+ {
+ dirent = readdir(dir);
+ if(dirent == RT_NULL) break;
+
+ item = &(fview->items[i]);
+ item->name = rt_strdup(dirent->d_name);
+
+ rt_memset(&s, 0, sizeof(struct stat));
+
+ //����ÿ���ļ���ȫ·��
+ if(directory[strlen(directory) - 1] != PATH_SEPARATOR)
+ rt_sprintf(fullpath, "%s%c%s", directory, PATH_SEPARATOR, dirent->d_name);
+ else
+ rt_sprintf(fullpath, "%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;
+ }
+ }
+
+ closedir(dir);
+ }
+
+ fview->now_aloc = 0;
+
+__return:
+ /* update view */
+ rtgui_widget_update(fview);
+}
+
+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_dir[strlen(view->current_dir) - 1] != PATH_SEPARATOR)
+ rt_snprintf(path, len, "%s%c%s",view->current_dir, PATH_SEPARATOR,
+ view->items[view->now_aloc].name);
+ else
+ rt_snprintf(path, len, "%s%s",view->current_dir,
+ view->items[view->now_aloc].name);
+}
+
+static rt_bool_t rtgui_fileview_onunfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_filelist_view_t *fview = (rtgui_filelist_view_t*)wdt;
+
+ if(fview == RT_NULL) return FALSE;
+
+ if(!RTGUI_WIDGET_IS_FOCUSED(fview))
+ {//��������
+ rtgui_filelist_view_update_current(fview);
+ }
+
+ return TRUE;
+}
+
+static rt_bool_t rtgui_fileview_sbar_handle(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_filelist_view_t *fview = (rtgui_filelist_view_t*)wdt;
+
+ fview->frist_aloc = fview->sbar->value;
+
+ rtgui_filelist_view_ondraw(fview);
+
+ return TRUE;
+}
+
+
diff --git a/components/rtgui_win/widgets/folder.xpm b/components/rtgui_win/widgets/folder.xpm
new file mode 100644
index 0000000000..f5feb65555
--- /dev/null
+++ b/components/rtgui_win/widgets/folder.xpm
@@ -0,0 +1,142 @@
+/* XPM */
+static const 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 ` ",
+" ...+.@.#.$.%.&.*.=.-.;.>. . ",
+" ,.'.).!.~.{.].^./.(._.:.<.,. ",
+" [.}.[.[.[.[.[.[.[.[.}.[.|. ",
+" ",
+" "
+};
+
diff --git a/components/rtgui_win/widgets/iconbox.c b/components/rtgui_win/widgets/iconbox.c
new file mode 100644
index 0000000000..6040b9b093
--- /dev/null
+++ b/components/rtgui_win/widgets/iconbox.c
@@ -0,0 +1,221 @@
+/*
+ * File : iconbox.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
+ */
+#include <rtgui/dc.h>
+
+#include <rtgui/widgets/iconbox.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/font.h>
+
+static rt_bool_t rtgui_iconbox_onfocus(PVOID wdt, rtgui_event_t* event);
+static rt_bool_t rtgui_iconbox_onunfocus(PVOID wdt, rtgui_event_t* event);
+
+static void _rtgui_iconbox_constructor(rtgui_iconbox_t *iconbox)
+{
+ /* init widget and set event handler */
+ rtgui_widget_set_event_handler(iconbox, rtgui_iconbox_event_handler);
+ RTGUI_WIDGET_FLAG(iconbox) |= RTGUI_WIDGET_FLAG_TRANSPARENT;
+ /* set proper of control */
+ iconbox->image = RT_NULL;
+ iconbox->selected = RT_FALSE;
+ iconbox->text = RT_NULL;
+ iconbox->text_position = RTGUI_ICONBOX_TEXT_BELOW;
+ iconbox->call = RT_NULL;
+
+ rtgui_widget_set_onfocus(iconbox,rtgui_iconbox_onfocus);
+ rtgui_widget_set_onunfocus(iconbox,rtgui_iconbox_onunfocus);
+}
+
+static void _rtgui_iconbox_destructor(rtgui_iconbox_t *iconbox)
+{
+ if(iconbox->image != RT_NULL)
+ {
+ rtgui_image_destroy(iconbox->image);
+ iconbox->image = RT_NULL;
+ }
+ if(iconbox->text != RT_NULL)
+ {
+ rt_free(iconbox->text);
+ iconbox->text = RT_NULL;
+ }
+}
+
+rtgui_type_t *rtgui_iconbox_type_get(void)
+{
+ static rtgui_type_t *iconbox_type = RT_NULL;
+
+ if(!iconbox_type)
+ {
+ iconbox_type = rtgui_type_create("iconbox", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_iconbox_t), RTGUI_CONSTRUCTOR(_rtgui_iconbox_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_iconbox_destructor));
+ }
+
+ return iconbox_type;
+}
+
+rt_bool_t rtgui_iconbox_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_iconbox_t* iconbox = (rtgui_iconbox_t*)widget;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ {
+ rtgui_theme_draw_iconbox(iconbox);
+ }
+
+ break;
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ rtgui_widget_focus(wdt);
+ if(iconbox->call)
+ iconbox->call();
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+rtgui_iconbox_t* rtgui_iconbox_create(PVOID parent, rtgui_image_t* image,const char* text,int position)
+{
+ rtgui_iconbox_t* iconbox;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ iconbox = rtgui_widget_create(RTGUI_ICONBOX_TYPE);
+ if(iconbox != RT_NULL)
+ {
+ rtgui_rect_t rect, text_rect;
+
+ rect.x2 = image->w;
+ rect.y2 = image->h;
+
+ /* get text rect */
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(iconbox), text, &text_rect);
+ if(position == RTGUI_ICONBOX_TEXT_BELOW)
+ {
+ rect.y2 += RTGUI_WIDGET_DEFAULT_MARGIN;
+ if(text_rect.x2 > rect.x2)
+ {
+ rect.x2 = text_rect.x2;
+ }
+ rect.y2 += text_rect.y2;
+ }
+ else if(position == RTGUI_ICONBOX_TEXT_RIGHT)
+ {
+ rect.x2 += RTGUI_WIDGET_DEFAULT_MARGIN;
+ if(text_rect.y2 > rect.y2)
+ {
+ rect.y2 = text_rect.y2;
+ }
+ rect.x2 += text_rect.x2;
+ }
+
+ /* set widget rect */
+ rtgui_widget_set_rect(iconbox, &rect);
+
+ /* set image and text position */
+ iconbox->image = image;
+ iconbox->text = rt_strdup(text);
+ iconbox->text_position = position;
+
+ rtgui_container_add_child(parent, iconbox);
+ }
+
+ return iconbox;
+}
+
+void rtgui_iconbox_destroy(rtgui_iconbox_t* iconbox)
+{
+ rtgui_widget_destroy(iconbox);
+}
+
+void rtgui_iconbox_set_text_position(rtgui_iconbox_t* iconbox, int position)
+{
+ rtgui_rect_t rect = {0, 0, 0, 0}, text_rect;
+
+ RT_ASSERT(iconbox != RT_NULL);
+
+ iconbox->text_position = position;
+
+ /* set mini width and height */
+ rect.x2 = iconbox->image->w;
+ rect.y2 = iconbox->image->h;
+
+ /* get text rect */
+ if(iconbox->text != RT_NULL)
+ {
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(iconbox),
+ iconbox->text, &text_rect);
+ if(position == RTGUI_ICONBOX_TEXT_BELOW)
+ {
+ rect.y2 += RTGUI_WIDGET_DEFAULT_MARGIN;
+ if(text_rect.x2 > rect.x2)
+ {
+ rect.x2 = text_rect.x2;
+ }
+ rect.y2 += text_rect.y2;
+ }
+ else if(position == RTGUI_ICONBOX_TEXT_RIGHT)
+ {
+ rect.x2 += RTGUI_WIDGET_DEFAULT_MARGIN;
+ if(text_rect.y2 > rect.y2)
+ {
+ rect.y2 = text_rect.y2;
+ }
+ rect.x2 += text_rect.x2;
+ }
+ }
+}
+
+static rt_bool_t rtgui_iconbox_onfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_rect_t rect;
+ rtgui_dc_t *dc;
+
+ RT_ASSERT(wdt != RT_NULL);
+
+ dc = rtgui_dc_begin_drawing(wdt);
+ if(dc == RT_NULL)return RT_FALSE;
+
+ rtgui_widget_get_rect(wdt,&rect);
+ rtgui_dc_draw_focus_rect(dc,&rect);
+
+ rtgui_dc_end_drawing(dc);
+
+ return RT_TRUE;
+}
+
+static rt_bool_t rtgui_iconbox_onunfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_rect_t rect;
+ rtgui_dc_t *dc;
+
+ RT_ASSERT(wdt != RT_NULL);
+
+ dc = rtgui_dc_begin_drawing(wdt);
+ if(dc == RT_NULL)return RT_FALSE;
+
+ rtgui_widget_get_rect(wdt,&rect);
+ RTGUI_DC_FC(dc) = RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(wdt)->parent);
+ rtgui_dc_draw_focus_rect(dc,&rect);
+
+ rtgui_dc_end_drawing(dc);
+
+ return RT_TRUE;
+}
+
diff --git a/components/rtgui_win/widgets/label.c b/components/rtgui_win/widgets/label.c
new file mode 100644
index 0000000000..608252c07a
--- /dev/null
+++ b/components/rtgui_win/widgets/label.c
@@ -0,0 +1,135 @@
+/*
+ * File : label.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
+ */
+#include <rtgui/dc.h>
+#include <rtgui/widgets/label.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_theme.h>
+
+static void _rtgui_label_constructor(rtgui_label_t *label)
+{
+ /* init widget and set event handler */
+ rtgui_widget_set_event_handler(label, rtgui_label_event_handler);
+
+ RTGUI_WIDGET_FOREGROUND(label) = black;
+ RTGUI_WIDGET_BACKGROUND(label) = default_background;
+ RTGUI_WIDGET_TEXTALIGN(label) = RTGUI_ALIGN_CENTER_VERTICAL;
+ /* set field */
+ label->text = RT_NULL;
+}
+
+static void _rtgui_label_destructor(rtgui_label_t *label)
+{
+ /* release text memory */
+ if(label->text != RT_NULL)
+ {
+ rt_free(label->text);
+ label->text = RT_NULL;
+ }
+}
+
+rtgui_type_t *rtgui_label_type_get(void)
+{
+ static rtgui_type_t *label_type = RT_NULL;
+
+ if(!label_type)
+ {
+ label_type = rtgui_type_create("label", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_label_t),
+ RTGUI_CONSTRUCTOR(_rtgui_label_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_label_destructor));
+ }
+
+ return label_type;
+}
+
+rt_bool_t rtgui_label_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_label_t* label;
+
+ RT_ASSERT(widget != RT_NULL);
+
+ label = (rtgui_label_t*) widget;
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ rtgui_theme_draw_label(label);
+ break;
+ default:
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+//parent������һ��������ؼ�
+rtgui_label_t* rtgui_label_create(PVOID parent, const char* text,int left, int top, int w, int h)
+{
+ rtgui_label_t* label;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ label = rtgui_widget_create(RTGUI_LABEL_TYPE);
+ if(label != RT_NULL)
+ {
+ rtgui_rect_t rect;
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(label, &rect);
+
+ label->text = rt_strdup(text);
+
+ rtgui_container_add_child(parent, label);
+ }
+
+ return label;
+}
+
+void rtgui_label_destroy(rtgui_label_t* label)
+{
+ rtgui_widget_destroy(label);
+}
+
+char* rtgui_label_get_text(rtgui_label_t* label)
+{
+ if(label == RT_NULL)return RT_NULL;
+
+ return label->text;
+}
+
+void rtgui_label_set_text(rtgui_label_t* label, const char* text)
+{
+ if(label == RT_NULL)return;
+
+ if(strcmp(text,label->text)==0)return;
+
+ if(label->text != RT_NULL)
+ {
+ /* release old text memory */
+ rt_free(label->text);
+ label->text = RT_NULL;
+ }
+
+ if(text != RT_NULL)
+ label->text = rt_strdup(text);
+ else
+ label->text = RT_NULL;
+
+ /* update widget */
+ rtgui_theme_draw_label(label);//�þ��ƺ��Ƕ����,�������Ͻ�(0,0)����һ���ַ���
+}
diff --git a/components/rtgui_win/widgets/list_view.c b/components/rtgui_win/widgets/list_view.c
new file mode 100644
index 0000000000..ced1ca157e
--- /dev/null
+++ b/components/rtgui_win/widgets/list_view.c
@@ -0,0 +1,667 @@
+/*
+ * 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>
+
+static void _rtgui_list_view_constructor(rtgui_list_view_t *view)
+{
+ /* default rect */
+ rtgui_rect_t rect = {0, 0, 200, 200};
+
+ /* set default widget rect and set event handler */
+ rtgui_widget_set_event_handler(view,rtgui_list_view_event_handler);
+ rtgui_widget_set_rect(view, &rect);
+
+ RTGUI_WIDGET_FLAG(view) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ view->flag = RTGUI_LIST_VIEW_LIST;
+ view->item_current = 0;
+ view->item_count = 0;
+ view->page = 0;
+
+ RTGUI_WIDGET_BACKGROUND(view) = white;
+ RTGUI_WIDGET_TEXTALIGN(view) = RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+static void _rtgui_list_view_destructor(rtgui_list_view_t *view)
+{
+
+}
+
+rtgui_type_t *rtgui_list_view_type_get(void)
+{
+ static rtgui_type_t *list_view_type = RT_NULL;
+
+ if(!list_view_type)
+ {
+ list_view_type = rtgui_type_create("listview", RTGUI_VIEW_TYPE,
+ sizeof(rtgui_list_view_t),
+ RTGUI_CONSTRUCTOR(_rtgui_list_view_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_list_view_destructor));
+ }
+
+ return list_view_type;
+}
+
+static void rtgui_list_view_onicondraw(rtgui_list_view_t* view)
+{
+ rtgui_rect_t rect, item_rect, drawing_rect;
+ rt_uint32_t c, r, i; /* col and row index */
+ rt_uint32_t item_width, item_height;
+ rtgui_image_t* image;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(view != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(view);
+ if(dc == RT_NULL)return;
+
+ if(view->item_count == 0) return;
+
+ rtgui_widget_get_rect(view, &rect);
+ i = (view->item_current / view->page) * view->page;
+
+ item_width = (rtgui_rect_width(rect) - 2 * RTGUI_WIDGET_DEFAULT_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(i < view->item_count)
+ {
+ item_rect.y1 = rect.y1 + RTGUI_WIDGET_DEFAULT_MARGIN + r * item_height;
+ item_rect.x1 = rect.x1 + RTGUI_WIDGET_DEFAULT_MARGIN + c * item_width;
+ item_rect.x2 = item_rect.x1 + item_width;
+ item_rect.y2 = item_rect.y1 + item_height;
+
+ if(i == view->item_current)
+ {
+ RTGUI_DC_BC(dc) = selected_color;
+ rtgui_dc_fill_rect(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 += 3; drawing_rect.y2 += 3;
+ rtgui_image_blit(view->items[i].image, dc, &drawing_rect);
+
+ item_rect.y1 = drawing_rect.y2 + RTGUI_WIDGET_DEFAULT_MARGIN;
+ item_rect.x1 += 3; item_rect.x2 -=3;
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(view), view->items[i].name,
+ &drawing_rect);
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ rtgui_dc_draw_text(dc, view->items[i].name, &drawing_rect);
+
+ i ++;
+ }
+ else break;
+ }
+ }
+ rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_list_view_update_icon(rtgui_list_view_t* view, rt_uint16_t old_item)
+{
+ rtgui_rect_t rect, item_rect, drawing_rect;
+ rt_uint32_t c, r; /* col and row index */
+ rt_uint32_t item_width, item_height;
+ rtgui_image_t* image;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(view != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(view);
+ if(dc == RT_NULL)return;
+
+ if((view->item_count == 0) ||
+ (old_item == view->item_current))
+ return;
+
+ if(old_item/view->page != view->item_current/view->page)
+ {
+ /* it's not a same page, update all */
+ rtgui_widget_update(view);
+ return;
+ }
+
+ rtgui_widget_get_rect(view, &rect);
+
+ item_width = (rtgui_rect_width(rect) - 2 * RTGUI_WIDGET_DEFAULT_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)/ view->col_items;
+ c = (old_item % view->page)% view->col_items;
+ item_rect.y1 = rect.y1 + RTGUI_WIDGET_DEFAULT_MARGIN + r * item_height;
+ item_rect.x1 = rect.x1 + RTGUI_WIDGET_DEFAULT_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 += 3; drawing_rect.y2 += 3;
+ rtgui_image_blit(view->items[old_item].image, dc,&drawing_rect);
+
+ /* draw text */
+ item_rect.y1 = drawing_rect.y2 + RTGUI_WIDGET_DEFAULT_MARGIN;
+ item_rect.x1 += 3; item_rect.x2 -=3;
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(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->item_current % view->page) / view->col_items;
+ c = (view->item_current % view->page) % view->col_items;
+ item_rect.y1 = rect.y1 + RTGUI_WIDGET_DEFAULT_MARGIN + r * item_height;
+ item_rect.x1 = rect.x1 + RTGUI_WIDGET_DEFAULT_MARGIN + c * item_width;
+ item_rect.x2 = item_rect.x1 + item_width;
+ item_rect.y2 = item_rect.y1 + item_height;
+ RTGUI_DC_BC(dc) = selected_color;
+ rtgui_dc_fill_rect(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->item_current].image, dc, &drawing_rect);
+
+ /* draw text */
+ item_rect.y1 = drawing_rect.y2 + RTGUI_WIDGET_DEFAULT_MARGIN;
+ item_rect.x1 += 3; item_rect.x2 -=3;
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(view),
+ view->items[view->item_current].name,
+ &drawing_rect);
+ rtgui_rect_moveto_align(&item_rect, &drawing_rect, RTGUI_ALIGN_CENTER_HORIZONTAL);
+ rtgui_dc_draw_text(dc, view->items[view->item_current].name, &drawing_rect);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_list_view_onlistdraw(rtgui_list_view_t* view)
+{
+ rt_uint32_t i, page;
+ rtgui_rect_t rect, item_rect, image_rect;
+ const rtgui_list_view_item_t* item;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(view != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(view);
+ if(dc == RT_NULL)return;
+
+ rtgui_widget_get_rect(view, &rect);
+
+ /* get item base rect */
+ item_rect = rect;
+ item_rect.x1 += 2;
+ item_rect.x2 -= 2;
+ item_rect.y1 += 2;
+ item_rect.y2 = item_rect.y1 + (2 + SELECTED_HEIGHT);
+
+ /* get current page */
+ page = (view->item_current / view->page) * view->page;
+ for(i = 0; i < view->page; i ++)
+ {
+ if(page + i >= view->item_count) break;
+
+ item = &(view->items[page + i]);
+
+ if(page + i == view->item_current)
+ {
+ RTGUI_DC_BC(dc) = selected_color;
+ rtgui_dc_fill_rect(dc, &item_rect);
+ }
+ item_rect.x1 += RTGUI_WIDGET_DEFAULT_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 -= RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ /* move to next item position */
+ item_rect.y1 += (SELECTED_HEIGHT + 2);
+ item_rect.y2 += (SELECTED_HEIGHT + 2);
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_list_view_update_list(rtgui_list_view_t* view, rt_uint16_t old_item)
+{
+ const rtgui_list_view_item_t* item;
+ rtgui_rect_t rect, item_rect;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(view != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(view);
+ if(dc == RT_NULL)return;
+
+ if(old_item/view->page != view->item_current/view->page)
+ {
+ /* it's not a same page, update all */
+ rtgui_widget_update(view);
+ return;
+ }
+
+ //������һ����Ŀ
+ rtgui_widget_get_rect(view, &rect);
+ item_rect = rect;
+ item_rect.x1 += 2;
+ item_rect.x2 -= 2;
+ item_rect.y1 += 2;
+ item_rect.y1 += (old_item % view->page) * (2 + SELECTED_HEIGHT);
+ item_rect.y2 = item_rect.y1 + (2 + SELECTED_HEIGHT);
+
+ rtgui_dc_fill_rect(dc,&item_rect);
+
+ item_rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ item = &(view->items[old_item]);
+ if(item->image != RT_NULL)
+ {
+ rtgui_rect_t 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);
+
+ //���Ƶ�ǰ��
+ item_rect = rect;
+ /* get current item's rect */
+ item_rect.x1 += 2;
+ item_rect.x2 -= 2;
+ item_rect.y1 += 2;
+ item_rect.y1 += (view->item_current % view->page) * (2 + SELECTED_HEIGHT);
+ item_rect.y2 = item_rect.y1 + (2 + SELECTED_HEIGHT);
+
+ /* draw current item */
+ RTGUI_DC_BC(dc) = selected_color;
+ rtgui_dc_fill_rect(dc, &item_rect);
+
+ item_rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ item = &(view->items[view->item_current]);
+ if(item->image != RT_NULL)
+ {
+ rtgui_rect_t 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_FC(dc) = white;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+
+ rtgui_dc_end_drawing(dc);
+}
+
+void rtgui_list_view_ondraw(rtgui_list_view_t* view)
+{
+ rtgui_rect_t rect;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(view != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(view);
+ if(dc == RT_NULL)return;
+
+ rtgui_widget_get_rect(view, &rect);
+ rtgui_dc_fill_rect(dc,&rect);
+
+ switch (view->flag)
+ {
+ case RTGUI_LIST_VIEW_LIST:
+ rtgui_list_view_onlistdraw(view);
+ break;
+
+ case RTGUI_LIST_VIEW_ICON:
+ rtgui_list_view_onicondraw(view);
+ break;
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+static rt_bool_t rtgui_list_view_onmouse(rtgui_list_view_t* view, rtgui_event_mouse_t* emouse)
+{
+ rtgui_rect_t rect;
+
+ /* calculate selected item */
+
+ /* get physical extent information */
+ rtgui_widget_get_rect(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->item_current;
+
+ switch (view->flag)
+ {
+ case RTGUI_LIST_VIEW_LIST:
+ index = (emouse->y - rect.y1) / (2 + SELECTED_HEIGHT);
+
+ if((index < view->item_count) && (index < view->page))
+ {
+ /* set selected item */
+ view->item_current = (view->item_current/view->page) * view->page + 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->item_current].action != RT_NULL)
+ {
+ view->items[view->item_current].action(view->items[view->item_current].parameter);
+ }
+ }
+ }
+ break;
+
+ case RTGUI_LIST_VIEW_ICON:
+ {
+ rt_uint16_t x, y;
+ rt_uint16_t item_height, item_width;
+ rt_uint32_t current_page;
+
+ item_width = (rtgui_rect_width(rect) - 2 * RTGUI_WIDGET_DEFAULT_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->item_current / view->page;
+
+ if((index + (current_page * view->page) < view->item_count))
+ {
+ if(emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ view->item_current = index + (current_page * view->page);
+
+ /* down event */
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ else
+ {
+ /* up event */
+ if(view->items[view->item_current].action != RT_NULL)
+ {
+ view->items[view->item_current].action(view->items[view->item_current].parameter);
+ }
+ }
+ }
+ }
+ break;
+
+ case RTGUI_LIST_VIEW_REPORT:
+ break;
+ }
+
+ return RT_TRUE;
+ }
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_list_view_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_list_view_t* 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:
+ {
+ rtgui_event_resize_t* resize;
+
+ resize = (rtgui_event_resize_t*)event;
+
+ /* recalculate page items */
+ view->page = resize->h / (2 + SELECTED_HEIGHT);
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_event_mouse_t* emouse;
+
+ emouse = (rtgui_event_mouse_t*)event;
+ return rtgui_list_view_onmouse(view, emouse);
+ }
+
+ case RTGUI_EVENT_KBD:
+ {
+ rtgui_event_kbd_t* ekbd = (rtgui_event_kbd_t*)event;
+ if(RTGUI_KBD_IS_DOWN(ekbd))
+ {
+ rt_uint16_t old_item;
+
+ old_item = view->item_current;
+ switch (ekbd->key)
+ {
+ case RTGUIK_LEFT:
+ if(view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if(view->item_current - view->page >= 0)
+ view->item_current -= view->page;
+
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if(view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if(view->item_current > 0)
+ view->item_current --;
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_UP:
+ if(view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if(view->item_current > 0)
+ view->item_current --;
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if(view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if(view->item_current >= view->col_items)
+ view->item_current -= view->col_items;
+ else
+ view->item_current = 0;
+
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_RIGHT:
+ if(view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if(view->item_current + view->page < view->item_count - 1)
+ view->item_current += view->page;
+
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if(view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if(view->item_current < view->item_count - 1)
+ view->item_current ++;
+
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_DOWN:
+ if(view->flag == RTGUI_LIST_VIEW_LIST)
+ {
+ if(view->item_current < view->item_count - 1)
+ view->item_current ++;
+
+ rtgui_list_view_update_list(view, old_item);
+ }
+ else if(view->flag == RTGUI_LIST_VIEW_ICON)
+ {
+ if(view->item_current + view->col_items <= (view->item_count - 1))
+ view->item_current += view->col_items;
+ else
+ view->item_current = view->item_count - 1;
+
+ rtgui_list_view_update_icon(view, old_item);
+ }
+ return RT_FALSE;
+
+ case RTGUIK_RETURN:
+ if(view->items[view->item_current].action != RT_NULL)
+ {
+ view->items[view->item_current].action(view->items[view->item_current].parameter);
+ }
+ return RT_FALSE;
+
+ default:
+ break;
+ }
+ }
+ }
+ return RT_FALSE;
+
+ default:
+ break;
+ }
+
+ /* use view event handler */
+ return rtgui_view_event_handler(widget, event);
+}
+
+static void rtgui_list_view_calc(rtgui_list_view_t* view)
+{
+ /* get image of first item*/
+ rtgui_image_t *image;
+ rtgui_rect_t rect;
+ rt_uint32_t text_width, text_height;
+ rt_uint32_t item_width, item_height;
+
+ if(view->item_count == 0) return;
+
+ image = view->items[0].image;
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(view), "HHHHHH", &rect);
+
+ text_height = rtgui_rect_height(rect);
+ text_width = rtgui_rect_width(rect);
+
+ rtgui_widget_get_rect(view, &rect);
+
+ item_width = image->w + RTGUI_WIDGET_DEFAULT_MARGIN;
+ if(item_width < (text_width + RTGUI_WIDGET_DEFAULT_MARGIN)) item_width = text_width + RTGUI_WIDGET_DEFAULT_MARGIN;
+ item_height = image->h + 3 + text_height + RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ view->row_items = (rtgui_rect_height(rect) - 2 * RTGUI_WIDGET_DEFAULT_MARGIN) / item_height;
+ view->col_items = (rtgui_rect_width(rect) - 2 * RTGUI_WIDGET_DEFAULT_MARGIN) / item_width;
+ view->page = view->row_items * view->col_items;
+}
+
+rtgui_list_view_t* rtgui_list_view_create(PVOID parent,const rtgui_list_view_item_t* items, rt_uint16_t count, int left,int top,int w,int h, rt_uint16_t flag)
+{
+ rtgui_list_view_t* view = RT_NULL;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ view = rtgui_widget_create(RTGUI_LIST_VIEW_TYPE);
+ if(view != RT_NULL)
+ {
+ rtgui_rect_t rect;
+ view->items = items;
+ view->item_count = count;
+
+ view->flag = flag;
+ rtgui_widget_get_rect(view, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(view, &rect);
+
+ if(flag == RTGUI_LIST_VIEW_LIST)
+ view->page = rtgui_rect_height(rect) / (2 + SELECTED_HEIGHT);
+ else if((flag == RTGUI_LIST_VIEW_ICON) && (count > 0))
+ {
+ rtgui_list_view_calc(view);
+ }
+ rtgui_container_add_child(parent, view);
+ }
+
+ return view;
+}
+
+void rtgui_list_view_destroy(rtgui_list_view_t* view)
+{
+ /* destroy view */
+ rtgui_widget_destroy(view);
+}
diff --git a/components/rtgui_win/widgets/listbox.c b/components/rtgui_win/widgets/listbox.c
new file mode 100644
index 0000000000..086a140ca4
--- /dev/null
+++ b/components/rtgui_win/widgets/listbox.c
@@ -0,0 +1,728 @@
+/*
+ * 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 RTGUI_WIDGET_DEFAULT_MARGIN 3
+
+static rt_bool_t rtgui_listbox_unfocus(PVOID wdt, rtgui_event_t* event);
+static rt_bool_t rtgui_listbox_sbar_handle(PVOID wdt, rtgui_event_t* event);
+static rt_uint32_t rtgui_listbox_get_item_count(rtgui_listbox_t* box);
+static void rtgui_listbox_add_item(rtgui_listbox_t* box,rtgui_listbox_item_t* item);
+
+static void _rtgui_listbox_constructor(rtgui_listbox_t *box)
+{
+ /* set default widget rect and set event handler */
+ rtgui_widget_set_event_handler(box,rtgui_listbox_event_handler);
+ rtgui_widget_set_onunfocus(box, rtgui_listbox_unfocus);
+ RTGUI_WIDGET_FLAG(box) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ box->frist_aloc = 0;
+ box->now_aloc = 0;
+ box->old_aloc = 0;
+ box->item_count = 0;
+ box->item_size = SELECTED_HEIGHT;
+ box->item_per_page = 0;
+ box->ispopup = RT_FALSE;
+ box->widgetlnk = RT_NULL;
+
+ RTGUI_WIDGET_BACKGROUND(box) = white;
+ RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_LEFT|RTGUI_ALIGN_CENTER_VERTICAL;
+
+ box->items = RT_NULL;
+ box->sbar = RT_NULL;
+
+ box->on_item = RT_NULL;
+
+ box->get_count = rtgui_listbox_get_item_count;
+ box->add_item = rtgui_listbox_add_item;
+}
+static void _rtgui_listbox_destructor(rtgui_listbox_t *box)
+{
+
+}
+
+rtgui_type_t *rtgui_listbox_type_get(void)
+{
+ static rtgui_type_t *listbox_type = RT_NULL;
+
+ if(!listbox_type)
+ {
+ listbox_type = rtgui_type_create("listbox", RTGUI_CONTAINER_TYPE,
+ sizeof(rtgui_listbox_t),
+ RTGUI_CONSTRUCTOR(_rtgui_listbox_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_listbox_destructor));
+ }
+
+ return listbox_type;
+}
+
+rtgui_listbox_t* rtgui_listbox_create(PVOID parent, int left,int top,int w,int h,rt_uint32_t style)
+{
+ rtgui_listbox_t* box = RT_NULL;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ box = rtgui_widget_create(RTGUI_LISTBOX_TYPE);
+ if(box != RT_NULL)
+ {
+ rtgui_rect_t rect;
+ rtgui_widget_get_rect(parent,&rect);
+ rtgui_widget_rect_to_device(parent, &rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(box,&rect);
+ rtgui_container_add_child(parent, box);
+
+ rtgui_widget_set_style(box,style);
+
+ if(box->sbar == RT_NULL)
+ {//��������ؼ�
+ rt_uint32_t sLeft,sTop,sWidth=RTGUI_DEFAULT_SB_WIDTH,sLen;
+ sLeft = rtgui_rect_width(rect)-RTGUI_WIDGET_BORDER(box)-sWidth;
+ sTop = RTGUI_WIDGET_BORDER(box);
+ sLen = rtgui_rect_height(rect)-RTGUI_WIDGET_BORDER(box)*2;
+
+ box->sbar = rtgui_scrollbar_create(box,sLeft,sTop,sWidth,sLen,RTGUI_VERTICAL);
+
+ if(box->sbar != RT_NULL)
+ {
+ box->sbar->widgetlnk = (PVOID)box;
+ box->sbar->on_scroll = rtgui_listbox_sbar_handle;
+ RTGUI_WIDGET_HIDE(box->sbar);//Ĭ�����ع�����
+ }
+ }
+ }
+
+ return box;
+}
+
+void rtgui_listbox_set_items(rtgui_listbox_t* box, rtgui_listbox_item_t* items, rt_uint32_t count)
+{
+ rtgui_rect_t rect;
+ rt_uint32_t i,h;;
+
+ RT_ASSERT(box != RT_NULL);
+
+ if(box->items != RT_NULL)
+ {
+ rt_free(box->items);
+ box->items = RT_NULL;
+ }
+ //֧������/ɾ����Ŀ,��̬�ռ�
+ box->items = (rtgui_listbox_item_t*) rt_malloc(sizeof(rtgui_listbox_item_t)*count);
+ if(box->items == RT_NULL) return;
+
+ for(i=0;i<count;i++)
+ {
+ box->items[i].name = rt_strdup(items[i].name);
+ box->items[i].image = items[i].image;
+ }
+
+ box->item_count = count;
+ box->now_aloc = 0;
+ box->old_aloc = 0;
+
+ rtgui_widget_get_rect(box, &rect);
+
+ box->item_per_page = rtgui_rect_height(rect) / (box->item_size+2);
+
+ if(box->ispopup)//����ʽ�����б�,������combo�ؼ�֮��
+ {
+ if(box->item_count < 5)
+ box->item_per_page = count;
+ else
+ box->item_per_page = 5;
+
+ h = 2+(box->item_size+2)*box->item_per_page;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_rect_to_device(box,&rect);
+ rtgui_widget_set_rect(box,&rect);//����box�Ĵ�С
+
+ if(box->sbar != RT_NULL) //����sbar��extent
+ {
+ rtgui_widget_get_rect(box->sbar,&rect);
+ rect.y2 = rect.y1+h-RTGUI_WIDGET_BORDER(box)*2;
+ rtgui_widget_rect_to_device(box->sbar,&rect);
+ rtgui_widget_set_rect(box->sbar,&rect);
+ }
+ }
+
+ if(box->sbar != RT_NULL)//����sbar�IJ���
+ {
+ if(box->item_count > box->item_per_page)
+ {
+ RTGUI_WIDGET_UNHIDE(box->sbar);
+ rtgui_scrollbar_set_line_step(box->sbar, 1);
+ rtgui_scrollbar_set_page_step(box->sbar, box->item_per_page);
+ rtgui_scrollbar_set_range(box->sbar, box->item_count);
+ }
+ else
+ {
+ RTGUI_WIDGET_HIDE(box->sbar);
+ }
+ rtgui_widget_update_clip(box);
+ }
+
+}
+
+void rtgui_listbox_destroy(rtgui_listbox_t* box)
+{
+ /* destroy box */
+ rtgui_widget_destroy(box);
+}
+
+//����ListBox����,����������
+void rtgui_listbox_ondraw(rtgui_listbox_t* box)
+{
+ rtgui_rect_t rect, item_rect, image_rect;
+ rt_uint16_t frist, i;
+ const rtgui_listbox_item_t* item;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(box != RT_NULL);
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(box);
+ if(dc == RT_NULL)return;
+
+ rtgui_widget_get_rect(box, &rect);
+
+ //���Ʊ߿�
+ rtgui_dc_draw_border(dc, &rect,RTGUI_WIDGET_BORDER_STYLE(box));
+ rtgui_rect_inflate(&rect,-RTGUI_WIDGET_BORDER(box));
+ RTGUI_DC_BC(dc) = white;
+ rtgui_dc_fill_rect(dc, &rect);
+ rtgui_rect_inflate(&rect,RTGUI_WIDGET_BORDER(box));
+
+ if(box->items==RT_NULL)return;//û����Ŀ,���ٻ�������
+
+ if(box->sbar && !RTGUI_WIDGET_IS_HIDE(box->sbar))
+ {
+ rect.x2 -= rtgui_rect_width(box->sbar->parent.extent);
+ }
+
+ /* get item base rect */
+ item_rect = rect;
+ item_rect.x1 += RTGUI_WIDGET_BORDER(box);
+ item_rect.x2 -= RTGUI_WIDGET_BORDER(box);
+ item_rect.y1 += RTGUI_WIDGET_BORDER(box);
+ item_rect.y2 = item_rect.y1 + (2+box->item_size);
+
+ /* get frist aloc */
+ frist = box->frist_aloc;
+ for(i = 0; i < box->item_per_page; i ++)
+ {
+ if(frist + i >= box->item_count) break;
+
+ item = &(box->items[frist + i]);
+
+ if(frist + i == box->now_aloc)
+ {//draw current item
+ if(RTGUI_WIDGET_IS_FOCUSED(box))
+ {
+ RTGUI_DC_BC(dc) = selected_color;
+ RTGUI_DC_FC(dc) = white;
+ rtgui_dc_fill_rect(dc, &item_rect);
+ rtgui_dc_draw_focus_rect(dc, &item_rect); //���ƽ����
+ }
+ else
+ {
+ RTGUI_DC_BC(dc) = dark_grey;
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_fill_rect(dc, &item_rect);
+ }
+ }
+ item_rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ if(item->image != RT_NULL)
+ {
+ /* get image base rect */
+ 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_paste(item->image, dc, &image_rect, white);
+ item_rect.x1 += item->image->w + 2;
+ }
+ /* draw text */
+ if(frist + i == box->now_aloc && RTGUI_WIDGET_IS_FOCUSED(box))
+ {
+ RTGUI_DC_FC(dc) = white;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+ else
+ {
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+
+ if(item->image != RT_NULL)
+ item_rect.x1 -= (item->image->w + 2);
+ item_rect.x1 -= RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ /* move to next item position */
+ item_rect.y1 += (box->item_size + 2);
+ item_rect.y2 += (box->item_size + 2);
+ }
+
+ if(box->sbar && !RTGUI_WIDGET_IS_HIDE(box->sbar))
+ {
+ rtgui_theme_draw_scrollbar(box->sbar);
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+//����ListBox����,ֻ�����¾ɽ�����
+void rtgui_listbox_update(rtgui_listbox_t* box)
+{
+ const rtgui_listbox_item_t* item;
+ rtgui_rect_t rect, item_rect, image_rect;
+ rtgui_dc_t* dc;
+
+ RT_ASSERT(box != RT_NULL);
+
+ if(RTGUI_WIDGET_IS_HIDE(box))return;
+ if(box->items==RT_NULL)return;
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(box);
+ if(dc == RT_NULL)return;
+
+ rtgui_widget_get_rect(box, &rect);
+ if(box->sbar && !RTGUI_WIDGET_IS_HIDE(box->sbar))
+ {
+ rect.x2 -= rtgui_rect_width(box->sbar->parent.extent);
+ }
+
+ if((box->old_aloc >= box->frist_aloc) && /* ��֮��ijҳ�� */
+ (box->old_aloc < box->frist_aloc+box->item_per_page) && /* ��֮ǰijҳ�� */
+ (box->old_aloc != box->now_aloc)) /* λ��û�б仯,����Ҫˢ���� */
+ {//��Щ����,��������޶ȵļ��ٻ�ͼ��˸����
+ item_rect = rect;
+ /* get old item's rect */
+ item_rect.x1 += RTGUI_WIDGET_BORDER(box);
+ item_rect.x2 -= RTGUI_WIDGET_BORDER(box);
+ item_rect.y1 += RTGUI_WIDGET_BORDER(box);
+ item_rect.y1 += ((box->old_aloc-box->frist_aloc) % box->item_per_page) * (2 + box->item_size);
+ item_rect.y2 = item_rect.y1 + (2+box->item_size);
+
+ /* draw old item */
+ RTGUI_DC_BC(dc) = white;
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_fill_rect(dc,&item_rect);
+
+ item_rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ item = &(box->items[box->old_aloc]);
+ if(item->image != RT_NULL)
+ {
+ 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_paste(item->image, dc, &image_rect, white);
+ item_rect.x1 += item->image->w + 2;
+ }
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+
+ /* draw now item */
+ item_rect = rect;
+ /* get now item's rect */
+ item_rect.x1 += RTGUI_WIDGET_BORDER(box);
+ item_rect.x2 -= RTGUI_WIDGET_BORDER(box);
+ item_rect.y1 += RTGUI_WIDGET_BORDER(box);
+ item_rect.y1 += ((box->now_aloc-box->frist_aloc) % box->item_per_page) * (2 + box->item_size);
+ item_rect.y2 = item_rect.y1 + (2 + box->item_size);
+
+ /* draw current item */
+ if(RTGUI_WIDGET_IS_FOCUSED(box))
+ {
+ RTGUI_DC_BC(dc) = selected_color;
+ RTGUI_DC_FC(dc) = white;
+ rtgui_dc_fill_rect(dc, &item_rect);
+ rtgui_dc_draw_focus_rect(dc, &item_rect); //���ƽ����
+ }
+ else
+ {
+ RTGUI_DC_BC(dc) = dark_grey;
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_fill_rect(dc, &item_rect);
+ }
+
+ item_rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN;
+
+ item = &(box->items[box->now_aloc]);
+ if(item->image != RT_NULL)
+ {
+ 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_paste(item->image, dc, &image_rect, white);
+ item_rect.x1 += (item->image->w + 2);
+ }
+ if(RTGUI_WIDGET_IS_FOCUSED(box))
+ {
+ RTGUI_DC_FC(dc) = white;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+ else
+ {
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_draw_text(dc, item->name, &item_rect);
+ }
+ box->old_aloc = box->now_aloc;
+
+ rtgui_dc_end_drawing(dc);
+}
+
+rt_bool_t rtgui_listbox_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_listbox_t* box = (rtgui_listbox_t*)wdt;
+
+ RT_ASSERT(box != RT_NULL);
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ {
+ rtgui_dc_t *dc;
+
+ dc = rtgui_dc_begin_drawing(box);
+ if(dc == RT_NULL)return RT_FALSE;
+
+ if(!RTGUI_WIDGET_IS_FOCUSED(box))
+ {
+ rtgui_rect_t rect;
+ rtgui_widget_get_rect(box, &rect);
+ rtgui_dc_fill_rect(dc,&rect);
+ }
+
+ rtgui_dc_end_drawing(dc);
+
+ rtgui_listbox_ondraw(box);
+ return RT_FALSE;
+ }
+ case RTGUI_EVENT_RESIZE:
+ {
+ rtgui_event_resize_t* resize;
+
+ resize = (rtgui_event_resize_t*)event;
+
+ /* recalculate page items */
+ box->item_per_page = resize->h / (2 + box->item_size);
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_rect_t rect;
+ rtgui_event_mouse_t* emouse;
+
+ emouse = (rtgui_event_mouse_t*)event;
+
+ /* get physical extent information */
+ rtgui_widget_get_rect(box, &rect);
+ if(box->sbar && !RTGUI_WIDGET_IS_HIDE(box->sbar))
+ rect.x2 -= rtgui_rect_width(box->sbar->parent.extent);
+
+ if((rtgui_region_contains_point(&RTGUI_WIDGET_CLIP(box), emouse->x, emouse->y,&rect) == RT_EOK) && (box->item_count > 0))
+ {
+ rt_uint16_t i;
+ i = (emouse->y - rect.y1) / (2 + box->item_size);
+
+ /* set focus */
+ rtgui_widget_focus(box);
+
+ if((i < box->item_count) && (i < box->item_per_page))
+ {
+ if(emouse->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ box->old_aloc = box->now_aloc;
+ /* set selected item */
+ box->now_aloc = box->frist_aloc + i;
+
+ if(box->on_item != RT_NULL)
+ {
+ box->on_item(box, RT_NULL);
+ }
+
+ /* down event */
+ rtgui_listbox_update(box);
+ }
+ else if(emouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ rtgui_listbox_update(box);
+
+ if(box->ispopup && !RTGUI_WIDGET_IS_HIDE(box))
+ {
+ RTGUI_WIDGET_HIDE(box);
+ box->frist_aloc=0;
+ box->now_aloc = 0;
+
+ rtgui_widget_update_clip(RTGUI_WIDGET_PARENT(box));
+ rtgui_widget_update(RTGUI_WIDGET_PARENT(box));
+ return RT_TRUE;
+ }
+ }
+ if(box->sbar && !RTGUI_WIDGET_IS_HIDE(box))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(box->sbar))
+ rtgui_scrollbar_set_value(box->sbar,box->frist_aloc);
+ }
+ }
+ }
+
+ }
+ break;
+
+ case RTGUI_EVENT_KBD:
+ {
+ rtgui_event_kbd_t* ekbd = (rtgui_event_kbd_t*)event;
+ if((RTGUI_KBD_IS_DOWN(ekbd)) && (box->item_count > 0))
+ {
+ switch (ekbd->key)
+ {
+ case RTGUIK_UP:
+ if(box->now_aloc > 0)
+ {
+ box->old_aloc = box->now_aloc;
+ box->now_aloc --;
+ if(box->now_aloc < box->frist_aloc)
+ {
+ if(box->frist_aloc)box->frist_aloc--;
+ rtgui_listbox_ondraw(box);
+ }
+ else
+ {
+ rtgui_listbox_update(box);
+ }
+
+ if(box->sbar && !RTGUI_WIDGET_IS_HIDE(box))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(box->sbar))
+ rtgui_scrollbar_set_value(box->sbar,box->frist_aloc);
+ }
+
+ if(box->on_item != RT_NULL)
+ {
+ box->on_item(box, RT_NULL);
+ }
+ }
+ break;
+
+ case RTGUIK_DOWN:
+ if(box->now_aloc < box->item_count - 1)
+ {
+ box->old_aloc = box->now_aloc;
+ box->now_aloc ++;
+ if(box->now_aloc >= box->frist_aloc+box->item_per_page)
+ {
+ box->frist_aloc++;
+ rtgui_listbox_ondraw(box);
+ }
+ else
+ {
+ rtgui_listbox_update(box);
+ }
+ if(box->sbar && !RTGUI_WIDGET_IS_HIDE(box))
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(box->sbar))
+ rtgui_scrollbar_set_value(box->sbar,box->frist_aloc);
+ }
+
+ if(box->on_item != RT_NULL)
+ {
+ box->on_item(box, RT_NULL);
+ }
+ }
+ break;
+
+ case RTGUIK_RETURN:
+ if(box->on_item != RT_NULL)
+ {
+ box->on_item(box, RT_NULL);
+ }
+
+ if(box->ispopup && !RTGUI_WIDGET_IS_HIDE(box))
+ {
+ RTGUI_WIDGET_HIDE(box);
+ box->frist_aloc=0;
+ box->now_aloc = 0;
+ rtgui_widget_update_clip(RTGUI_WIDGET_PARENT(box));
+ rtgui_widget_update(RTGUI_WIDGET_PARENT(box));
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return RT_FALSE;
+ }
+ default:
+ return rtgui_container_event_handler(box, event);
+ }
+
+ /* use box event handler */
+ return rtgui_container_event_handler(box, event);
+}
+
+void rtgui_listbox_set_onitem(rtgui_listbox_t* box, rtgui_event_handler_ptr func)
+{
+ if(box == RT_NULL) return;
+
+ box->on_item = func;
+}
+
+void rtgui_listbox_delete_item(rtgui_listbox_t* box, rt_uint32_t item_num)
+{
+ rtgui_listbox_item_t* _items;
+ rt_base_t i;
+
+ if(box == RT_NULL) return;
+
+ for(i=item_num;i<box->item_count-1;i++)
+ {
+ if(box->items[i].name != RT_NULL)
+ {
+ rt_free(box->items[i].name);
+ box->items[i].name = RT_NULL;
+ }
+ box->items[i].name = box->items[i+1].name;
+ box->items[i].image = box->items[i+1].image;
+ }
+
+ box->item_count -= 1;
+ _items = rt_realloc(box->items,sizeof(rtgui_listbox_item_t)*(box->item_count));
+ if(_items != RT_NULL)
+ {
+ box->items = _items;
+ }
+
+ rtgui_listbox_ondraw(box);
+}
+
+static void rtgui_listbox_add_item(rtgui_listbox_t* box,rtgui_listbox_item_t* item)
+{
+ rtgui_listbox_item_t* _items;
+ RT_ASSERT(box != RT_NULL);
+
+ if(box->item_count==0)
+ {
+ _items = rt_malloc(sizeof(rtgui_listbox_item_t)*(box->item_count+1));
+ }
+ else
+ {
+ _items = rt_realloc(box->items,sizeof(rtgui_listbox_item_t)*(box->item_count+1));
+ }
+
+ if(_items != RT_NULL)
+ {
+ box->items = _items;
+ box->items[box->item_count].name = rt_strdup(item->name);
+ box->items[box->item_count].image= item->image;
+ box->item_count += 1;
+
+ if(box->sbar != RT_NULL)
+ {
+ if(RTGUI_WIDGET_IS_HIDE(box->sbar))
+ {
+ if(box->item_count > box->item_per_page)
+ {
+ RTGUI_WIDGET_UNHIDE(box->sbar);
+ rtgui_scrollbar_set_line_step(box->sbar, 1);
+ rtgui_scrollbar_set_page_step(box->sbar, box->item_per_page);
+ rtgui_scrollbar_set_range(box->sbar, box->item_count);
+ }
+ else
+ {
+ RTGUI_WIDGET_HIDE(box->sbar);
+ }
+ rtgui_widget_update_clip(box);
+ }
+ else
+ {
+ rtgui_scrollbar_set_range(box->sbar, box->item_count);
+ }
+ }
+
+ if(!RTGUI_WIDGET_IS_HIDE(box))
+ rtgui_listbox_ondraw(box);
+ }
+}
+
+static rt_uint32_t rtgui_listbox_get_item_count(rtgui_listbox_t* box)
+{
+ return box->item_count;
+}
+
+static rt_bool_t rtgui_listbox_unfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_listbox_t *box = (rtgui_listbox_t*)wdt;
+ if(box == RT_NULL)return RT_FALSE;
+
+ if(!RTGUI_WIDGET_IS_FOCUSED(box))
+ {//��������
+ rtgui_listbox_update(RTGUI_LISTBOX(wdt));
+ }
+
+ if(box->ispopup)
+ {//�ǵ����б�,˵���ǹ���һЩ�ؼ�(����combo)�µ�
+ rtgui_win_t *win;
+
+ RTGUI_WIDGET_HIDE(box);
+ box->frist_aloc=0;
+ box->now_aloc = 0;
+
+ //rtgui_widget_update_clip(RTGUI_WIDGET_PARENT(box));
+ //rtgui_widget_update_clip_pirate(RTGUI_WIDGET_PARENT(box),box);
+ win = rtgui_win_get_win_by_widget(box);
+ if(win != RT_NULL)
+ {//��һ��������
+ if(rtgui_rect_is_intersect(&(RTGUI_WIDGET_EXTENT(win)),
+ &(RTGUI_WIDGET_EXTENT(box))) == RT_EOK)
+ {
+ rtgui_topwin_move(win,RTGUI_WIDGET_EXTENT(win).x1,
+ RTGUI_WIDGET_EXTENT(win).y1);
+ }
+ rtgui_widget_focus(win);
+ rtgui_widget_update_clip(win);
+ }
+ rtgui_panel_redraw(&(RTGUI_WIDGET_EXTENT(box)));
+ }
+
+ return RT_TRUE;
+}
+
+static rt_bool_t rtgui_listbox_sbar_handle(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_listbox_t *box = (rtgui_listbox_t*)wdt;
+
+ //�϶�ʱ���ı��һ��
+ box->frist_aloc = box->sbar->value;
+
+ rtgui_listbox_ondraw(box);
+
+ return RT_TRUE;
+}
+
diff --git a/components/rtgui_win/widgets/menu.c b/components/rtgui_win/widgets/menu.c
new file mode 100644
index 0000000000..5dd5662557
--- /dev/null
+++ b/components/rtgui_win/widgets/menu.c
@@ -0,0 +1,476 @@
+/*
+ * File : menu.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-07-16 amsl first version
+ */
+
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/menu.h>
+
+rt_bool_t rtgui_menu_event_handler(PVOID wdt, rtgui_event_t* event);
+//static rt_bool_t rtgui_menu_onfocus(PVOID wdt, rtgui_event_t* event);
+static rt_bool_t rtgui_menu_onunfocus(PVOID wdt, rtgui_event_t* event);
+
+static void _rtgui_menu_constructor(rtgui_menu_t *menu)
+{
+ /* init menu */
+ rtgui_widget_set_event_handler(menu, rtgui_menu_event_handler);
+ rtgui_widget_set_onunfocus(menu, rtgui_menu_onunfocus);
+ menu->current_item = RT_NULL; //��ǰ�˵���
+ menu->forego_item = RT_NULL;
+ menu->name = RT_NULL;
+ RTGUI_WIDGET_FLAG(menu) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ menu->head = RT_NULL;
+ menu->tail = RT_NULL;
+ menu->farther = RT_NULL;
+
+ //���û��Ʋ˵�ʱҪ�õ��IJ���
+ menu->orient = RTGUI_VERTICAL;
+ menu->item_count = 0;//�˵�������
+ menu->item_size = SELECTED_HEIGHT;
+}
+
+static void _rtgui_menu_destructor(rtgui_menu_t *menu)
+{
+ if(menu->name != RT_NULL)
+ {
+ rt_free(menu->name);
+ menu->name = RT_NULL;
+ }
+}
+
+rtgui_type_t *rtgui_menu_type_get(void)
+{
+ static rtgui_type_t *menu_type = RT_NULL;
+
+ if(!menu_type)
+ {
+ menu_type = rtgui_type_create("menu", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_menu_t),
+ RTGUI_CONSTRUCTOR(_rtgui_menu_constructor),
+ RTGUI_DESTRUCTOR (_rtgui_menu_destructor ));
+ }
+
+ return menu_type;
+}
+
+void rtgui_menu_set_selected(rtgui_menu_t* menu, int selected)
+{
+ RT_ASSERT(menu != RT_NULL);
+
+ if(selected >= menu->item_count) return;
+
+ if(selected >= 0)
+ {
+ rtgui_menu_item_t* item=menu->head;
+ while(selected--)
+ {
+ item = item->next;
+ }
+ menu->forego_item = menu->current_item;
+ menu->current_item = item;
+ }
+
+ /* update rbox widget */
+ rtgui_theme_draw_menu_item(menu, menu->forego_item);
+ rtgui_theme_draw_menu_item(menu, menu->current_item);
+
+ if(menu->current_item->func_updown)
+ {
+ menu->current_item->func_updown(menu);
+ }
+}
+
+static void rtgui_menu_onmouse(rtgui_menu_t* menu, rtgui_event_mouse_t* event)
+{
+ RT_ASSERT(menu != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ if(event->button & RTGUI_MOUSE_BUTTON_DOWN && event->button & RTGUI_MOUSE_BUTTON_LEFT)
+ {
+ rtgui_rect_t rect;
+
+ rtgui_widget_focus(menu);
+
+ rtgui_widget_get_rect(menu, &rect);
+ rtgui_widget_rect_to_device(menu, &rect);
+
+ rtgui_rect_inflate(&rect, -RTGUI_WIDGET_BORDER(menu));
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ if(menu->orient == RTGUI_VERTICAL)
+ {
+ int delta_y = event->y - rect.y1;
+ int sel = delta_y/(menu->item_size+1);
+
+ rtgui_menu_set_selected(menu, sel);
+
+ return;
+ }
+ }
+ }
+}
+
+rt_bool_t rtgui_menu_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_menu_t* menu = (rtgui_menu_t*)widget;
+
+ RT_ASSERT(widget != RT_NULL);
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ {
+ rtgui_theme_draw_menu(menu);
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(widget->on_mouseclick != RT_NULL)
+ widget->on_mouseclick(widget, event);
+ else
+ {
+ rtgui_menu_onmouse(menu, (rtgui_event_mouse_t*)event);
+ }
+ break;
+ case RTGUI_EVENT_KBD:
+ {
+ rtgui_event_kbd_t* ekbd = (rtgui_event_kbd_t*)event;
+
+ if(RTGUI_KBD_IS_DOWN(ekbd))
+ {
+ rt_uint16_t key = ekbd->key;
+
+ switch(key)
+ {
+ case RTGUIK_UP:
+ //������һ���˵�
+ rtgui_menu_on_up(menu);
+ break;
+
+ case RTGUIK_DOWN:
+ //������һ���˵�
+ rtgui_menu_on_down(menu);
+ break;
+
+ case RTGUIK_LEFT:
+ //������һ���˵�
+ break;
+
+ case RTGUIK_RIGHT:
+ //�����Ӳ˵�
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+ default:
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+static rt_bool_t rtgui_menu_onunfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_menu_t* menu = (rtgui_menu_t*)widget;
+
+ rtgui_menu_on_exit(menu);
+ return RT_TRUE;
+}
+
+rtgui_menu_t* rtgui_menu_create(PVOID parent, const char* name)
+{
+ rtgui_menu_t* menu;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ /* allocate view */
+ menu = rtgui_widget_create (RTGUI_MENU_TYPE);
+ if(menu != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += 1;//������ø�ֵ
+ rect.y1 += 1;
+ rect.x2 = rect.x1+10;
+ rect.y2 = rect.y1+10;
+ rtgui_widget_set_rect(menu, &rect);
+
+ menu->name = rt_strdup(name);
+ RTGUI_WIDGET_BACKGROUND(menu) = white;
+ RTGUI_WIDGET_TEXTALIGN(menu) = RTGUI_ALIGN_CENTER_VERTICAL;
+
+ rtgui_container_add_child(parent, menu);
+ }
+
+ return menu;
+}
+
+void rtgui_menu_destroy(rtgui_menu_t* menu)
+{
+ rtgui_widget_destroy(menu);
+}
+
+/*
+��һ��POPUP�˵�����������׷��һ���˵���,ͬWindow����
+Input: menu -- Ҫ׷�ӵIJ˵�
+ flags -- RTGUI_MENU_POPUP:��ʾ׷�ӵ���ΪPOPUP�˵�,����:��ʾ׷��Ϊ��ͨ�˵���
+ ID -- ���flagsΪMENU_FLAG_POPUP ,������ʾΪPOPUP�˵���ָ��,���flagsΪ���� ,������ʾΪ�˵����ID
+ name -- �˵�����
+return : TRUE --�ɹ�
+*/
+rt_bool_t rtgui_menu_append(rtgui_menu_t *menu,rt_uint32_t flag,rt_uint32_t ID,char* caption)
+{
+ rtgui_menu_item_t *item,*node,*old;
+
+ if(menu == RT_NULL) return RT_FALSE;
+
+ item = rt_malloc(sizeof(rtgui_menu_item_t));
+ if(item == RT_NULL) return RT_FALSE;
+ rt_memset(item, 0, sizeof(rtgui_menu_item_t));
+
+ item->type = flag;
+
+ item->caption = rt_strdup(caption);
+
+ item->shortcut = 0; /*�޿�ݼ�*/
+ item->bexit = RT_FALSE;//TRUE;
+ item->func_updown = RT_NULL;
+ item->func_enter = RT_NULL;
+
+ if(flag & RTGUI_MENU_POPUP)
+ {//popup�˵�
+ item->item_id = 0;
+ item->sub_menu = (rtgui_menu_t*)ID;
+
+ /*�����ϼ��˵�*/
+ item->sub_menu->farther = item;
+ }
+ else
+ {//��ͨ�˵�
+ item->item_id = ID;
+ item->sub_menu = 0;
+ }
+ item->next = RT_NULL;
+ menu->item_count++;
+
+ node = menu->head;
+ if(!node)
+ {
+ /*û�в˵����ǵ�һ��*/
+ menu->head = item;
+ menu->tail = item;
+ item->prev = RT_NULL;
+ return RT_TRUE;
+ }
+
+ while(node)
+ {
+ old = node;
+ node = node->next;/*��һ���˵��� */
+ }
+
+ /* ��������� */
+ old->next = item;
+ item->prev = old;
+
+ /*���¶���βָ�� */
+ menu->tail = item;
+
+ return RT_TRUE;
+}
+
+/*
+ * �ڲ˵���ɾ��һ���˵���,�����������һ���Ӳ˵�,�����Ӳ˵�ָ��
+ */
+rtgui_menu_t* rtgui_menu_item_delete(rtgui_menu_t* menu,rtgui_menu_item_t* item)
+{
+ rtgui_menu_t* ret;
+
+ if(item->prev == RT_NULL)
+ {
+ if(item->next == RT_NULL)
+ {
+ /*ֻ��һ�� */
+ menu->head = RT_NULL;
+ menu->tail = RT_NULL;
+ }
+ else
+ {
+ /*ɾ����һ�� */
+ item->next->prev = RT_NULL;
+ menu->head = item->next;
+ }
+ }
+ else
+ {
+ if( item->next == RT_NULL)
+ {
+ /*���һ�� */
+ item->prev->next = RT_NULL;
+ menu->tail = item->prev;
+ }
+ else
+ {
+ /* �� */
+ item->prev->next = item->next;
+ item->next->prev = item->prev;
+ }
+ }
+
+ if(item->type & RTGUI_MENU_POPUP)
+ ret = item->sub_menu; /* �����Ӳ˵� */
+ else
+ ret = RT_NULL;
+
+ rt_free(item->caption);
+ rt_free(item);
+
+ return ret;
+}
+
+/*
+�ж��Ƿ�һ���˵�Ϊ�ղ˵���û�в˵���)
+*/
+rt_bool_t rtgui_menu_is_null(rtgui_menu_t* hMenu)
+{
+ if(hMenu->head == RT_NULL)
+ return RT_TRUE;
+ return RT_FALSE;
+}
+
+/* ɾ��һ��Popup�˵� */
+void rtgui_menu_popup_delete(rtgui_menu_t* menu)
+{
+ rtgui_menu_item_t* pItem;
+ rtgui_menu_t* sub_menu;
+
+ if(rtgui_menu_is_null(menu))
+ {
+ /*�˵�Ϊ��,�ͷ�Popup�ռ�*/
+ rt_free(menu );
+ return;
+ }
+
+ pItem = menu->head;
+ while(pItem)
+ {
+ sub_menu = rtgui_menu_item_delete(menu,pItem);
+ if(sub_menu)
+ {
+ /*ʹ�õݹ��ͷ���һ���Ӳ˵� */
+ rtgui_menu_popup_delete(sub_menu);
+ }
+ /*ȡ��һ���� */
+ pItem = menu->head;
+ }
+ /*ȫ���˵����ͷ����,�ͷ�POPUPָ�� */
+
+ rt_free(menu);
+}
+
+/* �����ƶ�һ���˵�,����:��ǰ�˵���� */
+void rtgui_menu_on_down(rtgui_menu_t* menu)
+{
+ RT_ASSERT(menu != RT_NULL);
+
+ /* Popup�˵�û�в˵��� */
+ if(menu->current_item==RT_NULL)
+ {
+ return ; /* �˵��ݴ� */
+ }
+
+ menu->forego_item = menu->current_item;
+ /* ���һ���˵����� */
+ if(menu->current_item->next==RT_NULL)
+ {
+ /* ��,�ƶ�����ͷ��һ�� */
+ menu->current_item = menu->head;
+ }
+ else
+ {
+ /*�Ƶ���һ�� */
+ menu->current_item = menu->current_item->next;
+ }
+
+ rtgui_theme_draw_menu_item(menu, menu->forego_item);
+ rtgui_theme_draw_menu_item(menu, menu->current_item);
+
+ if(menu->current_item->func_updown)
+ {
+ menu->current_item->func_updown(menu);
+ }
+}
+
+/*
+�����ƶ�һ���˵�
+*/
+void rtgui_menu_on_up(rtgui_menu_t* menu)
+{
+ RT_ASSERT(menu != RT_NULL);
+
+ /*Popup�˵�û�в˵���,�˵���ƴ��� */
+ if(menu->current_item==RT_NULL)
+ {
+ return ; /*�˵��ݴ� */
+ }
+
+ menu->forego_item = menu->current_item;
+ /* ��һ���˵����� */
+ if(menu->current_item->prev==RT_NULL)
+ {
+ /* ��,�����ƶ�*/
+ menu->current_item = menu->tail;
+ }
+ else
+ {
+ /* �Ƶ���һ�� */
+ menu->current_item = menu->current_item->prev;
+ }
+
+ rtgui_theme_draw_menu_item(menu, menu->forego_item);
+ rtgui_theme_draw_menu_item(menu, menu->current_item);
+
+ if(menu->current_item->func_updown)
+ {
+ menu->current_item->func_updown(menu);
+ }
+}
+
+/*�����˵�
+*/
+void rtgui_menu_on_exit(rtgui_menu_t* menu)
+{
+ rtgui_widget_unfocus(menu);
+ rtgui_theme_draw_menu(menu);
+
+ if(menu->current_item->bexit)
+ {
+ menu->current_item = RT_NULL;
+ menu->forego_item = RT_NULL;
+ }
+}
+
+
+
diff --git a/components/rtgui_win/widgets/progressbar.c b/components/rtgui_win/widgets/progressbar.c
new file mode 100644
index 0000000000..0de2595c53
--- /dev/null
+++ b/components/rtgui_win/widgets/progressbar.c
@@ -0,0 +1,128 @@
+#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(bar, rtgui_progressbar_event_handler);
+ rtgui_widget_set_rect(bar, &rect);
+
+ bar->orient = RTGUI_HORIZONTAL;
+ bar->range = RTGUI_PROGRESSBAR_DEFAULT_RANGE;
+ bar->position = 0;
+
+ /* set gc */
+ RTGUI_WIDGET_TEXTALIGN(bar) = RTGUI_ALIGN_CENTER_HORIZONTAL|RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+static void _rtgui_progressbar_destructor(rtgui_progressbar_t *bar)
+{
+
+}
+
+rtgui_type_t *rtgui_progressbar_type_get(void)
+{
+ static rtgui_type_t *progressbar_type = RT_NULL;
+
+ if(!progressbar_type)
+ {
+ progressbar_type = rtgui_type_create("progressbar", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_progressbar_t),
+ RTGUI_CONSTRUCTOR(_rtgui_progressbar_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_progressbar_destructor));
+ }
+
+ return progressbar_type;
+}
+
+rt_bool_t rtgui_progressbar_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_progressbar_t* bar = (rtgui_progressbar_t*)widget;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ {
+ rtgui_theme_draw_progressbar(bar);
+ }
+
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+rtgui_progressbar_t* rtgui_progressbar_create(PVOID parent, int orient, int range, int left, int top, int w, int h)
+{
+ rtgui_progressbar_t* bar;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ bar = rtgui_widget_create (RTGUI_PROGRESSBAR_TYPE);
+ if(bar != RT_NULL)
+ {
+ rtgui_rect_t rect;
+ rtgui_widget_get_rect(bar, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(bar, &rect);
+
+ bar->orient = orient;
+ bar->range = range;
+
+ rtgui_container_add_child(parent, bar);
+ }
+
+ return bar;
+}
+
+void rtgui_progressbar_destroy(rtgui_progressbar_t* bar)
+{
+ rtgui_widget_destroy(bar);
+}
+
+void rtgui_progressbar_set_value(rtgui_progressbar_t *bar, int value)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ bar->position = value;
+
+ rtgui_theme_draw_progressbar(bar);
+ return;
+}
+
+int rtgui_progressbar_get_value(rtgui_progressbar_t *bar)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ return bar->position;
+}
+
+void rtgui_progressbar_set_range(rtgui_progressbar_t *bar, int range)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ bar->range = range;
+
+ rtgui_theme_draw_progressbar(bar);
+ return;
+}
+
+int rtgui_progressbar_get_range(rtgui_progressbar_t *bar)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ return bar->range;
+}
+
diff --git a/components/rtgui_win/widgets/radiobox.c b/components/rtgui_win/widgets/radiobox.c
new file mode 100644
index 0000000000..8f71b04faa
--- /dev/null
+++ b/components/rtgui_win/widgets/radiobox.c
@@ -0,0 +1,206 @@
+#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 *rbox)
+{
+ rtgui_rect_t rect = {0, 0, RTGUI_RADIOBOX_DEFAULT_WIDTH, RTGUI_RADIOBOX_DEFAULT_HEIGHT};
+
+ /* init widget and set event handler */
+ RTGUI_WIDGET_FLAG(rbox) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ RTGUI_WIDGET_TEXTALIGN(rbox) = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_CENTER_VERTICAL;
+ rtgui_widget_set_rect(rbox, &rect);
+ rtgui_widget_set_event_handler(rbox, rtgui_radiobox_event_handler);
+
+ /* set proper of control */
+ rbox->items = RT_NULL;
+ rbox->item_count = 0;
+ rbox->item_sel = -1;
+ rbox->orient = RTGUI_HORIZONTAL;
+}
+
+static void _rtgui_radiobox_destructor(rtgui_radiobox_t *rbox)
+{
+ if(rbox->name != RT_NULL)
+ {
+ rt_free(rbox->name);
+ rbox->name = RT_NULL;
+ }
+}
+rtgui_type_t *rtgui_radiobox_type_get(void)
+{
+ static rtgui_type_t *radiobox_type = RT_NULL;
+
+ if(!radiobox_type)
+ {
+ radiobox_type = rtgui_type_create("radiobox", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_radiobox_t),
+ RTGUI_CONSTRUCTOR(_rtgui_radiobox_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_radiobox_destructor));
+ }
+
+ return radiobox_type;
+}
+
+rtgui_radiobox_t* rtgui_radiobox_create(PVOID parent, const char* name, int orient, char** items, int count,
+ int left, int top, int w, int h)
+{
+ rtgui_radiobox_t* rbox;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ rbox = rtgui_widget_create(RTGUI_RADIOBOX_TYPE);
+ if(rbox != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(parent,&rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(rbox,&rect);
+ rtgui_container_add_child(parent, rbox);
+
+ rbox->name = rt_strdup(name);
+ rbox->item_count = count;
+ if(count > 0)
+ {
+ rbox->items = (char**)rt_malloc(sizeof(char**)*count);
+ if(rbox->items == RT_NULL) return RT_NULL;
+ }
+
+ rbox->item_sel = -1;
+ rbox->orient = orient;
+ }
+
+ return rbox;
+}
+
+void rtgui_radiobox_destroy(rtgui_radiobox_t* rbox)
+{
+ rtgui_widget_destroy(rbox);
+}
+
+static void rtgui_radiobox_onmouse(rtgui_radiobox_t* rbox, rtgui_event_mouse_t* event)
+{
+ RT_ASSERT(rbox != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ if(event->button & RTGUI_MOUSE_BUTTON_DOWN && event->button & RTGUI_MOUSE_BUTTON_LEFT)
+ {
+
+ rtgui_rect_t rect;
+
+ /* focus widgets */
+ rtgui_widget_focus(rbox);
+
+ /* get widget physical rect */
+ rtgui_widget_get_rect(rbox, &rect);
+
+ /* get board size */
+ if(rbox->orient == RTGUI_HORIZONTAL)
+ {//ˮƽ
+ }
+ else if(rbox->orient == RTGUI_VERTICAL)
+ {//��ֱ
+
+ }
+
+ }
+}
+
+rt_bool_t rtgui_radiobox_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_radiobox_t* rbox = (rtgui_radiobox_t*)widget;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ {
+ rtgui_theme_draw_radiobox(rbox);
+ }
+
+ break;
+
+ case RTGUI_EVENT_KBD:
+ if(widget->on_key != RT_NULL) widget->on_key(widget, event);
+ else
+ {
+ rtgui_event_kbd_t *e = (rtgui_event_kbd_t*)event;
+
+ /* set focused */
+ rtgui_widget_focus(rbox);
+ if(!(RTGUI_KBD_IS_UP(e))) return RT_FALSE;
+
+ if(rbox->orient == RTGUI_VERTICAL)
+ {
+ if(e->key == RTGUIK_UP)
+ {
+ if(rbox->item_sel > 0)
+ rtgui_radiobox_set_selection(rbox, rbox->item_sel - 1);
+ }
+ else if(e->key == RTGUIK_DOWN)
+ {
+ if(rbox->item_sel < rbox->item_count - 1)
+ rtgui_radiobox_set_selection(rbox, rbox->item_sel + 1);
+ }
+ }
+ else
+ {
+ if(e->key == RTGUIK_LEFT)
+ {
+ if(rbox->item_sel > 0)
+ rtgui_radiobox_set_selection(rbox, rbox->item_sel - 1);
+ }
+ else if(e->key == RTGUIK_RIGHT)
+ {
+ if(rbox->item_sel < rbox->item_count - 1)
+ rtgui_radiobox_set_selection(rbox, rbox->item_sel + 1);
+ }
+ }
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(widget->on_mouseclick != RT_NULL)
+ widget->on_mouseclick(widget, event);
+ else
+ {
+ rtgui_radiobox_onmouse(rbox, (rtgui_event_mouse_t*)event);
+ }
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+void rtgui_radiobox_set_selection(rtgui_radiobox_t* rbox, int selection)
+{
+ rt_uint16_t old_item;
+
+ if(selection == rbox->item_sel) return;
+
+ old_item = rbox->item_sel;
+ if(selection >= 0 && selection < rbox->item_count)
+ {
+ rbox->item_sel = selection;
+ }
+
+ /* update rbox widget */
+ rtgui_theme_draw_radiobutton(rbox, old_item);
+ rtgui_theme_draw_radiobutton(rbox, rbox->item_sel);
+}
+
+int rtgui_radiobox_get_selection(rtgui_radiobox_t* rbox)
+{
+ return rbox->item_sel;
+}
diff --git a/components/rtgui_win/widgets/scrollbar.c b/components/rtgui_win/widgets/scrollbar.c
new file mode 100644
index 0000000000..93d6287ccd
--- /dev/null
+++ b/components/rtgui_win/widgets/scrollbar.c
@@ -0,0 +1,666 @@
+/*
+ * 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/widgets/scrollbar.h>
+#include <rtgui/rtgui_theme.h>
+
+static void _rtgui_scrollbar_constructor(rtgui_scrollbar_t *bar)
+{
+ /* set event handler */
+ rtgui_widget_set_event_handler(bar, rtgui_scrollbar_event_handler);
+
+ bar->status = 0;
+ bar->value = 0;
+
+ bar->thumb_w = 16;
+ bar->thumb_len = 16;
+
+ bar->widgetlnk = RT_NULL;
+ bar->on_scroll = RT_NULL;
+
+ bar->orient = RTGUI_HORIZONTAL;
+ /* set gc */
+ RTGUI_WIDGET_TEXTALIGN(bar) = RTGUI_ALIGN_CENTER_HORIZONTAL|RTGUI_ALIGN_CENTER_VERTICAL;
+}
+
+static void _rtgui_scrollbar_destructor(rtgui_scrollbar_t *bar)
+{
+
+}
+
+rt_inline rt_uint32_t _rtgui_scrollbar_get_length(rtgui_scrollbar_t *bar)
+{
+ rtgui_rect_t rect;
+ rt_uint32_t result;
+
+ rtgui_widget_get_rect(bar, &rect);
+
+ if(bar->orient & RTGUI_VERTICAL)
+ result = rtgui_rect_height(rect) - 2*rtgui_rect_width(rect) - bar->thumb_len;
+ else
+ result = rtgui_rect_width(rect) - 2*rtgui_rect_height(rect) - bar->thumb_len;
+
+ return result;
+}
+
+rt_inline rt_uint32_t get_scrollbar_pos(rtgui_scrollbar_t* bar)
+{
+ double pos,ftmp;
+ rt_uint32_t result;
+
+ /* calculate thumb position */
+ pos = bar->value;
+ ftmp = _rtgui_scrollbar_get_length(bar);
+ pos *= ftmp;
+ ftmp = bar->count;
+ pos /= ftmp;
+
+ result = pos;
+ return result;
+}
+
+rtgui_type_t *rtgui_scrollbar_type_get(void)
+{
+ static rtgui_type_t *scrollbar_type = RT_NULL;
+
+ if(!scrollbar_type)
+ {
+ scrollbar_type = rtgui_type_create("scrollbar", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_scrollbar_t),
+ RTGUI_CONSTRUCTOR(_rtgui_scrollbar_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_scrollbar_destructor));
+ }
+
+ return scrollbar_type;
+}
+
+
+rtgui_scrollbar_t* rtgui_scrollbar_create(PVOID parent,int left,int top,int w,int len,int orient)
+{
+ rtgui_scrollbar_t* bar;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ bar = rtgui_widget_create (RTGUI_SCROLLBAR_TYPE);
+ if(bar != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+
+ bar->thumb_w = w;
+ if(orient == RTGUI_VERTICAL)
+ {
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+len;
+ }
+ else
+ {
+ rect.x2 = rect.x1+len;
+ rect.y2 = rect.y1+w;
+ }
+
+ rtgui_widget_set_rect(bar, &rect);
+
+ bar->orient = orient;
+
+ rtgui_container_add_child(parent, bar);
+ }
+
+ return bar;
+}
+
+void rtgui_scrollbar_destroy(rtgui_scrollbar_t* bar)
+{
+ rtgui_widget_destroy(bar);
+}
+
+
+void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *erect)
+{
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(bar, &rect);
+ if(bar->orient & RTGUI_VERTICAL)
+ {
+ /* vertical scroll bar */
+ erect->x1 = rect.x1;
+ erect->x2 = rect.x2;
+ erect->y1 = rect.y1 + rtgui_rect_width(rect) + get_scrollbar_pos(bar);
+ erect->y2 = erect->y1 + bar->thumb_len;
+ }
+ else
+ {
+ /* horizontal scroll bar */
+ erect->x1 = rect.x1 + rtgui_rect_height(rect) + get_scrollbar_pos(bar);
+ erect->x2 = erect->x1 + bar->thumb_len;
+ erect->y1 = rect.y1;
+ erect->y2 = rect.y2;
+ }
+}
+
+static rtgui_point_t sbar_mouse_move_size;
+
+static void _rtgui_scrollbar_on_mouseclick(PVOID wdt, rtgui_event_t * event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_rect_t btn_rect, bar_rect,rect;
+ rt_uint32_t pos;
+ rtgui_scrollbar_t *bar = (rtgui_scrollbar_t*)widget;
+ rtgui_event_mouse_t *mouse = (rtgui_event_mouse_t*)event;
+
+ RT_ASSERT(bar != RT_NULL);
+
+ /* get value */
+ pos = get_scrollbar_pos(bar);
+
+ rtgui_widget_get_rect(bar, &rect);
+ rtgui_widget_rect_to_device(bar,&rect);
+
+ if(bar->orient == RTGUI_VERTICAL)
+ { /* arrange vertical */
+ /* get up arrow button rect */
+ btn_rect.x1 = rect.x1;
+ btn_rect.x2 = rect.x2;
+ btn_rect.y1 = rect.y1;
+ btn_rect.y2 = rect.y1 + rtgui_rect_width(rect);
+
+ if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+ {
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ bar->status |= SBAR_UPARROW;
+ if(bar->value==0)
+ {
+ rtgui_theme_draw_scrollbar(bar);
+ return;
+ }
+ /* line step */
+ bar->value -= bar->line_step;
+ if(bar->value < 0) bar->value = 0;
+ }
+ else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ bar->status = 0;
+ }
+ goto __exit;
+ }
+ /* click on the thumb chunk, be going to dragging */
+ rtgui_scrollbar_get_thumb_rect(bar, &bar_rect);
+ rtgui_widget_rect_to_device(bar,&bar_rect);
+ if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+ { /* on thumb */
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ { /* changed status into drag */
+ bar->status |= SBAR_VERTTHUMB;
+ sbar_mouse_move_size.x = mouse->x;
+ sbar_mouse_move_size.y = mouse->y;
+ }
+ else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ bar->status = 0;
+ }
+ goto __exit;
+ }
+ else
+ { /* click on space without thumb */
+ /* get bar rect */
+ bar_rect.y1 = rect.y1 + rtgui_rect_width(rect);
+ bar_rect.y2 = rect.y2 - rtgui_rect_width(rect);
+ if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+ {
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ /* page step */
+ if(mouse->y < bar_rect.y1 + pos)
+ {
+ bar->status |= SBAR_UPSPACE;
+ bar->value -= bar->page_step;
+ if(bar->value < 0) bar->value = 0;
+ }
+ else if(mouse->y > pos + bar->thumb_len)
+ {
+ bar->status |= SBAR_DOWNSPACE;
+ bar->value += bar->page_step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ }
+ }
+ goto __exit;
+ }
+ }
+ /* likewise foregoing */
+ /* get down arrow button rect */
+ bar_rect.x1 = rect.x1;
+ bar_rect.x2 = rect.x2;
+ btn_rect.y1 = rect.y2 - rtgui_rect_width(rect);
+ btn_rect.y2 = rect.y2;
+ if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+ {
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ bar->status |= SBAR_DOWNARROW;
+ if(bar->value==bar->count)
+ {
+ rtgui_theme_draw_scrollbar(bar);
+ return;
+ }
+ /* line step */
+ bar->value += bar->line_step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ }
+ else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
+ bar->status = 0;
+ goto __exit;
+ }
+ }
+ else
+ {
+ /* get left arrow button rect */
+ btn_rect.x1 = rect.x1;
+ btn_rect.x2 = rect.x1 + rtgui_rect_height(rect);
+ btn_rect.y1 = rect.y1;
+ btn_rect.y2 = rect.y2;
+ if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+ {
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ bar->status |= SBAR_LEFTARROW;
+ if(bar->value==0)
+ {
+ rtgui_theme_draw_scrollbar(bar);
+ return;
+ }
+ /* line step */
+ bar->value -= bar->line_step;
+ if(bar->value < 0) bar->value = 0;
+ }
+ else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
+ bar->status = 0;
+ goto __exit;
+ }
+
+ rtgui_scrollbar_get_thumb_rect(bar, &bar_rect);
+ rtgui_widget_rect_to_device(bar,&bar_rect);
+ if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+ {/* on the thumb */
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ bar->status |= SBAR_HORZTHUMB;
+ sbar_mouse_move_size.x = mouse->x;
+ sbar_mouse_move_size.y = mouse->y;
+ }
+ else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ bar->status = 0;
+ }
+ goto __exit;
+ }
+ else
+ {
+ /* get bar rect */
+ bar_rect.x1 = rect.x1 + rtgui_rect_height(rect);
+ bar_rect.x2 = rect.x2 - rtgui_rect_height(rect);
+ bar_rect.y1 = rect.y1;
+ bar_rect.y2 = rect.y2;
+ if(rtgui_rect_contains_point(&bar_rect, mouse->x, mouse->y) == RT_EOK)
+ {
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ /* page step */
+ if(mouse->x < bar_rect.x1 + pos)
+ {
+ bar->status |= SBAR_LEFTSPACE;
+ bar->value -= bar->page_step;
+ if(bar->value < 0) bar->value = 0;
+ }
+ else if(mouse->x > pos + bar->thumb_len)
+ {
+ bar->status |= SBAR_RIGHTSPACE;
+ bar->value += bar->page_step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ }
+ }
+ else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
+ {
+ bar->status = 0;
+ }
+ goto __exit;
+ }
+ }
+ /* get right arrow button rect */
+ btn_rect.x1 = rect.x2 - rtgui_rect_height(rect);
+ btn_rect.x2 = rect.x2;
+ bar_rect.y1 = rect.y1;
+ bar_rect.y2 = rect.y2;
+ if(rtgui_rect_contains_point(&btn_rect, mouse->x, mouse->y) == RT_EOK)
+ {
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ bar->status |= SBAR_RIGHTARROW;
+ if(bar->value==bar->count)
+ {
+ rtgui_theme_draw_scrollbar(bar);
+ return;
+ }
+ /* line step */
+ bar->value += bar->line_step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ }
+ else if(mouse->button & RTGUI_MOUSE_BUTTON_UP)
+ bar->status = 0;
+ goto __exit;
+ }
+ }
+
+__exit:
+ rtgui_theme_draw_scrollbar(bar);
+ if((mouse->button & RTGUI_MOUSE_BUTTON_LEFT) && (mouse->button & RTGUI_MOUSE_BUTTON_DOWN))
+ {
+ if(bar->widgetlnk != RT_NULL && bar->on_scroll != RT_NULL)
+ {
+ rtgui_widget_focus(bar->widgetlnk);
+ bar->on_scroll(bar->widgetlnk, RT_NULL);
+ }
+ }
+
+}
+
+/* thumb chunk activity */
+static void _rtgui_scrollbar_on_mousemotion(PVOID wdt, rtgui_event_t * event)
+{
+ #include <stdlib.h>
+ float tmppos;
+ rt_uint32_t pos;
+ rtgui_scrollbar_t *bar = (rtgui_scrollbar_t*)wdt;
+ rtgui_event_mouse_t *mouse = (rtgui_event_mouse_t*)event;
+
+ tmppos = _rtgui_scrollbar_get_length(bar);
+ tmppos /= bar->count;
+ pos = (rt_uint32_t)tmppos;
+
+ if(bar->orient == RTGUI_VERTICAL)
+ {
+ if(bar->status & SBAR_VERTTHUMB)
+ { /* from then on mouseclick */
+ if((mouse->y-sbar_mouse_move_size.y) > 3)
+ {
+ bar->status |= SBAR_DOWNTHUMB;
+ }
+ else if((mouse->y-sbar_mouse_move_size.y) < -3)
+ {
+ bar->status |= SBAR_UPTHUMB;
+ }
+ else bar->status &= ~(SBAR_UPTHUMB|SBAR_DOWNTHUMB);
+
+ if(abs(mouse->y-sbar_mouse_move_size.y) >= pos)
+ {
+ int step = abs(mouse->y-sbar_mouse_move_size.y)/pos;
+ sbar_mouse_move_size.y = mouse->y;
+
+ if(bar->status & SBAR_UPTHUMB)
+ {
+ bar->value -= step;
+ if(bar->value < 0) bar->value = 0;
+ }
+ else if(bar->status & SBAR_DOWNTHUMB)
+ {
+ bar->value += step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ }
+ goto __exit;
+ }
+ }
+ else if(bar->status & SBAR_UPARROW)
+ { /* on-going push down uparrow button */
+ if(bar->value==0)return;
+ bar->value -= bar->line_step;
+ if(bar->value < 0) bar->value = 0;
+ goto __exit;
+ }
+ else if(bar->status & SBAR_DOWNARROW)
+ { /* on-going push down downarrow button */
+ if(bar->value==bar->count)return;
+ bar->value += bar->line_step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ goto __exit;
+ }
+ /*else if(bar->status & SBAR_UPSPACE)
+ {
+ bar->value -= bar->page_step;
+ if(bar->value < 0) bar->value = 0;
+ goto __exit;
+ }
+ else if(bar->status & SBAR_DOWNSPACE)
+ {
+ bar->value += bar->page_step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ goto __exit;
+ }*/
+ return;
+ }
+ else
+ { /* ˮƽ���� */
+ if(bar->status & SBAR_HORZTHUMB)
+ {
+ if((mouse->x-sbar_mouse_move_size.x) > 5)
+ {
+ bar->status |= SBAR_RIGHTTHUMB;
+ }
+ else if((mouse->x-sbar_mouse_move_size.x) < -5)
+ {
+ bar->status |= SBAR_LEFTTHUMB;
+ }
+ if(abs(mouse->x-sbar_mouse_move_size.x) > pos)
+ {
+ int step = abs(mouse->x-sbar_mouse_move_size.x)/pos;
+ sbar_mouse_move_size.x = mouse->x;
+ if(bar->status & SBAR_LEFTTHUMB)
+ {
+ bar->value -= step;
+ if(bar->value < 0) bar->value = 0;
+ }
+ else if(bar->status & SBAR_RIGHTTHUMB)
+ {
+ bar->value += step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ }
+ goto __exit;
+ }
+ }
+ else if(bar->status & SBAR_LEFTARROW)
+ {
+ if(bar->value==0)return;
+ bar->value -= bar->line_step;
+ if(bar->value < 0) bar->value = 0;
+ goto __exit;
+ }
+ else if(bar->status & SBAR_RIGHTARROW)
+ {
+ if(bar->value==bar->count)return;
+ bar->value += bar->line_step;
+ if(bar->value > bar->count) bar->value = bar->count;
+ goto __exit;
+ }
+ /*else if(bar->status & SBAR_LEFTSPACE)
+ {
+ bar->value -= bar->page_step;
+ if(bar->value < bar->min) bar->value = bar->min;
+ goto __exit;
+ }
+ else if(bar->status & SBAR_RIGHTSPACE)
+ {
+ bar->value += bar->page_step;
+ if(bar->value > bar->count-1) bar->value = bar->count-1;
+ goto __exit;
+ }*/
+ return;
+ }
+
+__exit:
+ rtgui_theme_draw_scrollbar(bar);
+ if(bar->widgetlnk != RT_NULL && bar->on_scroll != RT_NULL)
+ {
+ rtgui_widget_focus(bar->widgetlnk);
+ bar->on_scroll(bar->widgetlnk, RT_NULL);
+ }
+}
+
+
+rt_bool_t rtgui_scrollbar_event_handler(PVOID wdt, rtgui_event_t *event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_scrollbar_t* bar = (rtgui_scrollbar_t*)widget;
+
+ if(RTGUI_WIDGET_IS_HIDE(bar))return RT_FALSE;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ {
+ if(!RTGUI_WIDGET_IS_HIDE(bar))
+ rtgui_theme_draw_scrollbar(bar);
+ }
+
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(RTGUI_WIDGET_IS_ENABLE(widget))
+ {
+ if(widget->on_mouseclick != RT_NULL)
+ {
+ widget->on_mouseclick(widget, event);
+ }
+ else
+ {
+ _rtgui_scrollbar_on_mouseclick(bar, event);
+ }
+ }
+ break;
+ case RTGUI_EVENT_MOUSE_MOTION:
+ if(RTGUI_WIDGET_IS_ENABLE(widget))
+ {
+ _rtgui_scrollbar_on_mousemotion(bar, event);
+ }
+
+ default:
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+void rtgui_scrollbar_set_orientation(rtgui_scrollbar_t* bar, int orient)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ bar->orient = orient;
+}
+
+//ȡ�û���Ŀɻ����ij���
+rt_uint32_t get_sbar_active_len(rtgui_scrollbar_t *bar)
+{
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(bar, &rect);
+
+ if(bar->orient & RTGUI_VERTICAL)
+ return rtgui_rect_height(rect) - 2*rtgui_rect_width(rect);
+ else
+ return rtgui_rect_width(rect) - 2*rtgui_rect_height(rect);
+}
+
+void rtgui_scrollbar_set_thumbbar_len(rtgui_scrollbar_t* bar)
+{
+ double size=0;
+ rt_uint32_t len,w;
+
+ RT_ASSERT(bar != RT_NULL);
+
+ //Make sure called rtgui_scrollbar_set_range(),before you use under code.
+ //������ߴ�ķ���:
+ //��һҳ��Ŀ����/�ܼ��������ı�ֵ,��ȷ������ڿɻ�����еı���,
+ //�������ܶ���,ʹ�û����ĵ�һ����Ϊ��С�ߴ�.
+
+ size = bar->page_step;
+ size /= bar->count+bar->page_step;
+ size *= get_sbar_active_len(bar);
+ len = (rt_uint32_t)size ;
+
+ w = bar->thumb_w;
+
+ if(len < w/2) len = w/2;
+
+ bar->thumb_len = len;
+}
+
+//�������������ĵ���˳��:
+//1.SetLineStep();2.SetPageStep();3.SetRange();
+
+void rtgui_scrollbar_set_line_step(rtgui_scrollbar_t* bar, int step)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ bar->line_step = step;
+}
+
+void rtgui_scrollbar_set_page_step(rtgui_scrollbar_t* bar, int step)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ bar->page_step = step;
+}
+
+void rtgui_scrollbar_set_range(rtgui_scrollbar_t* bar, int count)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ /* disable or enable scrollbar */
+ if(bar->page_step >= count)
+ { /* disable bar */
+ RTGUI_WIDGET_DISABLE(bar);
+ }
+ else
+ { /* enable bar */
+ RTGUI_WIDGET_ENABLE(bar);
+ }
+
+ //���������� = �ܸ��� - һ������
+ bar->count = (rt_int16_t)(count-bar->page_step);
+ rtgui_scrollbar_set_thumbbar_len(bar);
+}
+
+//value��ֵ�DZ��󶨿ؼ�������ֵfrist_aloc
+void rtgui_scrollbar_set_value(rtgui_scrollbar_t* bar, rt_int16_t value)
+{
+ RT_ASSERT(bar != RT_NULL);
+
+ bar->value = value;
+
+ if(bar->value < 0) bar->value = 0;
+
+ rtgui_widget_update(bar);
+}
+
+void rtgui_scrollbar_set_onscroll(rtgui_scrollbar_t* bar, rtgui_event_handler_ptr handler)
+{
+ if(bar == RT_NULL || handler == RT_NULL) return;
+
+ bar->on_scroll = handler;
+}
diff --git a/components/rtgui_win/widgets/slider.c b/components/rtgui_win/widgets/slider.c
new file mode 100644
index 0000000000..f29653945f
--- /dev/null
+++ b/components/rtgui_win/widgets/slider.c
@@ -0,0 +1,229 @@
+#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_FLAG(slider) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ rtgui_widget_set_rect(slider, &rect);
+ rtgui_widget_set_event_handler(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 = 6;
+}
+
+static void _rtgui_slider_destructor(rtgui_slider_t *slider)
+{
+
+}
+
+rtgui_type_t *rtgui_slider_type_get(void)
+{
+ static rtgui_type_t *slider_type = RT_NULL;
+
+ if(!slider_type)
+ {
+ slider_type = rtgui_type_create("slider", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_slider_t),
+ RTGUI_CONSTRUCTOR(_rtgui_slider_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_slider_destructor));
+ }
+
+ return slider_type;
+}
+
+static void rtgui_slider_onmouse(rtgui_slider_t* slider, rtgui_event_mouse_t* 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(slider);
+ rtgui_slider_set_value(slider, sel);
+ }
+}
+
+static void rtgui_slider_onkey(rtgui_slider_t* slider, rtgui_event_kbd_t *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(slider);
+}
+
+rt_bool_t rtgui_slider_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_slider_t* slider = (rtgui_slider_t*)widget;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+ else
+ {
+ rtgui_theme_draw_slider(slider);
+ }
+
+ break;
+
+ case RTGUI_EVENT_KBD:
+ if(widget->on_key != RT_NULL) widget->on_key(widget, event);
+ else
+ {
+ rtgui_slider_onkey(slider, (rtgui_event_kbd_t *)event);
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
+ else
+ {
+ rtgui_slider_onmouse(slider, (rtgui_event_mouse_t*)event);
+ }
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+//����һ��������ؼ�
+rtgui_slider_t* rtgui_slider_create(PVOID parent, rt_size_t min, rt_size_t max, int left, int top, int w, int h, int orient)
+{
+ rtgui_slider_t* slider;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ slider = rtgui_widget_create (RTGUI_SLIDER_TYPE);
+ if(slider != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ /* set proper of control */
+ slider->min = min;
+ slider->max = max;
+ slider->value = min;
+
+ slider->ticks = 10;
+ slider->thumb_width = 6;//�����߿���
+
+ rtgui_slider_set_orientation(slider, orient);
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(slider, &rect);
+ }
+
+ return slider;
+}
+
+void rtgui_slider_destroy(rtgui_slider_t* slider)
+{
+ rtgui_widget_destroy(slider);
+}
+
+void rtgui_slider_set_range(rtgui_slider_t* 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(rtgui_slider_t* slider, rt_size_t value)
+{
+ RT_ASSERT(slider != RT_NULL);
+
+ 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(rtgui_slider_t* slider, int orient)
+{
+ RT_ASSERT(slider != RT_NULL);
+
+ /* set orient */
+ slider->orient = orient;
+}
+
+rt_size_t rtgui_slider_get_value(rtgui_slider_t* slider)
+{
+ RT_ASSERT(slider != RT_NULL);
+
+ return slider->value;
+}
diff --git a/components/rtgui_win/widgets/staticline.c b/components/rtgui_win/widgets/staticline.c
new file mode 100644
index 0000000000..a63dbe7c62
--- /dev/null
+++ b/components/rtgui_win/widgets/staticline.c
@@ -0,0 +1,96 @@
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/widgets/staticline.h>
+
+static void _rtgui_static_constructor(rtgui_staticline_t *sline)
+{
+ /* init widget and set event handler */
+ rtgui_rect_t rect = {0, 0, 100, 2};
+
+ rtgui_widget_set_rect(sline, &rect);
+ sline->orient= RTGUI_HORIZONTAL;
+
+ rtgui_widget_set_event_handler(sline, rtgui_staticline_event_handler);
+}
+
+static void _rtgui_static_destructor(rtgui_staticline_t *sline)
+{
+
+}
+
+rtgui_type_t *rtgui_staticline_type_get(void)
+{
+ static rtgui_type_t *staticline_type = RT_NULL;
+
+ if(!staticline_type)
+ {
+ staticline_type = rtgui_type_create("staticline", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_staticline_t),
+ RTGUI_CONSTRUCTOR(_rtgui_static_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_static_destructor));
+ }
+
+ return staticline_type;
+}
+
+rt_bool_t rtgui_staticline_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_staticline_t* sline;
+ RT_ASSERT(widget != RT_NULL);
+
+ sline = (rtgui_staticline_t*) widget;
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+ else
+ rtgui_theme_draw_staticline(sline);
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+rtgui_staticline_t * rtgui_staticline_create(PVOID parent,int left,int top,int w,int len,int orient)
+{
+ rtgui_staticline_t* sline;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ sline = rtgui_widget_create(RTGUI_STATICLINE_TYPE);
+ if(sline!= RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+
+ sline->orient = orient;
+
+ if(orient == RTGUI_HORIZONTAL)
+ {
+ rect.x2 = rect.x1+len;
+ rect.y2 = rect.y1+w;
+ }
+ else
+ {
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+len;
+ }
+
+ rtgui_widget_set_rect(sline,&rect);
+
+ rtgui_container_add_child(parent, sline);
+ }
+
+ return sline;
+}
+
+void rtgui_staticline_destroy(rtgui_staticline_t* sline)
+{
+ rtgui_widget_destroy(sline);
+}
+
diff --git a/components/rtgui_win/widgets/textbox.c b/components/rtgui_win/widgets/textbox.c
new file mode 100644
index 0000000000..f3f77e908a
--- /dev/null
+++ b/components/rtgui_win/widgets/textbox.c
@@ -0,0 +1,547 @@
+/*
+ * File : textbox.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
+ */
+#include <rtgui/rtgui.h>
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/textbox.h>
+#include <rtgui/widgets/widget.h>
+
+#include <ctype.h>
+
+static void rtgui_textbox_timeout(rtgui_timer_t* timer, void* parameter);
+static rt_bool_t rtgui_textbox_onkey(PVOID wdt, rtgui_event_t* event);
+static rt_bool_t rtgui_textbox_onfocus(PVOID wdt, rtgui_event_t* event);
+static rt_bool_t rtgui_textbox_onunfocus(PVOID wdt, rtgui_event_t* event);
+
+
+void _rtgui_textbox_constructor(rtgui_textbox_t *box)
+{
+ rtgui_rect_t rect;
+
+ RTGUI_WIDGET_FLAG(box) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+
+ rtgui_widget_set_event_handler(box, rtgui_textbox_event_handler);
+ rtgui_widget_set_onfocus(box, rtgui_textbox_onfocus);
+ rtgui_widget_set_onunfocus(box, rtgui_textbox_onunfocus);
+ rtgui_widget_set_onkey(box,rtgui_textbox_onkey);
+
+ RTGUI_WIDGET_BACKGROUND(box) = white;
+ /* set default text align */
+ RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_CENTER_VERTICAL;
+ rtgui_widget_set_style(box, RTGUI_BORDER_SUNKEN);
+ /* set proper of control ����һ�������͵Ŀ��ƶ�ʱ��*/
+ box->caret_timer = rtgui_timer_create(100, RT_TIMER_FLAG_PERIODIC,rtgui_textbox_timeout, box);
+
+ //��ʼ��...��ǰ��,��ʼ��,�ڵ�ǰ���е�λ��
+ box->line = box->line_begin = box->position = 0;
+ box->flag = RTGUI_TEXTBOX_NONE; //����(Ĭ��)
+ box->isedit = RT_TRUE;//Ĭ���ǿ��Ա༭��
+ /* allocate default line buffer ����Ĭ�ϵ��л��� */
+ box->text = RT_NULL;
+
+ rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(box), "h", &rect);
+ box->font_width = rtgui_rect_width(rect);
+ box->on_change = RT_NULL;
+ box->on_enter = RT_NULL;
+}
+
+void _rtgui_textbox_deconstructor(rtgui_textbox_t *textbox)
+{
+ if(textbox->text != RT_NULL)
+ {
+ rt_free(textbox->text);
+ textbox->text = RT_NULL;
+ }
+ if(textbox->caret_timer != RT_NULL)
+ rtgui_timer_destory(textbox->caret_timer);
+ textbox->caret_timer = RT_NULL;
+
+}
+
+rtgui_type_t *rtgui_textbox_type_get(void)
+{
+ static rtgui_type_t *textbox_type = RT_NULL;
+
+ if(!textbox_type)
+ {
+ textbox_type = rtgui_type_create("textbox", RTGUI_WIDGET_TYPE,
+ sizeof(rtgui_textbox_t),
+ RTGUI_CONSTRUCTOR(_rtgui_textbox_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_textbox_deconstructor));
+ }
+
+ return textbox_type;
+}
+
+//#include <rthw.h>
+//���Ʊ༭����
+void rtgui_textbox_draw_caret(rtgui_textbox_t* box, rt_uint16_t position)
+{
+ int x,y;
+// rtgui_color_t color;
+ rtgui_rect_t rect;
+ int font_h,box_h;
+ rtgui_dc_t *dc;
+
+ RT_ASSERT(box != RT_NULL);
+
+ dc = rtgui_dc_begin_drawing(box);
+ if(dc == RT_NULL)return;
+
+ rtgui_widget_get_rect(box, &rect);
+
+ font_h = rtgui_font_get_font_height(RTGUI_WIDGET_FONT(box));
+ box_h = rtgui_rect_height(rect);
+
+ rect.x1 += position * box->font_width+2;
+ rect.x2 = rect.x1+2;
+ rect.y1 += (box_h-font_h)/2;
+ rect.y2 = rect.y1 + font_h;
+
+ for(x=rect.x1;x<rect.x2;x++)
+ {
+ for(y=rect.y1;y<rect.y2;y++)
+ {
+// rt_hw_lcd_get_pixel(color,x,y);
+// color ^= white;
+// rtgui_dc_draw_point(box, color,x,y);
+
+ if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
+ {
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_draw_point(dc, x,y);
+ }
+ else
+ {
+ RTGUI_DC_FC(dc) = white;
+ rtgui_dc_draw_point(dc, x,y);
+ }
+ }
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+
+static void rtgui_textbox_timeout(rtgui_timer_t* timer, void* parameter)
+{
+ rtgui_textbox_t* box;
+
+ box = (rtgui_textbox_t*)parameter;
+ /* set caret flag */
+ if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
+ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
+ else
+ box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
+
+ rtgui_textbox_draw_caret(box,box->position);
+
+ return ;
+}
+
+static void rtgui_textbox_onmouse(rtgui_textbox_t* box, rtgui_event_mouse_t* event)
+{
+ rt_size_t length;
+ rt_uint16_t posbak = box->position;
+
+ RT_ASSERT(box != RT_NULL);
+ RT_ASSERT(event != RT_NULL);
+
+ if(box->isedit == RT_FALSE)return;
+
+ length = rt_strlen(box->text);
+
+ if(event->button & RTGUI_MOUSE_BUTTON_LEFT && event->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {
+ rt_int32_t x;
+ if(!box->isedit)return;
+ if(box->flag & RTGUI_TEXTBOX_MULTI)
+ {//�����ı�
+ /* set widget focus */
+ rtgui_widget_focus(box);
+
+ //add codes at here.
+ //...
+
+ box->position = 0;
+ box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box,box->position);
+ }
+ else
+ {//�����ı�
+ /* set caret position */
+ x = event->x - RTGUI_WIDGET(box)->extent.x1;
+ if(x < 0)
+ {
+ box->position = 0;
+ }
+ else if(x > length * box->font_width)
+ {
+ box->position = length;
+ }
+ else
+ {
+ box->position = x / box->font_width;
+ }
+
+ //�ı���λ��,�����һ��λ����ʾ�˱༭����,�����֮.
+ if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
+ {
+ rtgui_timer_stop(box->caret_timer);
+
+ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box, posbak);//��ˢ�����±༭����,�������ʾ״̬
+
+ rtgui_timer_start(box->caret_timer);
+ }
+
+ /* set widget focus */
+ rtgui_widget_focus(box);
+
+ /* draw caret ���Ʊ༭���� */
+ rtgui_textbox_draw_caret(box,box->position);
+ }
+ }
+}
+
+static rt_bool_t rtgui_textbox_onkey(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_textbox_t* box = (rtgui_textbox_t*)wdt;
+ rtgui_event_kbd_t* ekbd = (rtgui_event_kbd_t*)event;
+ rt_size_t length;
+ rt_uint16_t posbak = box->position;
+
+ RT_ASSERT(box != RT_NULL);
+ RT_ASSERT(ekbd != RT_NULL);
+
+ length = rt_strlen(box->text);
+ if(ekbd->key == RTGUIK_DELETE)
+ {//ɾ����������ַ�
+ if(box->position == length - 1)
+ {
+ box->text[box->position] = '\0';
+ }
+ else
+ {
+ char *c;
+
+ /* remove character */
+ for(c = &box->text[box->position]; c[1] != '\0'; c++)
+ *c = c[1];
+ *c = '\0';
+ }
+
+ if(box->on_change)box->on_change(box,RT_NULL);
+ }
+ else if(ekbd->key == RTGUIK_BACKSPACE)
+ {//ɾ�����ǰ����ַ�
+
+ if(box->position == length - 1)
+ {
+ box->text[box->position] = '\0';
+ box->position --;
+ }
+ else if(box->position != 0)
+ {
+ /* remove current character */
+ if(box->position != 0)
+ {
+ char *c;
+
+ /* remove character */
+ for(c = &box->text[box->position - 1]; c[1] != '\0'; c++)
+ *c = c[1];
+ *c = '\0';
+ }
+ box->position --;
+ }
+
+ if(box->on_change)box->on_change(box,RT_NULL);
+ }
+ else if(ekbd->key == RTGUIK_LEFT)
+ {//��������ƶ�һ���ַ�λ
+ if(box->position > 0)
+ {
+ box->position --;
+ }
+ }
+ else if(ekbd->key == RTGUIK_RIGHT)
+ {//��������ƶ�һ���ַ�λ
+ if(box->position < length)
+ {
+ box->position ++;
+ }
+ }
+ else if(ekbd->key == RTGUIK_HOME)
+ {//����ƶ�������
+ box->position = 0;
+ }
+ else if(ekbd->key == RTGUIK_END)
+ {//����ƶ�����β
+ box->position = length;
+ }
+ else if(ekbd->key == RTGUIK_RETURN)
+ {
+ if(box->on_enter != RT_NULL)
+ {
+ box->on_enter(box, RT_NULL);
+ }
+ }
+ else if(ekbd->key == RTGUIK_NUMLOCK)//���ּ���Ч
+ {
+ /* change numlock state */
+ }
+ else
+ {
+ if(isprint(ekbd->key))
+ {//�ǿɴ�ӡ�ַ�������
+ /* no buffer on this line */
+ if(box->flag & RTGUI_TEXTBOX_DIGIT)
+ {//������������
+ if(!isdigit(ekbd->key))
+ {//����'.'��'-'
+ if(ekbd->key != '.' && ekbd->key !='-')return RT_FALSE;
+ if(ekbd->key == '.' && strchr(box->text,'.'))return RT_FALSE;
+
+ if(ekbd->key == '-')
+ {//������ģʽ��,������������
+ if(length+1 > box->line_length) return RT_FALSE;
+ if(length+1 > box->dis_length) return RT_FALSE;
+
+ if(strchr(box->text,'-'))
+ {//��ǰ�Ѿ���Ϊ����
+ char* c;
+ for(c = &box->text[0]; c != &box->text[length]; c++)
+ *c = *(c+1);
+ box->text[length] = '\0';
+ box->position --;
+ goto _exit;
+ }
+ else
+ {
+ char* c;
+ for(c = &box->text[length]; c != &box->text[0]; c--)
+ *c = *(c-1);
+ box->text[0] = '-';
+ box->text[length+1] = '\0';
+ box->position ++;
+ goto _exit;
+ }
+ }
+ }
+ //rt_kprintf("%c ",ekbd->key);//debug printf
+ }
+ if(length+1 > box->line_length) return RT_FALSE;
+ if(length+1 > box->dis_length) return RT_FALSE;
+
+ if(box->position <= length-1)
+ {
+ char* c;
+
+ for(c = &box->text[length]; c != &box->text[box->position]; c--)
+ *c = *(c-1);
+ box->text[length+1] = '\0';
+ }
+
+ box->text[box->position] = ekbd->key;
+ box->position ++;
+
+ if(box->on_change)box->on_change(box,RT_NULL);
+ }
+ }
+
+_exit:
+ //�ı���λ��,�����һ��λ����ʾ�˱༭����,�����֮.
+ if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
+ {
+ rtgui_timer_stop(box->caret_timer);
+
+ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box, posbak);//��ˢ��һ�±༭����,�������ʾ״̬
+
+ rtgui_timer_start(box->caret_timer);
+ }
+ /* set widget focus */
+ rtgui_widget_focus(box);
+ /* set caret to show */
+ box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
+ /* re-draw text box */
+ rtgui_theme_draw_textbox(box);
+ /* draw caret ���Ʊ༭���� */
+ rtgui_textbox_draw_caret(box,box->position);
+
+ return RT_TRUE;
+}
+
+static rt_bool_t rtgui_textbox_onfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_textbox_t* box = (rtgui_textbox_t*)widget;
+
+ /* set caret to show */
+ box->flag |= RTGUI_TEXTBOX_CARET_SHOW;//�༭����
+ /* start caret timer */
+ rtgui_timer_start(box->caret_timer);
+
+ return RT_TRUE;
+}
+
+static rt_bool_t rtgui_textbox_onunfocus(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_textbox_t* box = (rtgui_textbox_t*)widget;
+
+ /* stop caret timer */
+ rtgui_timer_stop(box->caret_timer);
+
+ /* set caret to hide */
+ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box,box->position);
+
+ if(box->on_enter)box->on_enter(box,event);
+
+ rtgui_theme_draw_textbox(box);
+
+ return RT_TRUE;
+}
+
+rt_bool_t rtgui_textbox_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_textbox_t* box = (rtgui_textbox_t*)widget;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+ else
+ rtgui_theme_draw_textbox(box);
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event);
+ else
+ rtgui_textbox_onmouse(box, (rtgui_event_mouse_t*)event);
+ return RT_TRUE;
+
+ case RTGUI_EVENT_KBD:
+ if(widget->on_key != RT_NULL)
+ widget->on_key(widget, event);
+
+ return RT_TRUE;
+ default:
+ return rtgui_widget_event_handler(widget,event);
+
+ }
+
+ return RT_FALSE;
+}
+
+rtgui_textbox_t* rtgui_textbox_create(PVOID parent,const char* text,int left,int top,int w,int h, rt_uint32_t flag)
+{
+ rtgui_textbox_t* box;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ box = rtgui_widget_create(RTGUI_TEXTBOX_TYPE);
+ if(box != RT_NULL)
+ {
+ rtgui_rect_t rect;
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(box,&rect);
+
+ /* allocate default line buffer */
+ rtgui_textbox_set_value(box, text);
+
+ box->flag = flag;
+ //�趨����ʾ�ַ�����
+ box->dis_length = (w-5)/rtgui_font_get_font_width(RTGUI_WIDGET_FONT(box));
+
+ rtgui_container_add_child(parent, box);
+ }
+
+ return box;
+}
+
+void rtgui_textbox_destroy(rtgui_textbox_t* box)
+{
+ rtgui_widget_destroy(box);
+}
+
+//��һ���ı���������һ��textbox�ؼ�
+void rtgui_textbox_set_value(rtgui_textbox_t* box, const char* text)
+{
+ if(box->text != RT_NULL)
+ {//�Ѿ�������
+ /* free the old text */
+ rt_free(box->text);
+ box->text = RT_NULL;
+ }
+
+ //ԭ��û������
+ box->line_length = ((rt_strlen(text)+1)/RTGUI_TEXTBOX_LINE_MAX+1)*RTGUI_TEXTBOX_LINE_MAX;
+
+ /* allocate line buffer */
+ box->text = rt_malloc(box->line_length);
+ rt_memset(box->text, 0, box->line_length);
+
+ /* copy text */
+ rt_memcpy(box->text, text, rt_strlen(text) + 1);
+
+ /* set current position */
+ box->position = rt_strlen(text);
+}
+
+const char* rtgui_textbox_get_value(rtgui_textbox_t* box)
+{
+ return (const char*)box->text;
+}
+
+void rtgui_textbox_set_line_length(rtgui_textbox_t* box, rt_size_t length)
+{
+ rt_uint8_t* new_line;
+
+ RT_ASSERT(box != RT_NULL);
+
+ /* invalid length */
+ if(length <= 0) return;
+
+ new_line = rt_malloc(length);
+ if(length < box->line_length)
+ {
+ rt_memcpy(new_line, box->text, length - 1);
+ new_line[length] = '\0';
+ }
+ else
+ {
+ rt_memcpy(new_line, (const char*)box->text, rt_strlen((const char*)box->text));
+ }
+
+ /* set line length */
+ box->line_length = length;
+}
+
+//ȡ��textbox�ؼ����ı���ʾ����
+void rtgui_textbox_get_edit_rect(rtgui_textbox_t *box,rtgui_rect_t *rect)
+{
+ rtgui_widget_get_rect(box, rect);
+ rtgui_rect_inflate(rect,-1);
+}
+
+
diff --git a/components/rtgui_win/widgets/view.c b/components/rtgui_win/widgets/view.c
new file mode 100644
index 0000000000..2b4d529feb
--- /dev/null
+++ b/components/rtgui_win/widgets/view.c
@@ -0,0 +1,193 @@
+/*
+ * 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
+ */
+#include <rtgui/dc.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/view.h>
+
+static void _rtgui_view_constructor(rtgui_view_t *view)
+{
+ /* init view */
+ rtgui_widget_set_event_handler(view,rtgui_view_event_handler);
+
+ RTGUI_WIDGET_BORDER_STYLE(view) = RTGUI_BORDER_NONE;
+ view->title = RT_NULL;
+}
+
+static void _rtgui_view_destructor(rtgui_view_t *view)
+{
+ rt_free(view->title);
+}
+
+rtgui_type_t *rtgui_view_type_get(void)
+{
+ static rtgui_type_t *view_type = RT_NULL;
+
+ if(!view_type)
+ {
+ view_type = rtgui_type_create("view", RTGUI_CONTAINER_TYPE,
+ sizeof(rtgui_view_t),
+ RTGUI_CONSTRUCTOR(_rtgui_view_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_view_destructor));
+ }
+
+ return view_type;
+}
+
+rtgui_view_t* rtgui_view_create(PVOID parent,const char* title,int left,int top,int w,int h)
+{
+ rtgui_view_t* view;
+
+ RT_ASSERT(parent != RT_NULL);
+
+ /* allocate view */
+ view = rtgui_widget_create (RTGUI_VIEW_TYPE);
+ if(view != RT_NULL)
+ {
+ rtgui_rect_t rect;
+ rtgui_widget_get_rect(parent,&rect);
+ rtgui_widget_rect_to_device(parent, &rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(view,&rect);
+
+ if(title != RT_NULL)
+ view->title = rt_strdup(title);
+
+ rtgui_container_add_child(parent, view);
+ }
+
+ return view;
+}
+
+void rtgui_view_destroy(rtgui_view_t* view)
+{
+ rtgui_widget_destroy(view);
+}
+
+rt_bool_t rtgui_view_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_view_t* view = (rtgui_view_t*) widget;
+
+ RT_ASSERT(wdt != RT_NULL);
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ {
+ rtgui_rect_t rect;
+ rtgui_dc_t* dc;
+
+ /* begin drawing */
+ dc = rtgui_dc_begin_drawing(view);
+ if(dc == RT_NULL)return RT_FALSE;
+
+ rtgui_widget_get_rect(view, &rect);
+ /* fill view with background */
+ rtgui_dc_fill_rect(dc, &rect);
+
+ if(RTGUI_WIDGET_BORDER(view)>0)
+ rtgui_dc_draw_border(dc,&rect,RTGUI_WIDGET_BORDER_STYLE(view));
+
+ rtgui_dc_end_drawing(dc);
+
+ /* paint on each child */
+ rtgui_container_dispatch_event(RTGUI_CONTAINER(view), event);
+ }
+ break;
+
+ default:
+ return rtgui_container_event_handler(widget, event);
+ }
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_view_show(rtgui_view_t* view)
+{
+ /* parameter check */
+ if(view == RT_NULL) return RT_FALSE;
+
+ //�þ���ں���
+ rtgui_widget_show(view);
+
+ /* no modal mode, always return modal_ok */
+ return RT_TRUE;
+}
+
+
+void rtgui_view_hide(rtgui_view_t* view)
+{
+ if(view == RT_NULL) return;
+
+ if(RTGUI_WIDGET_PARENT(view) == RT_NULL)
+ {
+ RTGUI_WIDGET_HIDE(view);
+ return;
+ }
+
+ rtgui_widget_hide(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);
+
+ rt_free(view->title);
+
+ if(title != RT_NULL)
+ view->title = rt_strdup(title);
+ else
+ view->title = RT_NULL;
+}
+
+//��ʾһ����ͼ��ָ�����Ƶ�����ͼ
+void rtgui_view_show_child(PVOID wdt,const char* name)
+{
+ rtgui_list_t* node;
+ rtgui_container_t *container = (rtgui_container_t*)wdt;
+
+ rtgui_list_foreach(node, &(container->children))
+ {
+ rtgui_widget_t* child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if(RTGUI_IS_VIEW(child))
+ {
+ if(strcmp(RTGUI_VIEW(child)->title,name)==0)
+ {
+ RTGUI_WIDGET_UNHIDE(child);
+ }
+ else
+ {
+ RTGUI_WIDGET_HIDE(child);
+ }
+ }
+ }
+ rtgui_widget_update_clip(wdt);
+ rtgui_widget_update(wdt);
+}
+
+
+
diff --git a/components/rtgui_win/widgets/widget.c b/components/rtgui_win/widgets/widget.c
new file mode 100644
index 0000000000..e8556cebfe
--- /dev/null
+++ b/components/rtgui_win/widgets/widget.c
@@ -0,0 +1,757 @@
+/*
+ * File : widget.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
+ */
+#include <rtgui/dc_client.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/label.h>
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/combobox.h>
+#include <rtgui/widgets/view.h>
+#include <rtgui/widgets/listbox.h>
+#include <panel.h>
+#include <rtgui/dc.h>
+#include <topwin.h>
+
+
+static void _rtgui_widget_constructor(PVOID wdt)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ if(!widget) return;
+
+ /* set default flag */
+ widget->flag = RTGUI_WIDGET_FLAG_DEFAULT;
+
+ /* init list */
+ rtgui_list_init(&(widget->sibling));
+
+ /* init gc */
+ widget->gc.foreground = default_foreground;
+ widget->gc.background = default_background;
+ widget->gc.font = rtgui_font_default();
+ widget->gc.textstyle = RTGUI_TEXTSTYLE_NORMAL;
+ widget->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL|RTGUI_ALIGN_CENTER_VERTICAL;
+#ifndef RTGUI_USING_SMALL_SIZE
+ widget->align = RTGUI_ALIGN_CENTER_VERTICAL;
+#endif
+ rtgui_widget_set_style(widget,RTGUI_BORDER_SUNKEN);
+
+ widget->tab_index = 0;
+ widget->tab_stop = RT_FALSE;
+ /* set parent and toplevel */
+ 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_draw = RT_NULL;
+ widget->on_mouseclick = RT_NULL;
+ widget->on_key = RT_NULL;
+ widget->on_size = RT_NULL;
+ widget->on_command = RT_NULL;
+
+ /* set default event handler */
+ rtgui_widget_set_event_handler(widget,rtgui_widget_event_handler);
+
+ /* init user data private to 0 */
+ widget->user_data = 0;
+
+ /* init clip information */
+ rtgui_region_init(&(widget->clip));
+
+ /* init hardware dc */
+ rtgui_dc_client_init(widget);
+}
+
+/* Destroys the widget */
+static void _rtgui_widget_destructor(PVOID wdt)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ if(widget == RT_NULL) return;
+
+ if(widget->parent != RT_NULL)
+ {
+ /* remove widget from parent's child list */
+ rtgui_list_remove(&(RTGUI_CONTAINER(widget->parent)->children), &(widget->sibling));
+
+ widget->parent = RT_NULL;
+ }
+
+ /* fini clip region */
+ rtgui_region_fini(&(widget->clip));
+}
+
+rtgui_type_t *rtgui_widget_type_get(void)
+{
+ static rtgui_type_t *widget_type = RT_NULL;
+
+ if(!widget_type)
+ {
+ widget_type = rtgui_type_create("rtgui_widget", RTGUI_OBJECT_TYPE,
+ sizeof(rtgui_widget_t),
+ RTGUI_CONSTRUCTOR(_rtgui_widget_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_widget_destructor));
+ }
+
+ return widget_type;
+}
+
+PVOID rtgui_widget_create(rtgui_type_t *widget_type)
+{
+ PVOID widget;
+
+ widget = rtgui_object_create(widget_type);
+
+ return widget;
+}
+
+void rtgui_widget_destroy(PVOID wdt)
+{
+ rtgui_object_destroy(RTGUI_OBJECT(wdt));
+}
+
+void rtgui_widget_set_rect(PVOID wht, rtgui_rect_t* rect)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wht;
+ if(widget == RT_NULL || rect == RT_NULL) return;
+
+ widget->extent = *rect;
+
+ /* it's not empty, fini it */
+ if(rtgui_region_not_empty(&(widget->clip)))
+ {
+ rtgui_region_fini(&(widget->clip));
+ }
+
+ /* reset clip info */
+ rtgui_region_init_with_extents(&(widget->clip), rect);
+ if((widget->parent != RT_NULL) && (widget->toplevel != RT_NULL))
+ {
+ /* update widget clip */
+ rtgui_widget_update_clip(widget->parent);
+ }
+}
+
+//���ÿؼ��������ʽ
+void rtgui_widget_set_style(PVOID wdt, rt_uint32_t style)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->border_style = style;
+ switch(style)
+ {
+ case RTGUI_BORDER_NONE:
+ widget->border = 0;
+ break;
+
+ case RTGUI_BORDER_STATIC:
+ case RTGUI_BORDER_SIMPLE:
+ case RTGUI_BORDER_UP:
+ case RTGUI_BORDER_DOWN:
+ widget->border = 1;
+ break;
+
+ case RTGUI_BORDER_RAISE:
+ case RTGUI_BORDER_SUNKEN:
+ case RTGUI_BORDER_BOX:
+ case RTGUI_BORDER_EXTRA:
+ widget->border = 2;
+ break;
+
+ default:
+ widget->border = 2;
+ break;
+ }
+}
+
+/*
+ * ��������ƶ��ؼ��������ӿؼ���һ���߼���
+ */
+void rtgui_widget_move_to_logic(PVOID wdt, int dx, int dy)
+{
+ rtgui_list_t* node;
+ rtgui_widget_t* child;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ if(widget == RT_NULL) return;
+
+ rtgui_rect_moveto(&(widget->extent), dx, dy);
+
+ /* move each child */
+ if(RTGUI_IS_CONTAINER(widget))
+ {
+ rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
+ {
+ child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ rtgui_widget_move_to_logic(child, dx, dy);
+ }
+ }
+}
+
+void rtgui_widget_set_event_handler(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ RTGUI_WIDGET_EVENT_HANDLE(widget) = handler;
+}
+//���ؾ��������rect����
+void rtgui_widget_get_rect(PVOID wdt, rtgui_rect_t *rect)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ if (rect != RT_NULL)
+ {
+ rect->x1 = rect->y1 = 0;
+ rect->x2 = widget->extent.x2 - widget->extent.x1;
+ rect->y2 = widget->extent.y2 - widget->extent.y1;
+ }
+}
+
+void rtgui_widget_get_position(PVOID wdt, rtgui_point_t *p)
+{
+ rtgui_rect_t rect,parent_rect;
+ RT_ASSERT(wdt != RT_NULL && RTGUI_WIDGET_PARENT(wdt) != RT_NULL);
+
+ rtgui_widget_get_rect(wdt, &rect);
+ rtgui_widget_rect_to_device(wdt,&rect);
+ rtgui_widget_get_rect(RTGUI_WIDGET_PARENT(wdt), &parent_rect);
+ rtgui_widget_rect_to_device(RTGUI_WIDGET_PARENT(wdt),&parent_rect);
+
+ p->x = rect.x1 - parent_rect.x1;
+ p->y = rect.y1 - parent_rect.y1;
+}
+
+rt_uint16_t rtgui_widget_get_width(PVOID wdt)
+{
+ rtgui_rect_t rect={0};
+ RT_ASSERT(wdt != RT_NULL);
+
+ rtgui_widget_get_rect(wdt, &rect);
+ return rtgui_rect_width(rect);
+}
+
+rt_uint16_t rtgui_widget_get_height(PVOID wdt)
+{
+ rtgui_rect_t rect={0};
+ RT_ASSERT(wdt != RT_NULL);
+
+ rtgui_widget_get_rect(wdt, &rect);
+ return rtgui_rect_height(rect);
+}
+
+void rtgui_widget_set_onfocus(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_focus_in = handler;
+}
+
+void rtgui_widget_set_onunfocus(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_focus_out = handler;
+}
+
+void rtgui_widget_set_ondraw(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_draw = handler;
+}
+
+void rtgui_widget_set_onmouseclick(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_mouseclick = handler;
+}
+
+void rtgui_widget_set_onkey(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_key = handler;
+}
+
+void rtgui_widget_set_onsize(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_size = handler;
+}
+
+void rtgui_widget_set_oncommand(PVOID wdt, rtgui_event_handler_ptr handler)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ widget->on_command = handler;
+}
+
+/**
+ * find wdt's toplevel widget and return toplevel focused
+ */
+PVOID rtgui_widget_get_focus(PVOID wdt)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_widget_t *top;
+
+ if(widget == RT_NULL)return RT_NULL;
+
+ top = rtgui_widget_get_toplevel(widget);
+
+ if(RTGUI_IS_CONTAINER(top))
+ return RTGUI_CONTAINER(top)->focused;
+
+ return RT_NULL;
+}
+
+/**
+ * @brief Focuses the widget. The focused widget is the widget which can receive the keyboard events
+ * @param widget a widget
+ * @note The widget has to be attached to a top widget, otherwise it will have no effect
+ */
+void rtgui_widget_focus(PVOID wdt)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_container_t *parent;
+
+ if(widget == RT_NULL)return;
+
+ 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;
+
+ /* ȡ�þɵĸ��ؼ��ͽ���ؼ� */
+ parent = RTGUI_CONTAINER(widget->toplevel);
+ if(parent->focused == widget) return; /* it's the same focused widget */
+
+ /* unfocused the old widget */
+ if((parent->focused != RT_NULL) && !RTGUI_IS_WIN(parent->focused))
+ rtgui_widget_unfocus(parent->focused);
+
+ /* 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(parent));
+
+ /* invoke on focus in call back */
+ if(widget->on_focus_in != RT_NULL)
+ widget->on_focus_in(widget, RT_NULL);
+}
+
+/**
+ * @brief Unfocused the widget
+ * @param widget a widget
+ */
+void rtgui_widget_unfocus(PVOID wdt)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ if(widget == RT_NULL)return;
+
+ if(!widget->toplevel || !RTGUI_WIDGET_IS_FOCUSED(widget))
+ return;
+
+ widget->flag &= ~RTGUI_WIDGET_FLAG_FOCUS;
+
+ if(widget->on_focus_out != RT_NULL)
+ widget->on_focus_out(widget, RT_NULL);
+
+ if(RTGUI_IS_CONTAINER(widget))
+ {
+ rtgui_list_t *node;
+ rtgui_list_foreach(node,&(RTGUI_CONTAINER(widget)->children))
+ {
+ rtgui_widget_t *child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if(RTGUI_WIDGET_IS_HIDE(child))continue;
+ rtgui_widget_unfocus(child);
+ }
+ }
+
+ /* refresh widget ˢ�¿ؼ� */
+ //rtgui_widget_update(widget);//Ҫ��ȥ�þ�,�����ظ�ˢ��
+}
+
+void rtgui_widget_point_to_device(PVOID wdt, rtgui_point_t* point)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ if(point != RT_NULL)
+ {
+ point->x += widget->extent.x1;
+ point->y += widget->extent.y1;
+ }
+}
+
+void rtgui_widget_rect_to_device(PVOID wdt, rtgui_rect_t* rect)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ if(rect != RT_NULL)
+ {
+ rect->x1 += widget->extent.x1;
+ rect->x2 += widget->extent.x1;
+
+ rect->y1 += widget->extent.y1;
+ rect->y2 += widget->extent.y1;
+ }
+}
+
+void rtgui_widget_point_to_logic(PVOID wdt, rtgui_point_t* point)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ if(point != RT_NULL)
+ {
+ point->x -= widget->extent.x1;
+ point->y -= widget->extent.y1;
+ }
+}
+
+void rtgui_widget_rect_to_logic(PVOID wdt, rtgui_rect_t* rect)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ RT_ASSERT(widget != RT_NULL);
+
+ if(rect != RT_NULL)
+ {
+ rect->x1 -= widget->extent.x1;
+ rect->x2 -= widget->extent.x1;
+
+ rect->y1 -= widget->extent.y1;
+ rect->y2 -= widget->extent.y1;
+ }
+}
+
+PVOID rtgui_widget_get_toplevel(PVOID wdt)
+{
+ rtgui_widget_t *top;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ RT_ASSERT(widget != RT_NULL);
+
+ if(widget->toplevel)
+ return (PVOID)(widget->toplevel);
+
+ top = widget;
+ /* get the top widget */
+ while(top->parent != RT_NULL) top = top->parent;
+
+ /* set top */
+ widget->toplevel = top;
+
+ return top;
+}
+
+rt_bool_t rtgui_widget_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL) return widget->on_draw(widget, event);
+ break;
+
+ case RTGUI_EVENT_KBD:
+ if(widget->on_key != RT_NULL) return widget->on_key(widget, event);
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(widget->on_mouseclick != RT_NULL) return widget->on_mouseclick(widget, event);
+ break;
+
+ case RTGUI_EVENT_COMMAND:
+ if(widget->on_command != RT_NULL) return widget->on_command(widget, event);
+ break;
+
+ case RTGUI_EVENT_RESIZE:
+ if(widget->on_size != RT_NULL) return widget->on_size(widget, event);
+ break;
+ }
+
+ return RT_FALSE;
+}
+
+/*
+ * This function updates the clip info of widget
+ */
+void rtgui_widget_update_clip(PVOID wdt)
+{
+ rtgui_list_t *node;
+ rtgui_widget_t *parent;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ /* no widget or widget is hide, no update clip */
+ 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(parent == RT_NULL)
+ {
+ rtgui_panel_t *panel = rtgui_panel_get();
+ rtgui_panel_update_clip(panel);
+ return;
+ }
+
+ /* reset clip to extent */
+ rtgui_region_reset(&(widget->clip), &(widget->extent));
+
+ /* limit widget extent in screen extent */
+ //rtgui_region_intersect(&(widget->clip), &(widget->clip), &(parent->clip));
+ {
+ rtgui_rect_t screen_rect;
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),&screen_rect);
+ //rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &(parent->clip.extents));
+ rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &screen_rect);
+ }
+
+ /* get the no transparent parent */
+ while (parent != RT_NULL && parent->flag & RTGUI_WIDGET_FLAG_TRANSPARENT)
+ {
+ parent = parent->parent;
+ }
+
+ if (parent != RT_NULL)
+ {
+ /* subtract widget clip in parent clip */
+ if (!(widget->flag & RTGUI_WIDGET_FLAG_TRANSPARENT))
+ {
+ rtgui_region_subtract_rect(&(parent->clip), &(parent->clip),
+ &(widget->extent));
+ }
+ }
+
+ /*
+ * note: since the layout widget introduction, the sibling widget will not
+ * intersect.
+ */
+
+ /* if it's a container object, update the clip info of children */
+ if (RTGUI_IS_CONTAINER(widget))
+ {
+ rtgui_widget_t* child;
+ rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
+ {
+ child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if (RTGUI_WIDGET_IS_HIDE(child)) continue;
+ rtgui_widget_update_clip(child);
+ }
+ }
+}
+
+/*
+ * ���¶���ؼ��ص�ʱ��clip�������,���ӿؼ�topwdt��Ϊ��˿ؼ�,
+ * �����ֵܿؼ�����Ӧ�ļ��е�topwdt����,ʹ���Ǵ�λ���ϱ�topwdt����
+ * ���øú���ʱ,Ӧ�ñ�֤topwdt�ؼ���wdt�ؼ��µ�һ���ӿؼ�.
+ */
+void rtgui_widget_update_clip_pirate(PVOID wdt,PVOID topwdt)
+{
+ rtgui_list_t *node;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_rect_t wdt_rect;
+
+ if(widget == RT_NULL || RTGUI_WIDGET_IS_HIDE(widget)) return;
+
+ wdt_rect = widget->extent;
+
+ if(wdt == topwdt)
+ { /* the same as oneself */
+ rtgui_widget_update_clip(widget);
+ return;
+ }
+ else
+ { /* different widget */
+ if(rtgui_rect_is_intersect(&RTGUI_WIDGET_EXTENT(topwdt), &wdt_rect) == RT_EOK)
+ {
+ rtgui_rect_intersect(&RTGUI_WIDGET_EXTENT(topwdt), &wdt_rect);/* calculate overlap */
+ rtgui_region_reset(&(widget->clip), &(widget->extent));
+ rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),&wdt_rect);/* subtract overlap area */
+ }
+ else
+ {
+ rtgui_region_reset(&(widget->clip), &(widget->extent));
+ }
+ }
+
+ {
+ rtgui_rect_t screen_rect;
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),&screen_rect);
+ rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &screen_rect);
+ }
+
+ if(RTGUI_IS_CONTAINER(widget))
+ { /* update all child widget */
+ rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
+ {
+ rtgui_widget_t *child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if(RTGUI_WIDGET_IS_HIDE(child))continue;
+ if(RTGUI_IS_WIN(child))continue; /* no dispose windows */
+
+ rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),&(child->extent));
+ rtgui_widget_update_clip_pirate(child,topwdt);
+ }
+ }
+}
+
+void rtgui_widget_show(PVOID wdt)
+{
+ /* there is no parent or the parent is hide, no show at all */
+ if(RTGUI_WIDGET_PARENT(wdt) == RT_NULL ||RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET_PARENT(wdt))) return;
+
+ /* update the clip info of widget */
+ RTGUI_WIDGET_UNHIDE(wdt);
+ rtgui_widget_update_clip(wdt);
+}
+
+void rtgui_widget_hide(PVOID wdt)
+{
+ rtgui_rect_t rect;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ /* hide this widget */
+ RTGUI_WIDGET_HIDE(widget);
+
+ if (widget->parent != RT_NULL)
+ {
+ int index;
+ rtgui_widget_t *parent;
+
+ rect = widget->extent;
+ parent = widget->parent;
+ /* get the no transparent parent */
+ while (parent != RT_NULL && parent->flag & RTGUI_WIDGET_FLAG_TRANSPARENT)
+ {
+ parent = parent->parent;
+ }
+
+ /* union widget rect */
+ rtgui_region_union_rect(&(widget->parent->clip), &(widget->parent->clip), &rect);
+
+ /* subtract the external rect */
+ for (index = 0; index < external_clip_size; index ++)
+ {
+ rtgui_region_subtract_rect(&(widget->parent->clip), &(widget->parent->clip),
+ &(external_clip_rect[index]));
+ }
+ }
+}
+
+rtgui_color_t rtgui_widget_get_parent_foreground(PVOID wdt)
+{
+ rtgui_widget_t* parent;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ /* get parent widget */
+ parent = widget->parent;
+ while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT))
+ parent = parent->parent;
+
+ /* get parent's color */
+ if (parent != RT_NULL)
+ return RTGUI_WIDGET_FOREGROUND(parent);
+
+ return RTGUI_WIDGET_FOREGROUND(widget);
+}
+
+rtgui_color_t rtgui_widget_get_parent_background(PVOID wdt)
+{
+ rtgui_widget_t* parent;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ /* get parent widget */
+ parent = widget->parent;
+ while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT))
+ parent = parent->parent;
+
+ /* get parent's color */
+ if (parent != RT_NULL)
+ return RTGUI_WIDGET_BACKGROUND(parent);
+
+ return RTGUI_WIDGET_BACKGROUND(widget);
+}
+
+void rtgui_widget_update(PVOID wdt)
+{
+ rtgui_event_paint_t paint;
+
+ if(RTGUI_WIDGET_IS_HIDE(wdt)) return;
+
+ RTGUI_EVENT_PAINT_INIT(&paint);
+ paint.wid = RT_NULL;
+
+ RT_ASSERT(wdt != RT_NULL);
+
+ if(RTGUI_WIDGET_EVENT_HANDLE(wdt) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(wdt, &paint.parent);
+ }
+}
+
+//�����һ���ֵܿؼ�
+rtgui_widget_t* rtgui_widget_get_next_sibling(PVOID wdt)
+{
+ rtgui_widget_t* sibling = RT_NULL;
+ rtgui_widget_t* widget = wdt;
+
+ if(widget->sibling.next != RT_NULL)
+ {
+ sibling = rtgui_list_entry(widget->sibling.next, rtgui_widget_t, sibling);
+ }
+
+ return sibling;
+}
+
+//�����һ���ֵܿؼ�
+rtgui_widget_t* rtgui_widget_get_prev_sibling(PVOID wdt)
+{
+ rtgui_list_t* node;
+ rtgui_widget_t *sibling, *parent;
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+
+ node = RT_NULL; sibling = RT_NULL;
+ parent = widget->parent;
+ if(parent != RT_NULL)
+ {
+ rtgui_list_foreach(node, &(RTGUI_CONTAINER(parent)->children))
+ {
+ if(node->next == &(widget->sibling))
+ break;
+ }
+ }
+
+ if(node != RT_NULL)
+ sibling = rtgui_list_entry(node, rtgui_widget_t, sibling);
+
+ return sibling;
+}
diff --git a/components/rtgui_win/widgets/window.c b/components/rtgui_win/widgets/window.c
new file mode 100644
index 0000000000..4a11c1e5b0
--- /dev/null
+++ b/components/rtgui_win/widgets/window.c
@@ -0,0 +1,726 @@
+/*
+ * File : window.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
+ */
+#include <rtgui/dc.h>
+#include <rtgui/color.h>
+#include <rtgui/image.h>
+#include <rtgui/rtgui_system.h>
+#include <panel.h>
+#include <rtgui/widgets/window.h>
+#include <rtgui/widgets/button.h>
+#include <rtgui/rtgui_theme.h>
+
+
+static void _rtgui_win_constructor(rtgui_win_t *win)
+{
+ /* init window attribute */
+ win->title = RT_NULL;
+ win->on_activate = RT_NULL;
+ win->on_deactivate = RT_NULL;
+ win->on_close = RT_NULL;
+
+ win->modal_widget = RT_NULL;
+ win->tid = RT_NULL;
+
+ /* set window hide */
+ RTGUI_WIDGET_HIDE(win);
+
+ RTGUI_WIDGET_FLAG(win) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ RTGUI_WIDGET_BACKGROUND(win) = default_background;
+
+ /* set window status and style */
+ win->status = 0;
+ win->style = RTGUI_WIN_DEFAULT;
+ rtgui_widget_set_event_handler(win, rtgui_win_event_handler);
+
+ /* init user data */
+ win->user_data = RT_NULL;
+}
+
+static void _rtgui_win_destructor(rtgui_win_t* win)
+{
+ rtgui_event_win_t ewin;
+
+ /* remove win from box */
+ if(RTGUI_WIDGET_PARENT(win) != RT_NULL)
+ {
+ rtgui_container_t *box;
+
+ box = RTGUI_CONTAINER(RTGUI_WIDGET_PARENT(win));
+ rtgui_container_remove_child(box, win);
+ }
+
+ /* destroy in server */
+ RTGUI_EVENT_WIN_DESTROY_INIT(&ewin);
+ ewin.wid = win;
+ if(rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
+ {
+ return; /* destroy in server failed */
+ }
+
+ /* release field */
+ rt_free(win->title);
+}
+
+rtgui_type_t *rtgui_win_type_get(void)
+{
+ static rtgui_type_t *win_type = RT_NULL;
+
+ if(!win_type)
+ {
+ win_type = rtgui_type_create("win", RTGUI_CONTAINER_TYPE,
+ sizeof(rtgui_win_t),
+ RTGUI_CONSTRUCTOR(_rtgui_win_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_win_destructor));
+ }
+
+ return win_type;
+}
+
+rtgui_win_t* rtgui_win_create(PVOID parent, const char* title, rtgui_rect_t *rect, rt_uint32_t style)
+{
+ rtgui_win_t* win;
+ //ȡ��GUI�������߳�
+ struct rt_thread* server = rtgui_thread_get_server();
+ rtgui_thread_t* thread;
+
+ if(parent == RT_NULL) parent = RTGUI_CONTAINER(rtgui_panel_get());
+
+ RT_ASSERT(parent != RT_NULL);
+ if(server == RT_NULL) return RT_NULL;
+
+ win = rtgui_widget_create(RTGUI_WIN_TYPE);
+
+ if(win != RT_NULL)
+ {//������ʽ,����һЩ�ߴ����
+ /* set window title */
+ if(title != RT_NULL)
+ win->title = rt_strdup(title);
+ else
+ win->title = RT_NULL;
+
+ win->style = style;
+
+ //����Ĭ�ϵijߴ����
+ win->title_height = RTGUI_WIN_TITLE_HEIGHT;
+ win->status_height= RTGUI_WIN_STATUS_HEIGHT;
+ win->menu_height = RTGUI_WIN_MENU_HEIGHT;
+ win->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
+
+
+ RTGUI_WIDGET(win)->toplevel = RTGUI_WIDGET(win); //����������Ϊ�����ؼ�
+ /* set extent of win */
+ rtgui_widget_set_rect(win, rect);
+ rtgui_container_add_child(parent, win);
+
+ thread = rtgui_thread_self();
+ win->tid = thread->tid;//�����ڹ��ڵ�ǰ�߳���
+
+ rtgui_thread_set_widget(RTGUI_WIDGET(win));/* �������win����һ��thread */
+
+ {//����һ��������Ϣ
+ rtgui_event_win_t ewin;
+ RTGUI_EVENT_WIN_CREATE_INIT(&ewin);
+ ewin.wid = win;
+
+ if(rtgui_thread_send_sync(server, RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
+ {
+ rt_kprintf("create win: %s failed\n", win->title);
+ return RT_FALSE;
+ }
+ }
+ }
+
+ return win;
+}
+
+void rtgui_win_destroy(rtgui_win_t* win)
+{
+ if(RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ /* end modal */
+ rtgui_win_end_modal(win);
+ }
+
+ rtgui_widget_destroy(win);
+}
+
+//��ÿؼ�����������
+rtgui_win_t* rtgui_win_get_win_by_widget(PVOID wdt)
+{
+ rtgui_widget_t *parent=(rtgui_widget_t*)wdt;
+
+ if(RTGUI_IS_WIN(parent))
+ return (rtgui_win_t*)parent;
+
+ while(parent->parent != RT_NULL)
+ {
+ if(RTGUI_IS_WIN(parent))break;
+ parent = parent->parent;
+ }
+ if(RTGUI_IS_WIN(parent))
+ return (rtgui_win_t*)parent;
+
+ return RT_NULL;
+}
+
+//���ڹر�ʱ���¼�����
+void rtgui_win_close(PVOID wdt, rtgui_event_t *event)
+{
+ rtgui_win_t* win = RT_NULL;
+
+ if(RTGUI_IS_WIN(wdt))
+ win = RTGUI_WIN(wdt);
+ else
+ win = rtgui_win_get_win_by_widget(wdt);
+
+ if(win != RT_NULL)
+ {
+ rtgui_panel_t *panel=rtgui_panel_get();
+ //�ô���״̬Ϊ�ر�״̬
+ win->status |= RTGUI_WIN_STATUS_CLOSED;
+ RTGUI_CONTAINER(panel)->focused = RT_NULL;
+
+ rtgui_win_destroy(win);
+ }
+}
+
+void rtgui_win_show(rtgui_win_t* win, rt_bool_t modal)
+{
+
+ RT_ASSERT(win != RT_NULL);
+
+ if(RTGUI_WIDGET_IS_HIDE(win))
+ {
+ /* send show message to server */
+ rtgui_event_win_t ewin;
+ RTGUI_EVENT_WIN_SHOW_INIT(&ewin);
+ ewin.wid = win;
+
+ if(rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
+ {
+ return;
+ }
+ }
+ else rtgui_widget_update(win);
+
+ if(modal == RT_TRUE)
+ {//��ģʽ��ʽ��ʾ
+ rtgui_widget_t *parent_widget = RTGUI_WIDGET_PARENT(win);
+
+ if(parent_widget != RT_NULL)
+ {
+ /* set style */
+ win->status |= RTGUI_WIN_STATUS_MODAL;
+ //win->modal_widget = win;//��ʱû��ָ��ģʽ�ؼ�,��ָ������
+
+ if(RTGUI_IS_PANEL(parent_widget))
+ {
+ rtgui_panel_t* panel;
+ panel = RTGUI_PANEL(parent_widget);
+ panel->status |= RTGUI_PANEL_STATUS_MODAL;
+ panel->modal_widget = win;
+ }
+ else if(RTGUI_IS_WIN(parent_widget))
+ {
+ rtgui_win_t* pwin;
+ pwin = RTGUI_WIN(parent_widget);
+ pwin->status |= RTGUI_WIN_STATUS_MODAL;
+ pwin->modal_widget = win;
+ }
+ }
+ else
+ {
+ /* which is a top window */
+ win->status |= RTGUI_WIN_STATUS_MODAL;
+ rtgui_win_event_loop(win);
+
+ win->status &= ~RTGUI_WIN_STATUS_MODAL;
+ }
+ }
+}
+
+void rtgui_win_end_modal(rtgui_win_t* win)
+{
+ rtgui_widget_t* parent_widget;
+
+ RT_ASSERT(win != RT_NULL);
+
+ parent_widget = RTGUI_WIDGET_PARENT(win);
+
+ if(parent_widget != RT_NULL)
+ {
+ if(RTGUI_IS_PANEL(parent_widget))
+ {
+ rtgui_panel_t* panel;
+
+ /* which is shown under workbench */
+ panel = RTGUI_PANEL(parent_widget);
+ panel->status &= ~RTGUI_PANEL_STATUS_MODAL;
+ panel->modal_widget = RT_NULL;
+ }
+ else if(RTGUI_IS_WIN(parent_widget))
+ {
+ rtgui_win_t* pwin;
+
+ /* which is shown under win */
+ pwin = RTGUI_WIN(parent_widget);
+ pwin->status &= ~RTGUI_WIN_STATUS_MODAL;
+ pwin->modal_widget = RT_NULL;
+ }
+ }
+ else
+ {
+ /* which is a stand alone window */
+ }
+
+ /* remove modal mode */
+ win->status &= ~RTGUI_WIN_STATUS_MODAL;
+}
+
+void rtgui_win_hiden(rtgui_win_t* win)
+{
+ RT_ASSERT(win != RT_NULL);
+
+ if(!RTGUI_WIDGET_IS_HIDE(win) && rtgui_thread_get_server() != RT_NULL)
+ {
+ /* send hidden message to server */
+ rtgui_event_win_t ewin;
+ RTGUI_EVENT_WIN_HIDE_INIT(&ewin);
+ ewin.wid = win;
+
+ if(rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&ewin),sizeof(rtgui_event_win_t)) != RT_EOK)
+ {
+ rt_kprintf("hide win: %s failed\n", win->title);
+ return;
+ }
+
+ /* set window hide and deactivated */
+ RTGUI_WIDGET_HIDE(win);
+ win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
+ }
+}
+
+rt_bool_t rtgui_win_is_activated(rtgui_win_t* win)
+{
+ RT_ASSERT(win != RT_NULL);
+
+ return win->status & RTGUI_WIN_STATUS_ACTIVATE;
+}
+
+void rtgui_win_move(rtgui_win_t* win, int x, int y)
+{
+ rtgui_event_win_move_t emove;
+ RTGUI_EVENT_WIN_MOVE_INIT(&emove);
+
+ if (win == RT_NULL) return;
+
+ /* set win hide firstly */
+// RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
+
+ emove.wid = win;
+ emove.x = x;
+ emove.y = y;
+ if (rtgui_thread_send_sync(rtgui_thread_get_server(), RTGUI_EVENT(&emove),
+ sizeof(rtgui_event_win_move_t)) != RT_EOK)
+ {
+ return;
+ }
+
+// /* move window to logic position */
+// rtgui_widget_move_to_logic(win,
+// x - RTGUI_WIDGET(win)->extent.x1,
+// y - RTGUI_WIDGET(win)->extent.y1);
+//
+// /* set window visible */
+// RTGUI_WIDGET_UNHIDE(win);
+ return;
+
+}
+
+rt_bool_t rtgui_win_ondraw(rtgui_win_t* win)
+{
+ rtgui_event_paint_t event;
+
+ rtgui_theme_draw_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);
+
+ return RT_FALSE;
+}
+
+rt_bool_t rtgui_win_event_handler(PVOID wdt, rtgui_event_t* event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_win_t* win = (rtgui_win_t*)widget;
+
+ RT_ASSERT((win != RT_NULL) && (event != RT_NULL));
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_WIN_CLOSE:
+ if(win->on_close != RT_NULL)
+ {
+ if(win->on_close(widget, event) == RT_FALSE) return RT_TRUE;
+ }
+
+ if(RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ rtgui_win_destroy(win);
+ }
+ else
+ {
+ rtgui_win_close(win,RT_NULL);
+ }
+
+ /* exit event loop */
+ return RT_TRUE;
+
+ case RTGUI_EVENT_WIN_MAX: //��󻯴���
+ // TODO: Place code here.
+ break;
+
+ case RTGUI_EVENT_WIN_MIN: //��С������,(���ش���)
+ // TODO: Place code here.
+ break;
+
+ case RTGUI_EVENT_WIN_MOVE:
+ {
+ rtgui_event_win_move_t* emove = (rtgui_event_win_move_t*)event;
+ /* move window */
+ rtgui_win_move(win, emove->x, emove->y);
+ }
+ break;
+
+ case RTGUI_EVENT_WIN_ACTIVATE:
+ if(RTGUI_WIDGET_IS_HIDE(win))
+ {
+ rt_kprintf("activate window, but window is hide!\n");
+ }
+
+ win->status |= RTGUI_WIN_STATUS_ACTIVATE;
+
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ rtgui_widget_update(win);
+
+ if (win->on_activate != RT_NULL)
+ {
+ win->on_activate(widget, event);
+ }
+ break;
+
+ case RTGUI_EVENT_WIN_DEACTIVATE:
+ if(RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ /* do not deactivate a modal win, re-send win-show event */
+ rtgui_event_win_t eshow;
+ RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
+ eshow.wid = win;
+
+ rtgui_thread_send(rtgui_thread_get_server(), RTGUI_EVENT(&eshow),sizeof(rtgui_event_win_t));
+ }
+ else
+ {
+ win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
+
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ rtgui_win_ondraw(win);
+
+ if (win->on_deactivate != RT_NULL)
+ {
+ win->on_deactivate(widget, event);
+ }
+ }
+ break;
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL) widget->on_draw(widget, event);
+ else
+ rtgui_win_ondraw(win);
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ if(RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ if(win->modal_widget != RT_NULL)
+ return RTGUI_WIDGET_EVENT_CALL(win->modal_widget, event);
+ }
+
+ if(rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),(rtgui_event_mouse_t*)event) == RT_FALSE)
+ {//�ɷ���Ϣ
+ if(widget->on_mouseclick != RT_NULL)
+ {
+ return widget->on_mouseclick(widget, event);
+ }
+ }
+ break;
+
+ case RTGUI_EVENT_MOUSE_MOTION:
+ if (RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ if (win->modal_widget != RT_NULL)
+ return RTGUI_WIDGET_EVENT_CALL(win->modal_widget, event);
+ }
+
+ rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(win),(rtgui_event_mouse_t*)event);
+ break;
+
+ case RTGUI_EVENT_KBD:
+ if(RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ if(win->modal_widget != RT_NULL)
+ return RTGUI_WIDGET_EVENT_CALL(win->modal_widget, event);
+ }
+
+ if(RTGUI_CONTAINER(win)->focused != widget)
+ {
+ RTGUI_WIDGET_EVENT_CALL(RTGUI_CONTAINER(win)->focused, event);
+ }
+ break;
+
+ default:
+ //call parent widget event
+ return rtgui_container_event_handler(wdt,event);
+ }
+
+ return RT_FALSE;
+}
+
+/* windows event loop */
+void rtgui_win_event_loop(rtgui_win_t* win)
+{
+ rt_err_t result;
+ rtgui_thread_t* tid;
+ rtgui_event_t* event;
+
+ tid = rtgui_thread_self();
+ RT_ASSERT(tid != RT_NULL);
+
+ /* point to event buffer */
+ event = (rtgui_event_t*)tid->event_buffer;
+
+ if(RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ while(RTGUI_WIN_IS_MODAL_MODE(win))
+ {
+ 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_EVENT_CALL(win, event);
+ }
+ else if (result == -RT_ETIMEOUT)
+ {
+ tid->on_idle(win, RT_NULL);
+ }
+ }
+ else
+ {
+ result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+ if (result == RT_EOK)
+ {
+ /* perform event handler */
+ RTGUI_WIDGET_EVENT_CALL(win, event);
+ }
+ }
+ }
+ }
+ else
+ {
+ while(!(win->status & RTGUI_WIN_STATUS_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_EVENT_CALL(win, event);
+ }
+ else if (result == -RT_ETIMEOUT)
+ {
+ tid->on_idle(win, RT_NULL);
+ }
+ }
+ else
+ {
+ result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+ if (result == RT_EOK)
+ {
+ /* perform event handler */
+ RTGUI_WIDGET_EVENT_CALL(win, event);
+ }
+ }
+ }
+ }
+}
+
+void rtgui_win_set_rect(rtgui_win_t* win, rtgui_rect_t* rect)
+{
+ rtgui_event_win_resize_t event;
+
+ if(win == RT_NULL || rect == RT_NULL) return;
+
+ RTGUI_WIDGET(win)->extent = *rect;
+
+ if(rtgui_thread_get_server() != RT_NULL)
+ {
+ /* set window resize event to server */
+ RTGUI_EVENT_WIN_RESIZE_INIT(&event);
+ event.wid = win;
+ event.rect = *rect;
+
+ rtgui_thread_send(rtgui_thread_get_server(), &(event.parent), sizeof(rtgui_event_win_resize_t));
+ }
+}
+
+void rtgui_win_set_onactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler)
+{
+ if(win != RT_NULL)
+ {
+ win->on_activate = handler;
+ }
+}
+
+void rtgui_win_set_ondeactivate(rtgui_win_t* win, rtgui_event_handler_ptr handler)
+{
+ if(win != RT_NULL)
+ {
+ win->on_deactivate = handler;
+ }
+}
+
+void rtgui_win_set_onclose(rtgui_win_t* win, rtgui_event_handler_ptr handler)
+{
+ if(win != RT_NULL)
+ {
+ win->on_close = handler;
+ }
+}
+
+void rtgui_win_set_title(rtgui_win_t* win, const char *title)
+{
+ /* modify in local side */
+ rt_free(win->title);
+
+ if(title != RT_NULL)
+ win->title = rt_strdup(title);
+ else
+ win->title = RT_NULL;
+}
+
+char* rtgui_win_get_title(rtgui_win_t* win)
+{
+ RT_ASSERT(win != RT_NULL);
+
+ return win->title;
+}
+
+rtgui_point_t rtgui_win_get_client_zero(rtgui_win_t *win)
+{
+ rtgui_point_t p={0};
+ rtgui_rect_t r1,r2;
+
+ rtgui_win_get_client_rect(win, &r1);
+ rtgui_widget_get_rect(win, &r2);
+ p.x = r1.x1-r2.x1;
+ p.y = r1.y1-r2.y1;
+
+ return p;
+}
+
+//���ش��ڿͻ�������
+void rtgui_win_get_client_rect(rtgui_win_t *win, rtgui_rect_t *rect)
+{
+ rtgui_widget_get_rect(win, rect);
+
+ if(win->style & RTGUI_WIN_BORDER)
+ rtgui_rect_inflate(rect, -win->border_size);
+
+ if(win->style & RTGUI_WIN_TITLE)//�б��������ȥ�������ĸ߶�
+ rect->y1 += win->title_height;
+
+ if(win->style & RTGUI_WIN_MENU)
+ rect->y1 += win->menu_height;
+
+ if(win->style & RTGUI_WIN_STATUS)//��״̬�����ȥ״̬���ĸ߶�
+ rect->y2 -= win->status_height;
+
+}
+
+//���ش��ڵı���������
+void rtgui_win_get_title_rect(rtgui_win_t *win, rtgui_rect_t *rect)
+{
+ rtgui_widget_get_rect(win, rect);
+
+ if(win->style & RTGUI_WIN_TITLE)
+ {
+ if(win->style & RTGUI_WIN_BORDER)
+ {
+ rtgui_rect_inflate(rect, -win->border_size);
+ }
+ rect->y2 = rect->y1 + win->title_height;
+ }
+ else
+ {
+ rect->x1=rect->x2=rect->y1=rect->y2 = 0;
+ }
+}
+
+//���ش��ڵĹرհ�ť����
+void rtgui_win_get_closebox_rect(rtgui_win_t *win, rtgui_rect_t *rect)
+{
+ rtgui_win_get_title_rect(win,rect);
+ if(win->style & RTGUI_WIN_CLOSEBOX)
+ {
+ /* get close button rect (device value) */
+ rect->x2 = rect->x2 - 2;
+ rect->x1 = rect->x2 - RTGUI_WIN_CLOSEBOX_WIDTH;
+ rect->y1 = rect->y1 + (rtgui_rect_height(*rect)-RTGUI_WIN_CLOSEBOX_HEIGHT)/2;
+ rect->y2 = rect->y1 + RTGUI_WIN_CLOSEBOX_HEIGHT;
+ }
+}
+
+//���ش��ڵ���󻯰�ť����
+void rtgui_win_get_maxbox_rect(rtgui_win_t *win, rtgui_rect_t *rect)
+{
+ rtgui_win_get_closebox_rect(win,rect);
+ if(win->style & RTGUI_WIN_CLOSEBOX)
+ {
+ rtgui_rect_moveto(rect,-2-RTGUI_WIN_CLOSEBOX_WIDTH,0);
+ }
+}
+
+//���ش��ڵ���С����ť����
+void rtgui_win_get_minbox_rect(rtgui_win_t *win, rtgui_rect_t *rect)
+{
+ rtgui_win_get_closebox_rect(win,rect);
+ if(win->style & RTGUI_WIN_CLOSEBOX)
+ {
+ rtgui_rect_moveto(rect,-2-RTGUI_WIN_CLOSEBOX_WIDTH,0);
+ }
+ if(win->style &RTGUI_WIN_MAXBOX)
+ {
+ rtgui_rect_moveto(rect,-2-RTGUI_WIN_CLOSEBOX_WIDTH,0);
+ }
+}
+
+