From 774c4d961a3ef5a041aafd417b42ec35123bea0d Mon Sep 17 00:00:00 2001 From: "bernard.xiong" Date: Sun, 8 Nov 2009 23:57:21 +0000 Subject: [PATCH] add leaked destructor in widgets git-svn-id: https://rt-thread.googlecode.com/svn/trunk@157 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- rtgui/common/image.c | 3 +- rtgui/common/image_hdc.c | 24 +- rtgui/include/rtgui/driver.h | 3 + rtgui/include/rtgui/rtgui_config.h | 2 +- rtgui/include/rtgui/rtgui_server.h | 1 + rtgui/include/rtgui/widgets/workbench.h | 2 + rtgui/server/panel.c | 13 + rtgui/server/server.c | 2 +- rtgui/widgets/button.c | 19 +- rtgui/widgets/iconbox.c | 15 +- rtgui/widgets/label.c | 4 +- rtgui/widgets/textbox.c | 2 +- rtgui/widgets/title.c | 10 +- rtgui/widgets/toplevel.c | 1 + rtgui/widgets/view.c | 15 +- rtgui/widgets/window.c | 3 +- rtgui/widgets/workbench.c | 917 ++++++++++++------------ 17 files changed, 558 insertions(+), 478 deletions(-) diff --git a/rtgui/common/image.c b/rtgui/common/image.c index 9908c2962a..466807eb53 100644 --- a/rtgui/common/image.c +++ b/rtgui/common/image.c @@ -36,7 +36,8 @@ void rtgui_system_image_init(void) { /* always support XPM image */ rtgui_image_xpm_init(); - + rtgui_image_hdc_init(); + #ifdef RTGUI_IMAGE_BMP rtgui_image_bmp_init(); #endif diff --git a/rtgui/common/image_hdc.c b/rtgui/common/image_hdc.c index b38a276c7e..310725db4e 100644 --- a/rtgui/common/image_hdc.c +++ b/rtgui/common/image_hdc.c @@ -129,15 +129,18 @@ static void rtgui_image_hdc_unload(struct rtgui_image* image) } } -static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect) +static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* dst_rect) { rt_uint16_t y, w, h; rtgui_color_t foreground; struct rtgui_image_hdc* hdc; rt_uint16_t rect_pitch, hw_pitch; - rtgui_rect_t dc_rect; + rtgui_rect_t dc_rect, _rect, *rect; - RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL); + RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL); + + _rect = *dst_rect; + rect = &_rect; /* this dc is not visible */ if (dc->get_visible(dc) != RT_TRUE) return; @@ -148,8 +151,7 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, /* transfer logic coordinate to physical coordinate */ if (dc->type == RTGUI_DC_HW) { - struct rtgui_dc_hw *hw_dc = (struct rtgui_dc_hw*)dc; - dc_rect = hw_dc->owner->extent; + dc_rect = ((struct rtgui_dc_hw*)dc)->owner->extent; } else rtgui_dc_get_rect(dc, &dc_rect); rtgui_rect_moveto(rect, dc_rect.x1, dc_rect.y1); @@ -197,15 +199,15 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, for (y = 0; y < h; y ++) { - hdc->hw_driver->draw_raw_hline(rect_ptr, rect->x1, rect->x2, rect->y1 + y); - rect_ptr += rect_pitch; + hdc->hw_driver->draw_raw_hline(rect_ptr, rect->x1, rect->x1 + w, rect->y1 + y); + rect_ptr += hdc->pitch; } } } else { rt_uint8_t* rect_ptr; - rect_ptr = rtgui_malloc(rect_pitch); + rect_ptr = rtgui_malloc(hdc->pitch); if (rect_ptr == RT_NULL) return; /* no memory */ /* seek to the begin of pixel data */ @@ -223,7 +225,7 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, for (y = 0; y < h; y ++) { /* read pixel data */ - if (rtgui_filerw_read(hdc->filerw, rect_ptr, 1, rect_pitch) != rect_pitch) + if (rtgui_filerw_read(hdc->filerw, rect_ptr, 1, hdc->pitch) != hdc->pitch) break; /* read data failed */ rt_memcpy(hw_ptr, rect_ptr, rect_pitch); @@ -235,10 +237,10 @@ static void rtgui_image_hdc_blit(struct rtgui_image* image, struct rtgui_dc* dc, for (y = 0; y < h; y ++) { /* read pixel data */ - if (rtgui_filerw_read(hdc->filerw, rect_ptr, 1, rect_pitch) != rect_pitch) + if (rtgui_filerw_read(hdc->filerw, rect_ptr, 1, hdc->pitch) != hdc->pitch) break; /* read data failed */ - hdc->hw_driver->draw_raw_hline(rect_ptr, rect->x1, rect->x2, rect->y1 + y); + hdc->hw_driver->draw_raw_hline(rect_ptr, rect->x1, rect->x1 + w, rect->y1 + y); } } diff --git a/rtgui/include/rtgui/driver.h b/rtgui/include/rtgui/driver.h index 859a51b79b..cc5cd6e249 100644 --- a/rtgui/include/rtgui/driver.h +++ b/rtgui/include/rtgui/driver.h @@ -42,6 +42,9 @@ struct rtgui_graphic_driver void (*draw_hline)(rtgui_color_t *c, rt_base_t x1, rt_base_t x2, rt_base_t y); void (*draw_vline)(rtgui_color_t *c, rt_base_t x , rt_base_t y1, rt_base_t y2); + /* draw raw hline */ + void (*draw_raw_hline)(rt_uint8_t *pixels, rt_base_t x1, rt_base_t x2, rt_base_t y); + /* the driver list */ rtgui_list_t list; }; diff --git a/rtgui/include/rtgui/rtgui_config.h b/rtgui/include/rtgui/rtgui_config.h index fc63f17d6c..4f3716302c 100644 --- a/rtgui/include/rtgui/rtgui_config.h +++ b/rtgui/include/rtgui/rtgui_config.h @@ -26,7 +26,7 @@ // #define RT_USING_STDIO_FILERW #define RT_USING_DFS_FILERW -#define RTGUI_IMAGE_PNG +// #define RTGUI_IMAGE_PNG #define RTGUI_SVR_THREAD_PRIORITY 15 #define RTGUI_SVR_THREAD_TIMESLICE 5 diff --git a/rtgui/include/rtgui/rtgui_server.h b/rtgui/include/rtgui/rtgui_server.h index 738e60100e..8723d6e4f3 100644 --- a/rtgui/include/rtgui/rtgui_server.h +++ b/rtgui/include/rtgui/rtgui_server.h @@ -70,6 +70,7 @@ void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size); /* register or deregister panel in server */ void rtgui_panel_register(char* name, rtgui_rect_t* extent); void rtgui_panel_deregister(char* name); +void rtgui_panel_set_default_focused(char* name); #endif diff --git a/rtgui/include/rtgui/widgets/workbench.h b/rtgui/include/rtgui/widgets/workbench.h index 354cc6b474..858c1a49cf 100644 --- a/rtgui/include/rtgui/widgets/workbench.h +++ b/rtgui/include/rtgui/widgets/workbench.h @@ -51,6 +51,7 @@ struct rtgui_workbench /* workbench title */ unsigned char* title; + rtgui_view_t* current_view; }; rtgui_workbench_t *rtgui_workbench_create(const char* panel_name, const unsigned char* title); @@ -67,6 +68,7 @@ void rtgui_workbench_event_loop(rtgui_workbench_t* workbench); rt_err_t rtgui_workbench_show (rtgui_workbench_t* workbench); rt_err_t rtgui_workbench_hide (rtgui_workbench_t* workbench); +rtgui_view_t *rtgui_workbench_get_current_view(rtgui_workbench_t * workbench); void rtgui_workbench_add_view(rtgui_workbench_t* workbench, rtgui_view_t* view); void rtgui_workbench_remove_view(rtgui_workbench_t* workbench, rtgui_view_t* view); void rtgui_workbench_show_view(rtgui_workbench_t* workbench, rtgui_view_t* view); diff --git a/rtgui/server/panel.c b/rtgui/server/panel.c index 744fa5b3f7..e52858a91f 100644 --- a/rtgui/server/panel.c +++ b/rtgui/server/panel.c @@ -77,6 +77,19 @@ void rtgui_panel_deregister(char* name) } } +/* set default focused panel, please use it after registered panel */ +void rtgui_panel_set_default_focused(char* name) +{ + extern struct rtgui_panel* rtgui_server_focus_panel; + struct rtgui_panel* panel; + + panel = rtgui_panel_find(name); + if (panel != RT_NULL) + { + rtgui_server_focus_panel = panel; + } +} + struct rtgui_panel* rtgui_panel_find(char* name) { struct rtgui_list_node* node; diff --git a/rtgui/server/server.c b/rtgui/server/server.c index eb5615d8f5..c782e0e138 100644 --- a/rtgui/server/server.c +++ b/rtgui/server/server.c @@ -28,7 +28,7 @@ static struct rt_messagequeue rtgui_server_mq; static char rtgui_server_msg_pool[2048]; extern struct rtgui_topwin* rtgui_server_focus_topwin; -static struct rtgui_panel* rtgui_server_focus_panel = RT_NULL; +struct rtgui_panel* rtgui_server_focus_panel = RT_NULL; void rtgui_server_create_application(struct rtgui_event_panel_attach* event) { diff --git a/rtgui/widgets/button.c b/rtgui/widgets/button.c index 877f7faed5..f5bd8877d4 100644 --- a/rtgui/widgets/button.c +++ b/rtgui/widgets/button.c @@ -35,6 +35,21 @@ static void _rtgui_button_constructor(rtgui_button_t *button) RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(button)) = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; } +static void _rtgui_button_destructor(rtgui_button_t *button) +{ + if (button->pressed_image != RT_NULL) + { + rtgui_image_destroy(button->pressed_image); + button->pressed_image = RT_NULL; + } + + if (button->unpressed_image != RT_NULL) + { + rtgui_image_destroy(button->unpressed_image); + button->unpressed_image = RT_NULL; + } +} + rtgui_type_t *rtgui_button_type_get(void) { static rtgui_type_t *button_type = RT_NULL; @@ -42,7 +57,9 @@ rtgui_type_t *rtgui_button_type_get(void) if (!button_type) { button_type = rtgui_type_create("button", RTGUI_LABEL_TYPE, - sizeof(rtgui_button_t), RTGUI_CONSTRUCTOR(_rtgui_button_constructor), RT_NULL); + sizeof(rtgui_button_t), + RTGUI_CONSTRUCTOR(_rtgui_button_constructor), + RTGUI_DESTRUCTOR(_rtgui_button_destructor)); } return button_type; diff --git a/rtgui/widgets/iconbox.c b/rtgui/widgets/iconbox.c index ffb81fc493..b44cab1e76 100644 --- a/rtgui/widgets/iconbox.c +++ b/rtgui/widgets/iconbox.c @@ -28,6 +28,18 @@ static void _rtgui_iconbox_constructor(rtgui_iconbox_t *iconbox) iconbox->text_position = RTGUI_ICONBOX_TEXT_BELOW; } +static void _rtgui_iconbox_destructor(rtgui_iconbox_t *iconbox) +{ + if (iconbox->image != RT_NULL) + { + rtgui_image_destroy(iconbox->image); + iconbox->image = 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; @@ -35,7 +47,8 @@ rtgui_type_t *rtgui_iconbox_type_get(void) if (!iconbox_type) { iconbox_type = rtgui_type_create("iconbox", RTGUI_WIDGET_TYPE, - sizeof(rtgui_iconbox_t), RTGUI_CONSTRUCTOR(_rtgui_iconbox_constructor), RT_NULL); + sizeof(rtgui_iconbox_t), RTGUI_CONSTRUCTOR(_rtgui_iconbox_constructor), + RTGUI_DESTRUCTOR(_rtgui_iconbox_destructor)); } return iconbox_type; diff --git a/rtgui/widgets/label.c b/rtgui/widgets/label.c index e326bbf0d2..992142472d 100644 --- a/rtgui/widgets/label.c +++ b/rtgui/widgets/label.c @@ -28,7 +28,7 @@ static void _rtgui_label_constructor(rtgui_label_t *label) static void _rtgui_label_destructor(rtgui_label_t *label) { /* release text memory */ - rtgui_free(label->text); + rt_free(label->text); label->text = RT_NULL; } @@ -105,7 +105,7 @@ void rtgui_label_set_text(rtgui_label_t* label, const unsigned char* text) if (label->text != RT_NULL) { /* release old text memory */ - rtgui_free(label->text); + rt_free(label->text); } if (text != RT_NULL) label->text = (unsigned char*)rt_strdup((const char*)text); diff --git a/rtgui/widgets/textbox.c b/rtgui/widgets/textbox.c index a469bd65ee..bd79db3ec2 100644 --- a/rtgui/widgets/textbox.c +++ b/rtgui/widgets/textbox.c @@ -53,7 +53,7 @@ static void _rtgui_textbox_deconstructor(rtgui_textbox_t *box) { if (box->text != RT_NULL) { - rtgui_free(box->text); + rt_free(box->text); box->text = RT_NULL; } diff --git a/rtgui/widgets/title.c b/rtgui/widgets/title.c index 1e96cd34ed..41b8924cb7 100644 --- a/rtgui/widgets/title.c +++ b/rtgui/widgets/title.c @@ -21,6 +21,12 @@ static void _rtgui_wintitle_constructor(rtgui_wintitle_t* wintitle) RTGUI_WIDGET(wintitle)->flag = RTGUI_WIDGET_FLAG_DEFAULT; } +static void _rtgui_wintitle_deconstructor(rtgui_wintitle_t* wintitle) +{ + rt_free(wintitle->title); + wintitle->title = RT_NULL; +} + rtgui_type_t* rtgui_wintitle_type_get() { static rtgui_type_t *wintitle_type = RT_NULL; @@ -28,7 +34,9 @@ rtgui_type_t* rtgui_wintitle_type_get() if (!wintitle_type) { wintitle_type = rtgui_type_create("wintitle", RTGUI_TOPLEVEL_TYPE, - sizeof(rtgui_wintitle_t), RTGUI_CONSTRUCTOR(_rtgui_wintitle_constructor), RT_NULL); + sizeof(rtgui_wintitle_t), + RTGUI_CONSTRUCTOR(_rtgui_wintitle_constructor), + RTGUI_DESTRUCTOR(_rtgui_wintitle_deconstructor)); } return wintitle_type; diff --git a/rtgui/widgets/toplevel.c b/rtgui/widgets/toplevel.c index a20663ee24..b2089449fd 100644 --- a/rtgui/widgets/toplevel.c +++ b/rtgui/widgets/toplevel.c @@ -41,6 +41,7 @@ static void _rtgui_toplevel_destructor(rtgui_toplevel_t* toplevel) rtgui_free(toplevel->external_clip_rect); toplevel->drawing = 0; + rtgui_free(toplevel->external_clip_rect); toplevel->external_clip_rect = RT_NULL; toplevel->external_clip_size = 0; toplevel->focus = RT_NULL; diff --git a/rtgui/widgets/view.c b/rtgui/widgets/view.c index d016515af9..41b433c7ab 100644 --- a/rtgui/widgets/view.c +++ b/rtgui/widgets/view.c @@ -25,6 +25,15 @@ static void _rtgui_view_constructor(rtgui_view_t *view) view->title = RT_NULL; } +static void _rtgui_view_destructor(rtgui_view_t *view) +{ + if (view->title != RT_NULL) + { + rt_free(view->title); + view->title = RT_NULL; + } +} + rtgui_type_t *rtgui_view_type_get(void) { static rtgui_type_t *view_type = RT_NULL; @@ -32,7 +41,9 @@ rtgui_type_t *rtgui_view_type_get(void) if (!view_type) { view_type = rtgui_type_create("view", RTGUI_CONTAINER_TYPE, - sizeof(rtgui_view_t), RTGUI_CONSTRUCTOR(_rtgui_view_constructor), RT_NULL); + sizeof(rtgui_view_t), + RTGUI_CONSTRUCTOR(_rtgui_view_constructor), + RTGUI_DESTRUCTOR(_rtgui_view_destructor)); } return view_type; @@ -113,6 +124,8 @@ void rtgui_view_show(rtgui_view_t* view) } rtgui_workbench_show_view((rtgui_workbench_t*)(RTGUI_WIDGET(view)->parent), view); + if (RTGUI_WIDGET_IS_FOCUSABLE(RTGUI_WIDGET(view))) + rtgui_widget_focus(RTGUI_WIDGET(view)); } void rtgui_view_hide(rtgui_view_t* view) diff --git a/rtgui/widgets/window.c b/rtgui/widgets/window.c index d2cbcce286..01d4bd6057 100644 --- a/rtgui/widgets/window.c +++ b/rtgui/widgets/window.c @@ -50,12 +50,13 @@ static void _rtgui_win_destructor(rtgui_win_t* win) if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(win)->server, RTGUI_EVENT(&edestroy), sizeof(struct rtgui_event_win_destroy)) != RT_EOK) { + /* destroy in server failed */ return; } } /* release field */ - rtgui_free(win->title); + rt_free(win->title); } static rt_bool_t _rtgui_win_create_in_server(rtgui_win_t* win) diff --git a/rtgui/widgets/workbench.c b/rtgui/widgets/workbench.c index 795b1378eb..cdeb93232b 100644 --- a/rtgui/widgets/workbench.c +++ b/rtgui/widgets/workbench.c @@ -12,461 +12,466 @@ * 2009-10-04 Bernard first version */ #include -#include -#include - -static void _rtgui_workbench_constructor(rtgui_workbench_t *workbench) -{ - /* set event handler */ - rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), rtgui_workbench_event_handler); - - /* set attributes */ - workbench->panel = RT_NULL; - workbench->flag = RTGUI_WORKBENCH_FLAG_DEFAULT; -} - -static void _rtgui_workbench_destructor(rtgui_workbench_t *workbench) -{ - RT_ASSERT(workbench != RT_NULL); - - if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) - { - struct rtgui_event_panel_detach edetach; - RTGUI_EVENT_PANEL_DETACH_INIT(&edetach); - - /* detach from panel */ - edetach.panel = workbench->panel; - - /* send PANEL DETACH to server */ - if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, - RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK) - return; - - RTGUI_TOPLEVEL(workbench)->server = RT_NULL; - } - - /* release title */ - if (workbench->title != RT_NULL) - { - rtgui_free(workbench->title); - } -} - -rtgui_type_t *rtgui_workbench_type_get(void) -{ - static rtgui_type_t *workbench_type = RT_NULL; - - if (!workbench_type) - { - workbench_type = rtgui_type_create("workbench", RTGUI_TOPLEVEL_TYPE, - sizeof(rtgui_workbench_t), - RTGUI_CONSTRUCTOR(_rtgui_workbench_constructor), - RTGUI_DESTRUCTOR(_rtgui_workbench_destructor)); - } - - return workbench_type; -} - -rtgui_workbench_t *rtgui_workbench_create(const char* panel_name, const unsigned char* title) -{ - struct rtgui_workbench* workbench; - - /* the server thread id */ - rt_thread_t server = rtgui_thread_get_server(); - if (server == RT_NULL) - { - rt_kprintf("can't find rtgui server\n"); - return RT_NULL; - } - - /* create workbench */ - workbench = (rtgui_workbench_t*) rtgui_widget_create (RTGUI_WORKBENCH_TYPE); - if (workbench != RT_NULL) - { - /* the buffer uses to receive event */ - union - { - struct rtgui_event_panel_attach ecreate; - struct rtgui_event_panel_info epanel; - - char buffer[256]; /* use to recv other information */ - } event; - - /* set workbench title */ - workbench->title = (unsigned char*)rt_strdup((char*)title); - - /* create application in server */ - RTGUI_EVENT_PANEL_ATTACH_INIT(&(event.ecreate)); - - /* set the panel name and workbench */ - rt_strncpy(event.ecreate.panel_name, panel_name, RTGUI_NAME_MAX); - event.ecreate.workbench = workbench; - - /* send PANEL ATTACH to server */ - if (rtgui_thread_send_sync(server, - &(event.ecreate.parent), sizeof(struct rtgui_event_panel_attach)) != RTGUI_STATUS_OK) - { - return RT_NULL; - } - - /* get PANEL INFO */ - rtgui_thread_recv_filter(RTGUI_EVENT_PANEL_INFO, &(event.epanel.parent), sizeof(event)); - - /* set panel */ - workbench->panel = (struct rtgui_panel*)event.epanel.panel; - - /* connected */ - RTGUI_TOPLEVEL(workbench)->server = server; - - /* set extent of workbench */ - rtgui_widget_set_rect(RTGUI_WIDGET(workbench), &(event.epanel.extent)); - - /* set workbench in thread */ - rtgui_thread_set_widget(RTGUI_WIDGET(workbench)); - } - - return workbench; -} - -void rtgui_workbench_destroy(rtgui_workbench_t* workbench) -{ - RT_ASSERT(workbench != RT_NULL); - - if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) - { - struct rtgui_event_panel_detach edetach; - RTGUI_EVENT_PANEL_DETACH_INIT(&edetach); - - /* detach from panel */ - edetach.panel = workbench->panel; - - /* send PANEL DETACH to server */ - if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, - RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK) - return; - - RTGUI_TOPLEVEL(workbench)->server = RT_NULL; - } - - rtgui_widget_destroy(RTGUI_WIDGET(workbench)); -} - -void rtgui_workbench_set_flag(rtgui_workbench_t* workbench, rt_uint8_t flag) -{ - RT_ASSERT(workbench != RT_NULL); - - workbench->flag = flag; -} - -rtgui_view_t *rtgui_workbench_get_current_view(rtgui_workbench_t * workbench) -{ - struct rtgui_list_node* node; - struct rtgui_widget* view; - - RT_ASSERT(workbench != RT_NULL); - - /* find the first shown view */ - rtgui_list_foreach(node, &(RTGUI_CONTAINER(workbench)->children)) - { - view = rtgui_list_entry(node, struct rtgui_widget, sibling); - - /* is it a shown view? */ - if (!RTGUI_WIDGET_IS_HIDE(view)) - { - return (rtgui_view_t*)view; - } - } - - return RT_NULL; -} - -void rtgui_workbench_event_loop(rtgui_workbench_t* workbench) -{ - int quit = 0; - - /* the buffer uses to receive event */ - char event_buf[256]; - struct rtgui_event* event = (struct rtgui_event*)&event_buf[0]; - - /* show workbench firstly */ - rtgui_workbench_show(workbench); - - while (!quit) - { - if (rtgui_thread_recv(event, sizeof(event_buf)) == RT_EOK) - { - RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event); - } - } -} - -rt_err_t rtgui_workbench_show(rtgui_workbench_t* workbench) -{ - RT_ASSERT(workbench != RT_NULL); - - if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) - { - struct rtgui_event_panel_show eraise; - RTGUI_EVENT_PANEL_SHOW_INIT(&eraise); - eraise.workbench = workbench; - - eraise.panel = workbench->panel; - if (rtgui_thread_send_sync(workbench->parent.server, RTGUI_EVENT(&eraise), - sizeof(struct rtgui_event_panel_show)) != RT_EOK) - return -RT_ERROR; - - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(workbench)); - rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); - } - else return -RT_ERROR; - - return RT_EOK; -} - -rt_err_t rtgui_workbench_hide(rtgui_workbench_t* workbench) -{ - if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) - { - struct rtgui_event_panel_hide ehide; - RTGUI_EVENT_PANEL_HIDE_INIT(&ehide); - - RT_ASSERT(workbench != RT_NULL); - if (workbench->parent.server == RT_NULL) return -RT_ERROR; - - ehide.panel = workbench->panel; - if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, RTGUI_EVENT(&ehide), - sizeof(struct rtgui_event_panel_hide)) != RT_EOK) - return -RT_ERROR; - - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench)); - rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); - } - - return RT_EOK; -} - -rt_bool_t rtgui_workbench_event_handler(rtgui_widget_t* widget, rtgui_event_t* event) -{ - struct rtgui_workbench* workbench = (struct rtgui_workbench*)widget; - - switch (event->type) - { - case RTGUI_EVENT_PANEL_DETACH: - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench)); - RTGUI_TOPLEVEL(workbench)->server = RT_NULL; - return RT_TRUE; - - case RTGUI_EVENT_PANEL_SHOW: - /* show workbench in server */ - rtgui_workbench_show(workbench); - break; - - case RTGUI_EVENT_PANEL_HIDE: +#include +#include + +static void _rtgui_workbench_constructor(rtgui_workbench_t *workbench) +{ + /* set event handler */ + rtgui_widget_set_event_handler(RTGUI_WIDGET(workbench), rtgui_workbench_event_handler); + + /* set attributes */ + workbench->panel = RT_NULL; + workbench->flag = RTGUI_WORKBENCH_FLAG_DEFAULT; + workbench->current_view = RT_NULL; +} + +static void _rtgui_workbench_destructor(rtgui_workbench_t *workbench) +{ + RT_ASSERT(workbench != RT_NULL); + + if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) + { + struct rtgui_event_panel_detach edetach; + RTGUI_EVENT_PANEL_DETACH_INIT(&edetach); + + /* detach from panel */ + edetach.panel = workbench->panel; + + /* send PANEL DETACH to server */ + if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, + RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK) + return; + + RTGUI_TOPLEVEL(workbench)->server = RT_NULL; + } + + /* release title */ + rt_free(workbench->title); + workbench->title = RT_NULL; +} + +rtgui_type_t *rtgui_workbench_type_get(void) +{ + static rtgui_type_t *workbench_type = RT_NULL; + + if (!workbench_type) + { + workbench_type = rtgui_type_create("workbench", RTGUI_TOPLEVEL_TYPE, + sizeof(rtgui_workbench_t), + RTGUI_CONSTRUCTOR(_rtgui_workbench_constructor), + RTGUI_DESTRUCTOR(_rtgui_workbench_destructor)); + } + + return workbench_type; +} + +rtgui_workbench_t *rtgui_workbench_create(const char* panel_name, const unsigned char* title) +{ + struct rtgui_workbench* workbench; + + /* the server thread id */ + rt_thread_t server = rtgui_thread_get_server(); + if (server == RT_NULL) + { + rt_kprintf("can't find rtgui server\n"); + return RT_NULL; + } + + /* create workbench */ + workbench = (rtgui_workbench_t*) rtgui_widget_create (RTGUI_WORKBENCH_TYPE); + if (workbench != RT_NULL) + { + /* the buffer uses to receive event */ + union + { + struct rtgui_event_panel_attach ecreate; + struct rtgui_event_panel_info epanel; + + char buffer[256]; /* use to recv other information */ + } event; + + /* set workbench title */ + workbench->title = (unsigned char*)rt_strdup((char*)title); + + /* create application in server */ + RTGUI_EVENT_PANEL_ATTACH_INIT(&(event.ecreate)); + + /* set the panel name and workbench */ + rt_strncpy(event.ecreate.panel_name, panel_name, RTGUI_NAME_MAX); + event.ecreate.workbench = workbench; + + /* send PANEL ATTACH to server */ + if (rtgui_thread_send_sync(server, + &(event.ecreate.parent), sizeof(struct rtgui_event_panel_attach)) != RTGUI_STATUS_OK) + { + return RT_NULL; + } + + /* get PANEL INFO */ + rtgui_thread_recv_filter(RTGUI_EVENT_PANEL_INFO, &(event.epanel.parent), sizeof(event)); + + /* set panel */ + workbench->panel = (struct rtgui_panel*)event.epanel.panel; + + /* connected */ + RTGUI_TOPLEVEL(workbench)->server = server; + + /* set extent of workbench */ + rtgui_widget_set_rect(RTGUI_WIDGET(workbench), &(event.epanel.extent)); + + /* set workbench in thread */ + rtgui_thread_set_widget(RTGUI_WIDGET(workbench)); + } + + return workbench; +} + +void rtgui_workbench_destroy(rtgui_workbench_t* workbench) +{ + RT_ASSERT(workbench != RT_NULL); + + if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) + { + struct rtgui_event_panel_detach edetach; + RTGUI_EVENT_PANEL_DETACH_INIT(&edetach); + + /* detach from panel */ + edetach.panel = workbench->panel; + + /* send PANEL DETACH to server */ + if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, + RTGUI_EVENT(&edetach), sizeof(struct rtgui_event_panel_detach)) != RT_EOK) + return; + + RTGUI_TOPLEVEL(workbench)->server = RT_NULL; + } + + rtgui_widget_destroy(RTGUI_WIDGET(workbench)); +} + +void rtgui_workbench_set_flag(rtgui_workbench_t* workbench, rt_uint8_t flag) +{ + RT_ASSERT(workbench != RT_NULL); + + workbench->flag = flag; +} + +void rtgui_workbench_event_loop(rtgui_workbench_t* workbench) +{ + int quit = 0; + + /* the buffer uses to receive event */ + char event_buf[256]; + struct rtgui_event* event = (struct rtgui_event*)&event_buf[0]; + + /* show workbench firstly */ + rtgui_workbench_show(workbench); + + while (!quit) + { + if (rtgui_thread_recv(event, sizeof(event_buf)) == RT_EOK) + { + RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event); + } + } +} + +rt_err_t rtgui_workbench_show(rtgui_workbench_t* workbench) +{ + RT_ASSERT(workbench != RT_NULL); + + if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) + { + struct rtgui_event_panel_show eraise; + RTGUI_EVENT_PANEL_SHOW_INIT(&eraise); + eraise.workbench = workbench; + + eraise.panel = workbench->panel; + if (rtgui_thread_send_sync(workbench->parent.server, RTGUI_EVENT(&eraise), + sizeof(struct rtgui_event_panel_show)) != RT_EOK) + return -RT_ERROR; + + RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(workbench)); + rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); + } + else return -RT_ERROR; + + return RT_EOK; +} + +rt_err_t rtgui_workbench_hide(rtgui_workbench_t* workbench) +{ + if (RTGUI_TOPLEVEL(workbench)->server != RT_NULL) + { + struct rtgui_event_panel_hide ehide; + RTGUI_EVENT_PANEL_HIDE_INIT(&ehide); + + RT_ASSERT(workbench != RT_NULL); + if (workbench->parent.server == RT_NULL) return -RT_ERROR; + + ehide.panel = workbench->panel; + if (rtgui_thread_send_sync(RTGUI_TOPLEVEL(workbench)->server, RTGUI_EVENT(&ehide), + sizeof(struct rtgui_event_panel_hide)) != RT_EOK) + return -RT_ERROR; + + RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench)); + rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); + } + + return RT_EOK; +} + +rt_bool_t rtgui_workbench_event_handler(rtgui_widget_t* widget, rtgui_event_t* event) +{ + struct rtgui_workbench* workbench = (struct rtgui_workbench*)widget; + + switch (event->type) + { + case RTGUI_EVENT_PANEL_DETACH: + RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench)); + RTGUI_TOPLEVEL(workbench)->server = RT_NULL; + return RT_TRUE; + + case RTGUI_EVENT_PANEL_SHOW: + /* show workbench in server */ + rtgui_workbench_show(workbench); + break; + + case RTGUI_EVENT_PANEL_HIDE: /* hide widget */ - RTGUI_WIDGET_HIDE(widget); - break; - - case RTGUI_EVENT_MOUSE_MOTION: + RTGUI_WIDGET_HIDE(widget); + break; + + case RTGUI_EVENT_MOUSE_MOTION: + { + struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event; + struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid); + + /* check the destination window */ + if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) + { + RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); + } + else + { + /* let viewer to handle it */ + rtgui_view_t* view = workbench->current_view; + if (view != RT_NULL && + RTGUI_WIDGET(view)->event_handler != RT_NULL) + { + RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event); + } + } + } + break; + + case RTGUI_EVENT_MOUSE_BUTTON: + { + struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event; + struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid); + + /* check the destination window */ + if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) + { + RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); + } + else + { + /* let viewer to handle it */ + rtgui_view_t* view = workbench->current_view; + if (view != RT_NULL && + RTGUI_WIDGET(view)->event_handler != RT_NULL) + { + RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event); + } + } + } + break; + + case RTGUI_EVENT_KBD: + { + struct rtgui_event_kbd* kbd = (struct rtgui_event_kbd*)event; + struct rtgui_toplevel* top = RTGUI_TOPLEVEL(kbd->wid); + + /* check the destination window */ + if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) + { + RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); + } + else + { + return rtgui_toplevel_event_handler(widget, event); + } + } + break; + + case RTGUI_EVENT_PAINT: + { + struct rtgui_event_paint* epaint = (struct rtgui_event_paint*)event; + struct rtgui_toplevel* top = RTGUI_TOPLEVEL(epaint->wid); + + /* check the destination window */ + if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) + { + RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); + } + else + { + rtgui_view_t* view; + + /* paint a view */ + view = workbench->current_view; + if (view != RT_NULL) + { + /* remake a paint event */ + RTGUI_EVENT_PAINT_INIT(epaint); + epaint->wid = RT_NULL; + + /* send this event to the view */ + if (RTGUI_WIDGET(view)->event_handler != RT_NULL) + { + RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event); + } + } + else + { + struct rtgui_dc* dc; + struct rtgui_rect rect; + + dc = rtgui_dc_begin_drawing(widget); + rtgui_widget_get_rect(widget, &rect); + rtgui_dc_fill_rect(dc, &rect); + rtgui_dc_end_drawing(dc); + } + } + } + break; + + case RTGUI_EVENT_CLIP_INFO: + { + struct rtgui_event_clip_info* eclip = (struct rtgui_event_clip_info*)event; + struct rtgui_widget* dest_widget = RTGUI_WIDGET(eclip->wid); + + if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL) + { + dest_widget->event_handler(dest_widget, event); + } + else + { + return rtgui_toplevel_event_handler(widget, event); + } + } + break; + + case RTGUI_EVENT_WIN_CLOSE: + case RTGUI_EVENT_WIN_ACTIVATE: + case RTGUI_EVENT_WIN_DEACTIVATE: + { + struct rtgui_event_win* wevent = (struct rtgui_event_win*)event; + struct rtgui_widget* dest_widget = RTGUI_WIDGET(wevent->wid); + if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL) + { + dest_widget->event_handler(dest_widget, event); + } + } + break; + + case RTGUI_EVENT_WIN_MOVE: + { + struct rtgui_event_win_move* wevent = (struct rtgui_event_win_move*)event; + struct rtgui_toplevel* top = RTGUI_TOPLEVEL(wevent->wid); + if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) + { + RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); + } + } + break; + + default: + return rtgui_toplevel_event_handler(widget, event); + } + + return RT_TRUE; +} + +/* + * + * view on workbench + * + */ + +void rtgui_workbench_add_view(rtgui_workbench_t* workbench, rtgui_view_t* view) +{ + rtgui_container_add_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view)); + /* hide view in default */ + RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view)); + + /* reset view extent */ + rtgui_widget_set_rect(RTGUI_WIDGET(view), &(RTGUI_WIDGET(workbench)->extent)); +} + +void rtgui_workbench_remove_view(rtgui_workbench_t* workbench, rtgui_view_t* view) +{ + if (view == workbench->current_view) + rtgui_workbench_hide_view(workbench, view); + + rtgui_container_remove_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view)); +} + +void rtgui_workbench_show_view(rtgui_workbench_t* workbench, rtgui_view_t* view) +{ + RT_ASSERT(workbench != RT_NULL); + RT_ASSERT(view != RT_NULL); + + /* already shown */ + if (workbench->current_view == view) return; + + if (workbench->current_view != RT_NULL) + { + /* hide old view */ + RTGUI_WIDGET_HIDE(RTGUI_WIDGET(workbench->current_view)); + } + + /* show view */ + RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(view)); + workbench->current_view = view; + + /* update workbench clip */ + rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); + + if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(workbench))) + { + rtgui_widget_update(RTGUI_WIDGET(view)); + } +} + +void rtgui_workbench_hide_view(rtgui_workbench_t* workbench, rtgui_view_t* view) +{ + RT_ASSERT(workbench != RT_NULL); + RT_ASSERT(view != RT_NULL); + + /* hide view */ + RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view)); + + if (view == workbench->current_view) + { + rtgui_view_t *next_view; + + workbench->current_view = RT_NULL; + + next_view = RTGUI_VIEW(rtgui_widget_get_next_sibling(RTGUI_WIDGET(view))); + if (next_view == RT_NULL) + next_view = RTGUI_VIEW(rtgui_widget_get_prev_sibling(RTGUI_WIDGET(view))); + + if (next_view != RT_NULL) { - struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event; - struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid); - - /* check the destination window */ - if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) - { - RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); - } - else - { - /* let viewer to handle it */ - rtgui_view_t* view = rtgui_workbench_get_current_view(workbench); - if (view != RT_NULL && - RTGUI_WIDGET(view)->event_handler != RT_NULL) - { - RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event); - } - } - } - break; - - case RTGUI_EVENT_MOUSE_BUTTON: - { - struct rtgui_event_mouse* emouse = (struct rtgui_event_mouse*)event; - struct rtgui_toplevel* top = RTGUI_TOPLEVEL(emouse->wid); - - /* check the destination window */ - if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) - { - RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); - } - else - { - /* let viewer to handle it */ - rtgui_view_t* view = rtgui_workbench_get_current_view(workbench); - if (view != RT_NULL && - RTGUI_WIDGET(view)->event_handler != RT_NULL) - { - RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event); - } - } - } - break; - - case RTGUI_EVENT_KBD: - { - struct rtgui_event_kbd* kbd = (struct rtgui_event_kbd*)event; - struct rtgui_toplevel* top = RTGUI_TOPLEVEL(kbd->wid); - - /* check the destination window */ - if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) - { - RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); - } - else - { - return rtgui_toplevel_event_handler(widget, event); - } - } - break; - - case RTGUI_EVENT_PAINT: - { - struct rtgui_event_paint* epaint = (struct rtgui_event_paint*)event; - struct rtgui_toplevel* top = RTGUI_TOPLEVEL(epaint->wid); - - /* check the destination window */ - if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) - { - RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); - } - else - { - rtgui_view_t* view; - - /* paint a view */ - view = rtgui_workbench_get_current_view(workbench); - if (view != RT_NULL) - { - /* remake a paint event */ - RTGUI_EVENT_PAINT_INIT(epaint); - epaint->wid = RT_NULL; - - /* send this event to the view */ - if (RTGUI_WIDGET(view)->event_handler != RT_NULL) - { - RTGUI_WIDGET(view)->event_handler(RTGUI_WIDGET(view), event); - } - } - } - } - break; - - case RTGUI_EVENT_CLIP_INFO: - { - struct rtgui_event_clip_info* eclip = (struct rtgui_event_clip_info*)event; - struct rtgui_widget* dest_widget = RTGUI_WIDGET(eclip->wid); - - if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL) - { - dest_widget->event_handler(dest_widget, event); - } - else - { - return rtgui_toplevel_event_handler(widget, event); - } - } - break; - - case RTGUI_EVENT_WIN_CLOSE: - case RTGUI_EVENT_WIN_ACTIVATE: - case RTGUI_EVENT_WIN_DEACTIVATE: - { - struct rtgui_event_win* wevent = (struct rtgui_event_win*)event; - struct rtgui_widget* dest_widget = RTGUI_WIDGET(wevent->wid); - if (dest_widget != RT_NULL && dest_widget->event_handler != RT_NULL) - { - dest_widget->event_handler(dest_widget, event); - } - } - break; - - case RTGUI_EVENT_WIN_MOVE: - { - struct rtgui_event_win_move* wevent = (struct rtgui_event_win_move*)event; - struct rtgui_toplevel* top = RTGUI_TOPLEVEL(wevent->wid); - if (top != RT_NULL && RTGUI_WIDGET(top)->event_handler != RT_NULL) - { - RTGUI_WIDGET(top)->event_handler(RTGUI_WIDGET(top), event); - } - } - break; - - default: - return rtgui_toplevel_event_handler(widget, event); - } - - return RT_TRUE; -} - -void rtgui_workbench_add_view(rtgui_workbench_t* workbench, rtgui_view_t* view) -{ - rtgui_container_add_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view)); - - /* reset view extent */ - rtgui_widget_set_rect(RTGUI_WIDGET(view), &(RTGUI_WIDGET(workbench)->extent)); -} - -void rtgui_workbench_remove_view(rtgui_workbench_t* workbench, rtgui_view_t* view) -{ - rtgui_container_remove_child(RTGUI_CONTAINER(workbench), RTGUI_WIDGET(view)); -} - -void rtgui_workbench_show_view(rtgui_workbench_t* workbench, rtgui_view_t* view) -{ - RT_ASSERT(workbench != RT_NULL); - RT_ASSERT(view != RT_NULL); - - if (rtgui_workbench_get_current_view(workbench) == view && - !RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(view))) return; - - /* remove from child list */ - rtgui_list_remove(&(RTGUI_CONTAINER(workbench)->children), &(RTGUI_WIDGET(view)->sibling)); - - /* insert to the head of child list */ - rtgui_list_insert(&(RTGUI_CONTAINER(workbench)->children), &(RTGUI_WIDGET(view)->sibling)); - - /* show view */ - RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(view)); - - /* update workbench clip */ - rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); - - if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(workbench))) - { - rtgui_widget_update(RTGUI_WIDGET(view)); - } -} - -void rtgui_workbench_hide_view(rtgui_workbench_t* workbench, rtgui_view_t* view) -{ - RT_ASSERT(workbench != RT_NULL); - RT_ASSERT(view != RT_NULL); - - /* remove from child list */ - rtgui_list_remove(&(RTGUI_CONTAINER(workbench)->children), &(RTGUI_WIDGET(view)->sibling)); - - /* append to the end of child list */ - rtgui_list_append(&(RTGUI_CONTAINER(workbench)->children), &(RTGUI_WIDGET(view)->sibling)); - - /* hide view */ - RTGUI_WIDGET_HIDE(RTGUI_WIDGET(view)); - - /* update workbench clip */ - rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); - - if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(workbench))) - { - view = rtgui_workbench_get_current_view(workbench); - rtgui_widget_update(RTGUI_WIDGET(view)); - } -} + rtgui_view_show(next_view); + } + else + { + /* update workbench clip */ + rtgui_toplevel_update_clip(RTGUI_TOPLEVEL(workbench)); + } + } +}