Selaa lähdekoodia

update menu control and add notebook control.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1220 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 14 vuotta sitten
vanhempi
commit
297405c3c6

+ 1 - 0
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

+ 1 - 0
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
 

+ 39 - 0
components/rtgui/include/rtgui/widgets/notebook.h

@@ -0,0 +1,39 @@
+#ifndef __RTGUI_NOTEBOOK_H__
+#define __RTGUI_NOTEBOOK_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/container.h>
+
+/** 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

+ 1 - 0
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);

+ 24 - 4
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;
+}

+ 60 - 7
components/rtgui/widgets/menu.c

@@ -2,10 +2,6 @@
 #include <rtgui/widgets/menu.h>
 #include <rtgui/rtgui_theme.h>
 
-#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);
+}

+ 76 - 0
components/rtgui/widgets/notebook.c

@@ -0,0 +1,76 @@
+#include <rtgui/rtgui.h>
+#include <rtgui/widgets/notebook.h>
+
+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 &notebook->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 == &notebook->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(&notebook->childs[notebook->current]);
+		
+		notebook->current = index;
+		rtgui_widget_show(&notebook->childs[notebook->current]);
+		rtgui_widget_update(&notebook->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 &notebook->childs[index];
+
+	return RT_NULL;
+}
+
+rt_bool_t rtgui_notebook_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
+{
+	return RT_FALSE;
+}

+ 8 - 0
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)
 {

+ 5 - 2
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;