diff --git a/components/rtgui/include/rtgui/widgets/listctrl.h b/components/rtgui/include/rtgui/widgets/listctrl.h index 9ce3263d54..bd42dd12e7 100644 --- a/components/rtgui/include/rtgui/widgets/listctrl.h +++ b/components/rtgui/include/rtgui/widgets/listctrl.h @@ -60,5 +60,6 @@ void rtgui_listctrl_destroy(rtgui_listctrl_t* ctrl); rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui_event* event); void rtgui_listctrl_set_onitem(rtgui_listctrl_t* ctrl, rtgui_onitem_func_t func); void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint16_t count); +rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect); #endif diff --git a/components/rtgui/include/rtgui/widgets/menu.h b/components/rtgui/include/rtgui/widgets/menu.h index e573ad6a1e..f6c422bb19 100644 --- a/components/rtgui/include/rtgui/widgets/menu.h +++ b/components/rtgui/include/rtgui/widgets/menu.h @@ -73,6 +73,7 @@ void rtgui_menu_set_onmenupop(struct rtgui_menu* menu, rtgui_event_handler_ptr h void rtgui_menu_set_onmenuhide(struct rtgui_menu* menu, rtgui_event_handler_ptr handler); void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y); +void rtgui_menu_hiden(struct rtgui_menu* menu); #endif diff --git a/components/rtgui/include/rtgui/widgets/notebook.h b/components/rtgui/include/rtgui/widgets/notebook.h new file mode 100644 index 0000000000..76e4298ec2 --- /dev/null +++ b/components/rtgui/include/rtgui/widgets/notebook.h @@ -0,0 +1,39 @@ +#ifndef __RTGUI_NOTEBOOK_H__ +#define __RTGUI_NOTEBOOK_H__ + +#include +#include + +/** Gets the type of a notebook */ +#define RTGUI_NOTEBOOK_TYPE (rtgui_notebook_type_get()) +/** Casts the object to a notebook control */ +#define RTGUI_NOTEBOOK(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_NOTEBOOK_TYPE, rtgui_notebook_t)) +/** Checks if the object is a notebook control */ +#define RTGUI_IS_NOTEBOOK(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_NOTEBOOK_TYPE)) + +struct rtgui_notebook +{ + struct rtgui_container parent; + + /* widget private data */ + struct rtgui_widget* childs; + rt_uint16_t count; + rt_int16_t current; +}; +typedef struct rtgui_notebook rtgui_notebook_t; + +rtgui_type_t *rtgui_notebook_type_get(void); + +rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect); +void rtgui_notebook_destroy(rtgui_notebook_t* notebook); + +void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_widget_t* child); +int rtgui_notebook_get_count(rtgui_notebootk_t* notebook); +rtgui_widget_t* rtgui_notebook_get_current(rtgui_notebook_t* notebook); +void rtgui_notebook_set_current(rtgui_notebook_t* notebook, rtgui_widget_t* widget); +void rtgui_notebook_set_current_by_index(rtgui_notebook_t* notebook, rt_uint16_t index); +rtgui_widget_t* rtgui_notebook_get_index(rtgui_notebook_t* notebook, rt_uint16_t index); + +rt_bool_t rtgui_notebook_event_handler(struct rtgui_widget* widget, struct rtgui_event* event); + +#endif diff --git a/components/rtgui/include/rtgui/widgets/widget.h b/components/rtgui/include/rtgui/widgets/widget.h index 719272f272..1a58d6bead 100644 --- a/components/rtgui/include/rtgui/widgets/widget.h +++ b/components/rtgui/include/rtgui/widgets/widget.h @@ -150,6 +150,7 @@ void rtgui_widget_set_oncommand(rtgui_widget_t* widget, rtgui_event_handler_ptr /* get and set rect of widget */ void rtgui_widget_get_rect(rtgui_widget_t* widget, rtgui_rect_t *rect); void rtgui_widget_set_rect(rtgui_widget_t* widget, rtgui_rect_t* rect); +void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect); #ifndef RTGUI_USING_SMALL_SIZE void rtgui_widget_set_miniwidth(rtgui_widget_t* widget, int width); diff --git a/components/rtgui/widgets/listctrl.c b/components/rtgui/widgets/listctrl.c index 943f5793fb..360b2ad892 100644 --- a/components/rtgui/widgets/listctrl.c +++ b/components/rtgui/widgets/listctrl.c @@ -59,8 +59,8 @@ void rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl) rect.x2 -= 1; rect.y2 -= 1; /* draw focused border */ - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(ctrl))) - rtgui_dc_draw_focus_rect(dc, &rect); + // if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(ctrl))) + // rtgui_dc_draw_focus_rect(dc, &rect); /* get item base rect */ item_rect = rect; @@ -191,8 +191,8 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui /* update focus border */ rect.x2 -= 1; rect.y2 -= 1; /* draw focused border */ - if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(ctrl))) - rtgui_dc_draw_focus_rect(dc, &rect); + // if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(ctrl))) + // rtgui_dc_draw_focus_rect(dc, &rect); rtgui_dc_end_drawing(dc); } } @@ -322,3 +322,23 @@ void rtgui_listctrl_set_items(rtgui_listctrl_t* ctrl, rt_uint32_t items, rt_uint rtgui_widget_update(RTGUI_WIDGET(ctrl)); } + +rt_bool_t rtgui_listctrl_get_item_rect(rtgui_listctrl_t* ctrl, rt_uint16_t item, rtgui_rect_t* item_rect) +{ + if (item < ctrl->items_count) + { + rt_uint16_t index; + + /* check whether this item in current page */ + index = (ctrl->current_item / ctrl->page_items) * ctrl->page_items; + if (index > item || index + ctrl->page_items <= item) return RT_FALSE; + + rtgui_widget_get_extent(RTGUI_WIDGET(ctrl), item_rect); + item_rect->y1 -= 2; + item_rect->y1 += (item % ctrl->page_items) * (2 + rtgui_theme_get_selected_height()); + item_rect->y2 = item_rect->y1 + (2 + rtgui_theme_get_selected_height()); + return RT_TRUE; + } + + return RT_FALSE; +} diff --git a/components/rtgui/widgets/menu.c b/components/rtgui/widgets/menu.c index 5a4e178394..215a426cbb 100644 --- a/components/rtgui/widgets/menu.c +++ b/components/rtgui/widgets/menu.c @@ -2,10 +2,6 @@ #include #include -#define RTGUI_MENU_IMAGE_MAGIN 18 -#define RTGUI_MENU_SUBMENU_MAGIN 16 - -static void rtgui_menu_item_unselect(struct rtgui_menu_item* item); static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t* event); const static rt_uint8_t right_arrow[] = {0x80, 0xc0, 0xe0, 0xf0, 0xe0, 0xc0, 0x80}; @@ -31,6 +27,14 @@ static void _rtgui_menu_constructor(rtgui_menu_t *menu) static void _rtgui_menu_destructor(rtgui_menu_t* menu) { + if (menu->sub_menu != RT_NULL) + { + rtgui_menu_destroy(menu->sub_menu); + menu->sub_menu = RT_NULL; + } + + rtgui_listctrl_destroy(menu->items_list); + menu->items_list = RT_NULL; } static void _rtgui_menu_onitem(struct rtgui_widget* widget, struct rtgui_event* event) @@ -43,15 +47,45 @@ static void _rtgui_menu_onitem(struct rtgui_widget* widget, struct rtgui_event* { const rtgui_menu_item_t* items; rt_uint16_t count; + rtgui_rect_t item_rect; items = menu->items[menu->items_list->current_item].submenu; count = menu->items[menu->items_list->current_item].submenu_count; + if (menu->sub_menu != RT_NULL) + { + if (menu->sub_menu->items == items) + { + if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(menu->sub_menu))) + { + /* hide this sub menu */ + rtgui_win_hiden(RTGUI_WIN(menu->sub_menu)); + return; + } + + /* show this sub menu */ + rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect); + rtgui_menu_pop(menu->sub_menu, item_rect.x2, item_rect.y1); + return; + } + + /* delete sub menu */ + rtgui_menu_destroy(menu->sub_menu); + menu->sub_menu = RT_NULL; + } + + /* create sub menu */ menu->sub_menu = rtgui_menu_create("submenu", menu, items, count); - rtgui_menu_pop(menu, 10, 10); + + rtgui_listctrl_get_item_rect(menu->items_list, menu->items_list->current_item, &item_rect); + rtgui_menu_pop(menu->sub_menu, item_rect.x2 + 5, item_rect.y1); } else /* other menu item */ { - rtgui_win_hiden(RTGUI_WIN(menu)); + /* invoke action */ + if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL) + menu->items[menu->items_list->current_item].on_menuaction(RTGUI_WIDGET(menu), RT_NULL); + + rtgui_menu_hiden(menu); } } @@ -126,10 +160,21 @@ static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t* { rtgui_menu_t* menu = (rtgui_menu_t*) widget; + if (menu->parent_menu != RT_NULL) + { + /* whether click on parent menu */ + if (rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_TRUE && + menu->parent_menu->items[menu->parent_menu->items_list->current_item].submenu == menu->items) + return RT_TRUE; + } + /* submenu is activate */ if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU) { /* if sub menu activated, not hide menu */ + if (menu->sub_menu != RT_NULL && + rtgui_win_is_activated(RTGUI_WIN(menu->sub_menu)) == RT_TRUE) + return RT_TRUE; } rtgui_win_hiden(RTGUI_WIN(menu)); @@ -140,7 +185,7 @@ static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t* /* if it's a submenu, try to hide parent menu */ if (menu->parent_menu != RT_NULL && - !rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu))) + rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_FALSE) { rtgui_menu_on_deactivate(RTGUI_WIDGET(menu->parent_menu), event); } @@ -222,3 +267,11 @@ void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y) /* show menu window */ rtgui_win_show(RTGUI_WIN(menu), RT_FALSE); } + +void rtgui_menu_hiden(struct rtgui_menu* menu) +{ + rtgui_win_hiden(RTGUI_WIN(menu)); + + if (menu->parent_menu != RT_NULL) + rtgui_menu_hiden(menu->parent_menu); +} diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c new file mode 100644 index 0000000000..eed59c99d4 --- /dev/null +++ b/components/rtgui/widgets/notebook.c @@ -0,0 +1,76 @@ +#include +#include + +rtgui_type_t *rtgui_notebook_type_get(void) +{ +} + +rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect) +{ +} + +void rtgui_notebook_destroy(rtgui_notebook_t* notebook) +{ +} + +void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_widget_t* child) +{ +} + +int rtgui_notebook_get_count(rtgui_notebootk_t* notebook) +{ + return notebook->count; +} + +rtgui_widget_t* rtgui_notebook_get_current(rtgui_notebook_t* notebook) +{ + RT_ASSERT(notebook != RT_NULL); + if (notebook->current != RTGUI_NOT_FOUND) + return ¬ebook->childs[notebook->current]; + + return RT_NULL; +} +void rtgui_notebook_set_current(rtgui_notebook_t* notebook, rtgui_widget_t* widget) +{ + rt_int16_t index; + + RT_ASSERT(notebook != RT_NULL); + + for (index = 0; index < notebook->count; index ++) + { + if (widget == ¬ebook->childs[index]) + { + rtgui_notebook_set_current_by_index(notebook, index); + return; + } + } +} + +void rtgui_notebook_set_current_by_index(rtgui_notebook_t* notebook, rt_uint16_t index) +{ + RT_ASSERT(notebook != RT_NULL); + + if ((index < notebook->count) && (notebook->current != index)) + { + if (notebook->current != RTGUI_NOT_FOUND) + rtgui_widget_hide(¬ebook->childs[notebook->current]); + + notebook->current = index; + rtgui_widget_show(¬ebook->childs[notebook->current]); + rtgui_widget_update(¬ebook->childs[notebook->current]); + } +} + +rtgui_widget_t* rtgui_notebook_get_index(rtgui_notebook_t* notebook, rt_uint16_t index) +{ + RT_ASSERT(notebook != RT_NULL); + if (index < notebook->count) + return ¬ebook->childs[index]; + + return RT_NULL; +} + +rt_bool_t rtgui_notebook_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +{ + return RT_FALSE; +} diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c index 34b022c04a..b3c5450444 100644 --- a/components/rtgui/widgets/widget.c +++ b/components/rtgui/widgets/widget.c @@ -138,6 +138,14 @@ void rtgui_widget_set_rect(rtgui_widget_t* widget, rtgui_rect_t* rect) } } +void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect) +{ + RT_ASSERT(widget != RT_NULL); + RT_ASSERT(rect != RT_NULL); + + *rect = widget->extent; +} + #ifndef RTGUI_USING_SMALL_SIZE void rtgui_widget_set_miniwidth(rtgui_widget_t* widget, int width) { diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c index 13982395ef..824a7ac014 100644 --- a/components/rtgui/widgets/window.c +++ b/components/rtgui/widgets/window.c @@ -306,7 +306,9 @@ rt_bool_t rtgui_win_is_activated(struct rtgui_win* win) { RT_ASSERT(win != RT_NULL); - return win->style & RTGUI_WIN_STYLE_ACTIVATE; + if (win->style & RTGUI_WIN_STYLE_ACTIVATE) return RT_TRUE; + + return RT_FALSE; } void rtgui_win_move(struct rtgui_win* win, int x, int y) @@ -413,7 +415,8 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even case RTGUI_EVENT_WIN_ACTIVATE: if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win))) { - rt_kprintf("activate window, but window is hide!\n"); + /* activate a hide window */ + return RT_TRUE; } win->style |= RTGUI_WIN_STYLE_ACTIVATE;