diff --git a/components/rtgui/common/font_bmp.c b/components/rtgui/common/font_bmp.c index 36192c6244d3bab5789b84cfec4820f0fbc3736a..1e6bbeba0159cacf16d7a62da2af89b5e6bed182 100644 --- a/components/rtgui/common/font_bmp.c +++ b/components/rtgui/common/font_bmp.c @@ -156,7 +156,7 @@ static void rtgui_bitmap_font_get_metrics(struct rtgui_font* font, const char* t if (bmp_font->char_width != NULL) { /* get width for each character */ - while (*text < 0x80) + while (*text && (*text < 0x80)) { rect->x2 += bmp_font->char_width[*text - bmp_font->first_char]; text ++; diff --git a/components/rtgui/common/font_freetype.c b/components/rtgui/common/font_freetype.c index 5e78b2666552f19f768853e937d02feeac8be689..dc231fc04b8e9301bd19343c857aa4f28489d8ff 100644 --- a/components/rtgui/common/font_freetype.c +++ b/components/rtgui/common/font_freetype.c @@ -2,8 +2,8 @@ #ifdef RTGUI_USING_TTF #include -#include -#include +#include +#include static void rtgui_freetype_font_draw_text(struct rtgui_font* font, struct rtgui_dc* dc, const char* text, rt_ubase_t len, struct rtgui_rect* rect); static void rtgui_freetype_font_get_metrics(struct rtgui_font* font, const char* text, rtgui_rect_t* rect); diff --git a/components/rtgui/common/image_jpg.c b/components/rtgui/common/image_jpg.c index 189db5349235374f74e90d22ef631be7362ed02d..914655923089136b6443abc36c5f161b296a9f3f 100644 --- a/components/rtgui/common/image_jpg.c +++ b/components/rtgui/common/image_jpg.c @@ -1,10 +1,11 @@ +#include +#include +#ifdef RTGUI_USING_JPEG #include #include #include "jpeg/jpeglib.h" -#include -#include #include #include #include @@ -476,3 +477,4 @@ static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file) return is_JPG; } +#endif diff --git a/components/rtgui/common/image_png.c b/components/rtgui/common/image_png.c index ff17bf275122a52b7d6dcffe715fe4133b421c2f..bb6e1b4bf8c57dfc3244d3566e6c5c905b70b30b 100644 --- a/components/rtgui/common/image_png.c +++ b/components/rtgui/common/image_png.c @@ -1,8 +1,10 @@ -#include "libpng/png.h" #include -#include #include +#ifdef RTGUI_USING_PNG +#include "libpng/png.h" +#include + #define PNG_MAGIC_LEN 8 struct rtgui_image_png @@ -328,3 +330,4 @@ void rtgui_image_png_init() /* register png on image system */ rtgui_image_register_engine(&rtgui_image_png_engine); } +#endif diff --git a/components/rtgui/common/rtgui_system.c b/components/rtgui/common/rtgui_system.c index 28071e6c28506abf51518bf7fc5154cd64e5ef9e..15843c51aa800de8c86e3f79b8768a76eca4a47a 100644 --- a/components/rtgui/common/rtgui_system.c +++ b/components/rtgui/common/rtgui_system.c @@ -403,7 +403,6 @@ rt_err_t rtgui_thread_send_urgent(rt_thread_t tid, rtgui_event_t* event, rt_size struct rtgui_thread* thread; rtgui_event_dump(tid, event); - rt_kprintf("event size: %d\n", event_size); /* find rtgui_thread */ thread = (struct rtgui_thread*) (tid->user_data); @@ -424,7 +423,6 @@ rt_err_t rtgui_thread_send_sync(rt_thread_t tid, rtgui_event_t* event, rt_size_t struct rt_mailbox ack_mb; rtgui_event_dump(tid, event); - rt_kprintf("event size: %d\n", event_size); /* init ack mailbox */ r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0); diff --git a/components/rtgui/include/rtgui/dc.h b/components/rtgui/include/rtgui/dc.h index f9276b676459d8a51a18dc489c5299df4b6184fc..866192cbb41015e462ef840689d4f877aed84ac1 100644 --- a/components/rtgui/include/rtgui/dc.h +++ b/components/rtgui/include/rtgui/dc.h @@ -68,7 +68,7 @@ struct rtgui_dc /* create a buffer dc */ struct rtgui_dc* rtgui_dc_buffer_create(int width, int height); -rt_uint8_t* rtgui_dc_buffer_get_pixel(struct rtgui_dc* dc); +rt_uint8_t* rtgui_dc_buffer_get_pixel(struct rtgui_dc* dc); /* begin and end a drawing */ struct rtgui_dc* rtgui_dc_begin_drawing(rtgui_widget_t* owner); diff --git a/components/rtgui/include/rtgui/rtgui_config.h b/components/rtgui/include/rtgui/rtgui_config.h index 1c69abec50baae942a0f849cb5a7f5488190efb0..225225a7a4fffef06dd6ba72d9a253c78919770a 100644 --- a/components/rtgui/include/rtgui/rtgui_config.h +++ b/components/rtgui/include/rtgui/rtgui_config.h @@ -26,7 +26,7 @@ /* support Chinese font */ #define RTGUI_USING_FONTHZ /* support FreeType TTF font */ - #define RTGUI_USING_TTF + // #define RTGUI_USING_TTF /* use small size in RTGUI */ #define RTGUI_USING_SMALL_SIZE /* use mouse cursor */ @@ -36,8 +36,8 @@ #define RTGUI_USING_STDIO_FILERW #define RTGUI_IMAGE_BMP - #define RTGUI_IMAGE_PNG - #define RTGUI_IMAGE_JPEG + // #define RTGUI_IMAGE_PNG + // #define RTGUI_IMAGE_JPEG #define RTGUI_USING_FONT12 #define RTGUI_USING_HZ_BMP #define RTGUI_MEM_TRACE diff --git a/components/rtgui/include/rtgui/widgets/combobox.h b/components/rtgui/include/rtgui/widgets/combobox.h new file mode 100644 index 0000000000000000000000000000000000000000..e5243588343d4d0009603ca27a3b43469cb37991 --- /dev/null +++ b/components/rtgui/include/rtgui/widgets/combobox.h @@ -0,0 +1,53 @@ +#ifndef __RTGUI_COMBOBOX_H__ +#define __RTGUI_COMBOBOX_H__ + +#include +#include +#include + +/* combobox item */ +struct rtgui_combobox_item +{ + char* name; + rtgui_image_t *image; +}; + +/** Gets the type of a combobox */ +#define RTGUI_COMBOBOX_TYPE (rtgui_combobox_type_get()) +/** Casts the object to a rtgui_combobox */ +#define RTGUI_COMBOBOX(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_COMBOBOX_TYPE, rtgui_combobox_t)) +/** Checks if the object is a rtgui_combobox */ +#define RTGUI_IS_COMBOBOX(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_COMBOBOX_TYPE)) + +#define RTGUI_COMBOBOX_WIDTH 75 +#define RTGUI_COMBOBOX_HEIGHT 20 +#define RTGUI_COMBOBOX_BUTTON_WIDTH 18 + +struct rtgui_combobox +{ + struct rtgui_widget parent; + + /* widget private data */ + + /* pull down window */ + struct rtgui_win* pd_win; + rt_bool_t pd_pressed; + + /* combobox items */ + struct rtgui_combobox_item* items; + rt_uint16_t items_count; + rt_uint16_t current_item; + + /* call back */ + rt_bool_t (*on_selected) (struct rtgui_widget* widget, struct rtgui_event* event); +}; +typedef struct rtgui_combobox rtgui_combobox_t; + +rtgui_type_t *rtgui_combobox_type_get(void); +rtgui_combobox_t *rtgui_combobox_create(); +void rtgui_combobox_destroy(rtgui_combobox_t* box); + +rt_bool_t rtgui_combobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event); +struct rtgui_item* rtgui_combox_get_select(struct rtgui_combobox* box); + +#endif diff --git a/components/rtgui/widgets/combobox.c b/components/rtgui/widgets/combobox.c new file mode 100644 index 0000000000000000000000000000000000000000..7d17429bb8e4d977d3a3dc56bddaa7d9f1d238c9 --- /dev/null +++ b/components/rtgui/widgets/combobox.c @@ -0,0 +1,237 @@ +#include +#include + +static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_widget* widget, struct rtgui_event* event); + +static void _rtgui_combobox_constructor(rtgui_combobox_t *box) +{ + rtgui_rect_t rect = {0, 0, RTGUI_COMBOBOX_WIDTH, RTGUI_COMBOBOX_HEIGHT}; + + /* init widget and set event handler */ + rtgui_widget_set_event_handler(RTGUI_WIDGET(box), rtgui_combobox_event_handler); + rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect); + + RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL; + + box->pd_pressed = RT_FALSE; + box->current_item = 0; + box->on_selected = RT_NULL; + + box->pd_win = rtgui_win_create(RT_NULL, "combo", &rect, RTGUI_WIN_STYLE_NO_TITLE); + box->pd_win->user_data = (rt_uint32_t)box; + rtgui_win_set_ondeactivate(RTGUI_WIN(box->pd_win), rtgui_combobox_pulldown_hide); +} + +static void _rtgui_combobox_destructor(rtgui_combobox_t *box) +{ + /* destroy pull down window */ + rtgui_win_destroy(box->pd_win); + + /* reset box field */ + box->pd_win = RT_NULL; +} + +rtgui_type_t *rtgui_combobox_type_get(void) +{ + static rtgui_type_t *combobox_type = RT_NULL; + + if (!combobox_type) + { + combobox_type = rtgui_type_create("combobox", RTGUI_WIDGET_TYPE, + sizeof(rtgui_combobox_t), + RTGUI_CONSTRUCTOR(_rtgui_combobox_constructor), + RTGUI_DESTRUCTOR(_rtgui_combobox_destructor)); + } + + return combobox_type; +} + +rtgui_combobox_t *rtgui_combobox_create() +{ + rtgui_combobox_t* box; + + box = (rtgui_combobox_t*)rtgui_widget_create(RTGUI_COMBOBOX_TYPE); + + return box; +} + +void rtgui_combobox_destroy(rtgui_combobox_t* box) +{ + rtgui_widget_destroy(RTGUI_WIDGET(box)); +} + +static void rtgui_combobox_ondraw(struct rtgui_combobox* box) +{ + /* draw button */ + struct rtgui_dc* dc; + struct rtgui_rect rect; + + /* begin drawing */ + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box)); + if (dc == RT_NULL) return; + + /* get widget rect */ + rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect); + /* fill widget rect with background color */ + rtgui_dc_fill_rect(dc, &rect); + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE); + + /* draw current item */ + if (box->current_item < box->items_count) + { + rect.x1 += 5; + rtgui_dc_draw_text(dc, box->items[box->current_item].name, &rect); + } + + /* draw pull down button */ + rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH; + rtgui_rect_inflate(&rect, -1); + if (box->pd_pressed == RT_TRUE) rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); + else rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_RAISE); + rtgui_dc_draw_arraw(dc, &rect, RTGUI_ARRAW_DOWN); + + /* end drawing */ + rtgui_dc_end_drawing(dc); + return; +} + +static rt_bool_t rtgui_combobox_onmouse_button(struct rtgui_combobox* box, struct rtgui_event_mouse* event) +{ + struct rtgui_rect rect; + + /* get widget rect */ + rect = RTGUI_WIDGET(box)->extent; + + /* move to the pull down button */ + rect.x1 = rect.x2 - RTGUI_COMBOBOX_BUTTON_WIDTH; + if (rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK) + { + /* handle mouse button on pull down button */ + if (event->button & RTGUI_MOUSE_BUTTON_LEFT && + event->button & RTGUI_MOUSE_BUTTON_DOWN) + { + box->pd_pressed = RT_TRUE; + rtgui_widget_update(RTGUI_WIDGET(box)); + } + else if (event->button & RTGUI_MOUSE_BUTTON_LEFT && + event->button & RTGUI_MOUSE_BUTTON_UP) + { + box->pd_pressed = RT_FALSE; + rtgui_widget_update(RTGUI_WIDGET(box)); + + /* pop pull down window */ + if (box->pd_win != RT_NULL) + { + struct rtgui_rect r; + rtgui_box_t* pd_win_box; + + r.x1 = RTGUI_WIDGET(box)->extent.x1; + r.y1 = RTGUI_WIDGET(box)->extent.y2 + 2; + r.x2 = RTGUI_WIDGET(box)->extent.x2; + r.y2 = r.y1 + box->pd_win_height; + + rtgui_win_set_rect(RTGUI_WIN(box->pd_win), &r); + pd_win_box = (rtgui_box_t*) rtgui_container_get_first_child(RTGUI_CONTAINER(box->pd_win)); + if (pd_win_box != RT_NULL) + { + RTGUI_WIDGET(pd_win_box)->extent = RTGUI_WIDGET(box->pd_win)->extent; + rtgui_box_layout(pd_win_box); + } + + /* show combo box pull down window */ + rtgui_win_show(RTGUI_WIN(box->pd_win), RT_FALSE); + } + } + + return RT_TRUE; + } + + return RT_FALSE; +} + +rt_bool_t rtgui_combobox_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) +{ + struct rtgui_combobox* box = (struct rtgui_combobox*)widget; + + switch (event->type) + { + case RTGUI_EVENT_PAINT: +#ifndef RTGUI_USING_SMALL_SIZE + if (widget->on_draw != RT_NULL) widget->on_draw(widget, event); + else +#endif + rtgui_combobox_ondraw(box); + + break; + + case RTGUI_EVENT_MOUSE_BUTTON: + return rtgui_combobox_onmouse_button(box, (struct rtgui_event_mouse*)event); + + case RTGUI_EVENT_FOCUSED: + { + /* item focused */ + struct rtgui_item* item; + struct rtgui_event_focused* focused; + + focused = (struct rtgui_event_focused*) event; + + item = (struct rtgui_item*) (focused->widget); + if (item != RT_NULL) + { + if (box->pd_select != RT_NULL) + { + /* un-select old item */ + rtgui_item_selected(box->pd_select, RT_FALSE); + } + + box->pd_select = item; + if (box->on_selected != RT_NULL) + { + box->on_selected(RTGUI_WIDGET(box), RT_NULL); + } + + /* hide pull down window */ + rtgui_win_hiden(RTGUI_WIN(box->pd_win)); + rtgui_combobox_ondraw(box); + } + } + break; + } + + return RT_FALSE; +} + +static rt_bool_t rtgui_combobox_pulldown_hide(struct rtgui_widget* widget, struct rtgui_event* event) +{ + struct rtgui_combobox* box; + + if (widget == RT_NULL) return RT_TRUE; + + box = (struct rtgui_combobox*) (((struct rtgui_win*)widget)->user_data); + if (box == RT_NULL) return RT_TRUE; + + /* clear select item */ + if (box->pd_select != RT_NULL) + { + rtgui_item_selected(box->pd_select, RT_FALSE); + } + + /* hide pull down window */ + rtgui_win_hiden(RTGUI_WIN(box->pd_win)); + + /* clear pull down button state */ + box->pd_pressed = RT_FALSE; + rtgui_widget_update(RTGUI_WIDGET(box)); + + return RT_TRUE; +} + +struct rtgui_item* rtgui_combox_get_select(struct rtgui_combobox* box) +{ + if ((box != RT_NULL) && (box->current_item < box->items_count)) + { + return &(box->items[box->current_item]); + } + + return RT_NULL; +}