From 0ce439673d649eae01fb972be053651296dffc96 Mon Sep 17 00:00:00 2001 From: "bernard.xiong" Date: Wed, 13 Jan 2010 23:41:15 +0000 Subject: [PATCH] add draw_round_rect, update radiobox widget implementation. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@298 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- rtgui/common/dc.c | 15 +++ rtgui/common/rtgui_system.c | 165 +++++++++++++++++++++++++ rtgui/common/rtgui_theme.c | 110 ++++++++++++++++- rtgui/include/rtgui/dc.h | 1 + rtgui/include/rtgui/rtgui_theme.h | 2 + rtgui/include/rtgui/widgets/radiobox.h | 18 ++- rtgui/widgets/radiobox.c | 104 +++++++--------- 7 files changed, 347 insertions(+), 68 deletions(-) diff --git a/rtgui/common/dc.c b/rtgui/common/dc.c index b8e06bf176..f31884cd06 100644 --- a/rtgui/common/dc.c +++ b/rtgui/common/dc.c @@ -138,6 +138,21 @@ void rtgui_dc_draw_rect (struct rtgui_dc* dc, struct rtgui_rect* rect) rtgui_dc_draw_vline(dc, rect->x2 - 1, rect->y1, rect->y2); } +void rtgui_dc_draw_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect) +{ + int r = 3; + + rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y1 + r, r, 180, 270); + rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y1 + r, r, 270, 360); + rtgui_dc_draw_arc(dc, rect->x1 + r, rect->y2 - r, r, 90, 180); + rtgui_dc_draw_arc(dc, rect->x2 - r, rect->y2 - r, r, 0, 90); + + rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y1); + rtgui_dc_draw_hline(dc, rect->x1 + r, rect->x2 - r, rect->y2); + rtgui_dc_draw_vline(dc, rect->x1, rect->y1 + r, rect->y2 - r); + rtgui_dc_draw_vline(dc, rect->x2, rect->y1 + r, rect->y2 - r); +} + void rtgui_dc_fill_rect (struct rtgui_dc* dc, struct rtgui_rect* rect) { if (dc == RT_NULL) return; diff --git a/rtgui/common/rtgui_system.c b/rtgui/common/rtgui_system.c index 824d298abc..e07ba74e9c 100644 --- a/rtgui/common/rtgui_system.c +++ b/rtgui/common/rtgui_system.c @@ -658,3 +658,168 @@ void rtgui_free(void* ptr) rt_free(ptr); } + +#if 0 +/* + * read/write lock implementation + */ +struct rtgui_rwlock* rtgui_rwlock_create() +{ + struct rtgui_rwlock* rwlock; + + rwlock = rtgui_malloc(sizeof(struct rtgui_rwlock)); + if (rwlock != RT_NULL) + { + rwlock->stat = RTGUI_RWLOCK_UNLOCK; + rwlock->reader_count = 0; + + rt_sem_init(&(rwlock->rd_lock), "rwr", 0, RT_IPC_FLAG_FIFO); + rt_sem_init(&(rwlock->wr_lock), "rww", 0, RT_IPC_FLAG_FIFO); + } + + return rwlock; +} + +rt_err_t rtgui_rwlock_delete(struct rtgui_rwlock* rwlock) +{ + RT_ASSERT(rwlock != RT_NULL); + + rt_sem_detach(&(rwlock->rd_lock)); + rt_sem_detach(&(rwlock->wr_lock)); + + rtgui_free(rwlock); + + return RT_EOK; +} + +rt_err_t rtgui_rwlock_read_take(struct rtgui_rwlock* rwlock, rt_int32_t timeout) +{ + rt_err_t result; + rt_ubase_t level; + + RT_ASSERT(rwlock != RT_NULL); + level = rt_hw_interrupt_disable(); + switch (rwlock->stat) + { + case RTGUI_RWLOCK_UNLOCK: + break; + + case RTGUI_RWLOCK_READING: + if (rwlock->wr_lock.parent.suspend_thread_count > 0) + { + /* suspend read thread */ + result = rt_sem_take(&rwlock->rd_lock, timeout); + if (result != RT_EOK) + { + rt_hw_interrupt_enable(level); + return result; + } + } + break; + + case RTGUI_RWLOCK_WRITTING: + /* suspend read thread */ + result = rt_sem_take(&(rwlock->rd_lock), timeout); + if (result != RT_EOK) + { + rt_hw_interrupt_enable(level); + return result; + } + break; + } + + /* get rwlock */ + rwlock->reader_count ++; + rwlock->stat = RTGUI_RWLOCK_READING; + + rt_hw_interrupt_enable(level); +} + +rt_err_t rtgui_rwlock_write_take(struct rtgui_rwlock* rwlock, rt_int32_t timeout) +{ + rt_err_t result; + rt_ubase_t level; + + RT_ASSERT(rwlock != RT_NULL); + + level = rt_hw_interrupt_disable(); + rwlock->stat = RTGUI_RWLOCK_WRITTING; + result = rt_sem_take(&(rwlock->wr_lock), timeout); + + if (result != RT_EOK) + { + if (rwlock->wr_lock.parent.suspend_thread_count == 0) + { + if (rwlock->reader_count > 0) + rwlock->stat = RTGUI_RWLOCK_READING; + } + } + rt_hw_interrupt_enable(level); + + return result; +} + +rt_err_t rtgui_rwlock_read_release(struct rtgui_rwlock* rwlock) +{ + rt_ubase_t level; + + RT_ASSERT(rwlock != RT_NULL); + + level = rt_hw_interrupt_disable(); + switch (rwlock->stat) + { + case RTGUI_RWLOCK_UNLOCK: + ASSERT(0); + break; + + case RTGUI_RWLOCK_READING: + rwlock->reader_count --; + if (rwlock->reader_count == 0) + rwlock->stat = RTGUI_RWLOCK_UNLOCK; + break; + + case RTGUI_RWLOCK_WRITTING: + rwlock->reader_count --; + + if (rwlock->reader_count == 0) + { + /* resume write */ + rt_sem_release(&(rwlock->wr_lock)); + } + break; + } + rt_hw_interrupt_enable(level); +} + +rt_err_t rtgui_rwlock_write_release(struct rtgui_rwlock* rwlock) +{ + rt_err_t result; + rt_ubase_t level; + + RT_ASSERT(rwlock != RT_NULL); + + level = rt_hw_interrupt_disable(); + result = rt_sem_release(&(rwlock->wr_lock)); + + if ((result == RT_EOK) && (rwlock->wr_lock.parent.suspend_thread_count == 0)) + { + rt_uint32_t index, reader_thread_count; + + reader_thread_count = rwlock->rd_lock.parent.suspend_thread_count; + if (reader_thread_count > 0) + { + rwlock->stat = RTGUI_RWLOCK_READING; + + /* resume all reader thread */ + for (index = 0; index < reader_thread_count; index ++) + { + rt_sem_release(&(rwlock->rd_lock)); + } + } + else rwlock->stat = RTGUI_RWLOCK_UNLOCK; + } + rt_hw_interrupt_enable(level); + + return result; +} +#endif diff --git a/rtgui/common/rtgui_theme.c b/rtgui/common/rtgui_theme.c index 13588f2a1f..07575f0bb7 100644 --- a/rtgui/common/rtgui_theme.c +++ b/rtgui/common/rtgui_theme.c @@ -470,7 +470,7 @@ void rtgui_theme_draw_iconbox(rtgui_iconbox_t* iconbox) rtgui_dc_end_drawing(dc); } -void rtgui_theme_draw_checkbox(rtgui_checkbox_t* checkbox) +void rtgui_theme_draw_checkbox(struct rtgui_checkbox* checkbox) { struct rtgui_dc* dc; struct rtgui_rect rect, box_rect; @@ -528,6 +528,114 @@ void rtgui_theme_draw_checkbox(rtgui_checkbox_t* checkbox) return; } +void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox) +{ + struct rtgui_dc* dc; + struct rtgui_rect rect, item_rect; + rt_size_t item_size, bord_size, index; + + /* begin drawing */ + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(radiobox)); + if (dc == RT_NULL) return; + + /* get widget rect */ + rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect); + rtgui_dc_fill_rect(dc, &rect); + + item_size = radiobox->item_size; + /* get board size */ + if (radiobox->orient == RTGUI_VERTICAL) + bord_size = item_size; + else + { + rtgui_font_get_metrics(rtgui_dc_get_font(dc), "H", &item_rect); + bord_size = rtgui_rect_height(item_rect); + } + + /* draw box */ + rtgui_rect_inflate(&rect, -bord_size/2); + rtgui_dc_draw_round_rect(dc, &rect); + rtgui_rect_inflate(&rect, bord_size/2); + if (radiobox->text != RT_NULL) + { + struct rtgui_rect text_rect; + + /* draw group text */ + rtgui_font_get_metrics(rtgui_dc_get_font(dc), radiobox->text, &text_rect); + rtgui_rect_moveto(&text_rect, rect.x1 + 5, rect.y1); + rtgui_dc_fill_rect(dc, &text_rect); + rtgui_dc_draw_text(dc, radiobox->text, &text_rect); + } + + /* set init item rect */ + item_rect = rect; + rtgui_rect_inflate(&item_rect, - bord_size); + + if (radiobox->orient == RTGUI_VERTICAL) + { + /* set the first text rect */ + item_rect.y2 = item_rect.y1 + item_size; + + /* draw each radio button */ + for (index = 0; index < radiobox->item_count; index ++) + { + if (item_rect.y2 > rect.y2 - item_size) break; + + /* draw radio */ + if (radiobox->item_selection == index) + { + rtgui_dc_draw_focus_rect(dc, &item_rect); + rtgui_dc_fill_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2); + } + else + { + rtgui_dc_draw_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2); + } + + /* draw text */ + item_rect.x1 += item_size + 3; + rtgui_dc_draw_text(dc, radiobox->items[index], item_rect); + item_rect.x1 -= item_size + 3; + + item_rect.y1 += item_size; + item_rect.y2 += item_size; + } + } + else + { + /* set the first text rect */ + item_rect.x2 = item_rect.x1 + item_size; + + /* draw each radio button */ + for (index = 0; index < radiobox->item_count; index ++) + { + if (item_rect.x2 > rect.x2 - item_size) break; + + /* draw radio */ + if (radiobox->item_selection == index) + { + rtgui_dc_draw_focus_rect(dc, &item_rect); + rtgui_dc_fill_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2); + } + else + { + rtgui_dc_draw_circle(dc, item_rect.x1 + item_size/2 + 2, item_rect.y1 + item_size/2 + 2, item_size/2 - 2); + } + + /* draw text */ + item_rect.x1 += item_size + 3; + rtgui_dc_draw_text(dc, radiobox->items[index], item_rect); + item_rect.x1 -= item_size + 3; + + item_rect.x1 += item_size; + item_rect.x2 += item_size; + } + } + + /* end drawing */ + rtgui_dc_end_drawing(dc); +} + void rtgui_theme_draw_slider(struct rtgui_slider* slider) { /* draw button */ diff --git a/rtgui/include/rtgui/dc.h b/rtgui/include/rtgui/dc.h index 1bf7bc1ee3..33c45d3838 100644 --- a/rtgui/include/rtgui/dc.h +++ b/rtgui/include/rtgui/dc.h @@ -104,6 +104,7 @@ void rtgui_dc_get_rect(struct rtgui_dc*dc, rtgui_rect_t* rect); void rtgui_dc_draw_line (struct rtgui_dc* dc, int x1, int y1, int x2, int y2); void rtgui_dc_draw_rect (struct rtgui_dc* dc, struct rtgui_rect* rect); +void rtgui_dc_draw_round_rect(struct rtgui_dc* dc, struct rtgui_rect* rect); void rtgui_dc_draw_text (struct rtgui_dc* dc, const rt_uint8_t* text, struct rtgui_rect* rect); diff --git a/rtgui/include/rtgui/rtgui_theme.h b/rtgui/include/rtgui/rtgui_theme.h index 9f0ddba0e8..979e1cb254 100644 --- a/rtgui/include/rtgui/rtgui_theme.h +++ b/rtgui/include/rtgui/rtgui_theme.h @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -38,6 +39,7 @@ void rtgui_theme_draw_label(rtgui_label_t* label); void rtgui_theme_draw_textbox(rtgui_textbox_t* box); void rtgui_theme_draw_iconbox(rtgui_iconbox_t* iconbox); void rtgui_theme_draw_checkbox(rtgui_checkbox_t* checkbox); +void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox); void rtgui_theme_draw_slider(struct rtgui_slider* slider); void rtgui_theme_draw_progressbar(struct rtgui_progressbar* bar); void rtgui_theme_draw_staticline(struct rtgui_staticline* staticline); diff --git a/rtgui/include/rtgui/widgets/radiobox.h b/rtgui/include/rtgui/widgets/radiobox.h index dfd563ff9e..efab51698c 100644 --- a/rtgui/include/rtgui/widgets/radiobox.h +++ b/rtgui/include/rtgui/widgets/radiobox.h @@ -7,19 +7,25 @@ /** Gets the type of a radiobox */ #define RTGUI_RADIOBOX_TYPE (rtgui_radiobox_type_get()) /** Casts the object to an rtgui_radiobox */ -#define RTGUI_SLIDER(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_RADIOBOX_TYPE, rtgui_radiobox_t)) +#define RTGUI_RADIOBOX(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_RADIOBOX_TYPE, rtgui_radiobox_t)) /** Checks if the object is an rtgui_radiobox */ -#define RTGUI_IS_SLIDER(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_RADIOBOX_TYPE)) +#define RTGUI_IS_RADIOBOX(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_RADIOBOX_TYPE)) struct rtgui_radiobox { struct rtgui_widget parent; /* widget private data */ - int orient; + char* text; /* radio box label */ - char* items; - int item_count, item_selection; + /* box orient */ + rt_uint8_t orient; + + /* item size */ + rt_uint8_t item_size; + + char** items; + rt_uint16_t item_count, item_selection; }; typedef struct rtgui_radiobox rtgui_radiobox_t; @@ -33,4 +39,6 @@ int rtgui_radiobox_get_selection(struct rtgui_radiobox* radiobox); rt_bool_t rtgui_radiobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event); +void rtgui_radiobox_set_orientation(struct rtgui_radiobox* radiobox, int orientation); + #endif diff --git a/rtgui/widgets/radiobox.c b/rtgui/widgets/radiobox.c index 3059b63ff5..c02843eab9 100644 --- a/rtgui/widgets/radiobox.c +++ b/rtgui/widgets/radiobox.c @@ -42,6 +42,24 @@ static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui if (event->button & RTGUI_MOUSE_BUTTON_DOWN && event->button & RTGUI_MOUSE_BUTTON_LEFT) { + int bord_size; + struct rtgui_rect rect; + + /* get widget rect */ + rtgui_widget_get_rect(RTGUI_WIDGET(radiobox), &rect); + + /* get board size */ + if (radiobox->orient == RTGUI_VERTICAL) + bord_size = radiobox->item_size; + else + { + struct rtgui_rect bord_rect; + + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &bord_rect); + bord_size = rtgui_rect_height(bord_rect); + } + rtgui_rect_inflate(&rect, - bord_size); + if (radiobox->orient == RTGUI_VERTICAL) { } @@ -53,68 +71,6 @@ static void rtgui_radiobox_onmouse(struct rtgui_radiobox* radiobox, struct rtgui } } -void rtgui_theme_draw_radiobox(struct rtgui_radiobox* radiobox) -{ - struct rtgui_dc* dc; - struct rtgui_rect rect, item_rect, radio_rect; - rt_size_t item_height; - - /* begin drawing */ - dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(label)); - if (dc == RT_NULL) return; - - rtgui_widget_get_rect(RTGUI_WIDGET(label), &rect); - rtgui_dc_fill_rect(dc, &rect); - - rtgui_dc_get_text_metrix(dc, "H", &item_rect); - item_height = rtgui_rect_height(item_rect); - radio_rect.x1 = 0; radio_rect.y1 = 0; - radio_rect.x2 = radio_rect.x1 + item_height; - radio_rect.y2 = radio_rect.y1 + item_height; - - /* draw box */ - rtgui_rect_inflat(&rect, -3); - rtgui_dc_draw_round_rect(dc, &rect); - if (radiobox->text != RT_NULL) - { - /* draw group text */ - rtgui_dc_get_text_metrix(dc, radiobox->text, &item_rect); - rtgui_rect_moveto(&item_rect, rect.x1 + 5, rect.y1); - rtgui_dc_fill_rect(dc, &item_rect); - - rtgui_dc_draw_text(dc, radiobox->text, &item_rect); - } - - /* set the first text rect */ - item_rect = rect; - item_rect.x1 += 5; - item_rect.y1 += item_height; - item_rect.y2 = item_rect.y1 + item_height; - - /* draw each radio button */ - for (index = 0; index < radiobox->item_count; index ++) - { - if (text_rect.y2 > rect.y2 - item_height) break; - - /* draw radio */ - rtgui_dc_draw_circyle(dc, ); - if (radiobox->item_selection == index) - { - rtgui_dc_draw_focus_rect(dc, ); - rtgui_dc_fill_circyle(dc, ); - } - - /* draw text */ - rtgui_dc_draw_text(dc, radiobox->items[index], text_rect); - - text_rect.y1 += item_height; - text_rect.y2 += item_height; - } - - /* end drawing */ - rtgui_dc_end_drawing(dc); -} - rt_bool_t rtgui_radiobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) { struct rtgui_radiobox* radiobox = (struct rtgui_radiobox*)widget; @@ -184,6 +140,30 @@ struct rtgui_radiobox* rtgui_radiobox_create(int orient, char** radio_items, int /* set proper of control */ rtgui_radiobox_set_orientation(radiobox, orient); + if (orient == RTGUI_VERTICAL) + { + struct rtgui_rect rect; + rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)), "H", &rect); + + radiobox->item_size = rtgui_rect_height(rect); + } + else + { + int index; + struct rtgui_font* font; + struct rtgui_rect rect; + + /* set init item size */ + radiobox->item_size = 0; + + font = RTGUI_WIDGET_FONT(RTGUI_WIDGET(radiobox)); + for (index = 0; index < number; index ++) + { + rtgui_font_get_metrics(font, radio_items[index], &rect); + if (rtgui_rect_width(rect) > radiobox->item_size) + radiobox->item_size = rtgui_rect_width(rect); + } + } } return radiobox; -- GitLab