diff options
Diffstat (limited to 'components/rtgui_win/widgets/textbox.c')
| -rw-r--r-- | components/rtgui_win/widgets/textbox.c | 547 |
1 files changed, 547 insertions, 0 deletions
diff --git a/components/rtgui_win/widgets/textbox.c b/components/rtgui_win/widgets/textbox.c new file mode 100644 index 0000000000..f3f77e908a --- /dev/null +++ b/components/rtgui_win/widgets/textbox.c @@ -0,0 +1,547 @@ +/* + * File : textbox.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-10-16 Bernard first version + */
+#include <rtgui/rtgui.h> +#include <rtgui/dc.h> +#include <rtgui/rtgui_theme.h> +#include <rtgui/rtgui_system.h> +#include <rtgui/widgets/textbox.h>
+#include <rtgui/widgets/widget.h>
+ +#include <ctype.h>
+ +static void rtgui_textbox_timeout(rtgui_timer_t* timer, void* parameter);
+static rt_bool_t rtgui_textbox_onkey(PVOID wdt, rtgui_event_t* event); +static rt_bool_t rtgui_textbox_onfocus(PVOID wdt, rtgui_event_t* event); +static rt_bool_t rtgui_textbox_onunfocus(PVOID wdt, rtgui_event_t* event);
+
+ +void _rtgui_textbox_constructor(rtgui_textbox_t *box) +{ + rtgui_rect_t rect; + + RTGUI_WIDGET_FLAG(box) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ + rtgui_widget_set_event_handler(box, rtgui_textbox_event_handler); + rtgui_widget_set_onfocus(box, rtgui_textbox_onfocus); + rtgui_widget_set_onunfocus(box, rtgui_textbox_onunfocus);
+ rtgui_widget_set_onkey(box,rtgui_textbox_onkey);
+ + RTGUI_WIDGET_BACKGROUND(box) = white;
+ /* set default text align */ + RTGUI_WIDGET_TEXTALIGN(box) = RTGUI_ALIGN_CENTER_VERTICAL; + rtgui_widget_set_style(box, RTGUI_BORDER_SUNKEN); + /* set proper of control ����һ�������͵Ŀ��ƶ�ʱ��*/ + box->caret_timer = rtgui_timer_create(100, RT_TIMER_FLAG_PERIODIC,rtgui_textbox_timeout, box);
+ + //��ʼ��...��ǰ��,��ʼ��,�ڵ�ǰ���е�λ�� + box->line = box->line_begin = box->position = 0;
+ box->flag = RTGUI_TEXTBOX_NONE; //����(Ĭ��) + box->isedit = RT_TRUE;//Ĭ���ǿ��Ա༭�� + /* allocate default line buffer ����Ĭ�ϵ��л��� */ + box->text = RT_NULL; + + rtgui_font_get_string_rect(RTGUI_WIDGET_FONT(box), "h", &rect); + box->font_width = rtgui_rect_width(rect);
+ box->on_change = RT_NULL;
+ box->on_enter = RT_NULL; +} + +void _rtgui_textbox_deconstructor(rtgui_textbox_t *textbox) +{ + if(textbox->text != RT_NULL) + { + rt_free(textbox->text); + textbox->text = RT_NULL; + } + if(textbox->caret_timer != RT_NULL) + rtgui_timer_destory(textbox->caret_timer); + textbox->caret_timer = RT_NULL;
+ +} + +rtgui_type_t *rtgui_textbox_type_get(void) +{ + static rtgui_type_t *textbox_type = RT_NULL; + + if(!textbox_type) + { + textbox_type = rtgui_type_create("textbox", RTGUI_WIDGET_TYPE, + sizeof(rtgui_textbox_t), + RTGUI_CONSTRUCTOR(_rtgui_textbox_constructor), + RTGUI_DESTRUCTOR(_rtgui_textbox_deconstructor)); + } + + return textbox_type; +}
+
+//#include <rthw.h>
+//���Ʊ༭����
+void rtgui_textbox_draw_caret(rtgui_textbox_t* box, rt_uint16_t position)
+{
+ int x,y;
+// rtgui_color_t color;
+ rtgui_rect_t rect;
+ int font_h,box_h;
+ rtgui_dc_t *dc;
+
+ RT_ASSERT(box != RT_NULL);
+
+ dc = rtgui_dc_begin_drawing(box);
+ if(dc == RT_NULL)return;
+ + rtgui_widget_get_rect(box, &rect);
+
+ font_h = rtgui_font_get_font_height(RTGUI_WIDGET_FONT(box));
+ box_h = rtgui_rect_height(rect);
+
+ rect.x1 += position * box->font_width+2; + rect.x2 = rect.x1+2; + rect.y1 += (box_h-font_h)/2;
+ rect.y2 = rect.y1 + font_h;
+
+ for(x=rect.x1;x<rect.x2;x++)
+ {
+ for(y=rect.y1;y<rect.y2;y++)
+ {
+// rt_hw_lcd_get_pixel(color,x,y);
+// color ^= white;
+// rtgui_dc_draw_point(box, color,x,y);
+
+ if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
+ {
+ RTGUI_DC_FC(dc) = black;
+ rtgui_dc_draw_point(dc, x,y);
+ }
+ else
+ {
+ RTGUI_DC_FC(dc) = white;
+ rtgui_dc_draw_point(dc, x,y);
+ }
+ }
+ }
+
+ rtgui_dc_end_drawing(dc);
+}
+ +static void rtgui_textbox_timeout(rtgui_timer_t* timer, void* parameter) +{ + rtgui_textbox_t* box; + + box = (rtgui_textbox_t*)parameter; + /* set caret flag */ + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW) + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW; + else + box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
+ + rtgui_textbox_draw_caret(box,box->position);
+ + return ; +}
+ +static void rtgui_textbox_onmouse(rtgui_textbox_t* box, rtgui_event_mouse_t* event) +{ + rt_size_t length;
+ rt_uint16_t posbak = box->position; + + RT_ASSERT(box != RT_NULL); + RT_ASSERT(event != RT_NULL);
+
+ if(box->isedit == RT_FALSE)return;
+ + length = rt_strlen(box->text); + + if(event->button & RTGUI_MOUSE_BUTTON_LEFT && event->button & RTGUI_MOUSE_BUTTON_DOWN) + { + rt_int32_t x;
+ if(!box->isedit)return; + if(box->flag & RTGUI_TEXTBOX_MULTI)
+ {//�����ı�
+ /* set widget focus */ + rtgui_widget_focus(box);
+
+ //add codes at here.
+ //...
+
+ box->position = 0;
+ box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box,box->position);
+ }
+ else
+ {//�����ı� + /* set caret position */ + x = event->x - RTGUI_WIDGET(box)->extent.x1; + if(x < 0) + { + box->position = 0; + } + else if(x > length * box->font_width) + { + box->position = length; + } + else + { + box->position = x / box->font_width; + }
+
+ //�ı���λ��,�����һ��λ����ʾ�˱༭����,�����֮. + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
+ {
+ rtgui_timer_stop(box->caret_timer);
+
+ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box, posbak);//��ˢ�����±༭����,�������ʾ״̬
+
+ rtgui_timer_start(box->caret_timer);
+ }
+
+ /* set widget focus */ + rtgui_widget_focus(box); + + /* draw caret ���Ʊ༭���� */ + rtgui_textbox_draw_caret(box,box->position);
+ } + } +}
+ +static rt_bool_t rtgui_textbox_onkey(PVOID wdt, rtgui_event_t* event) +{ + rtgui_textbox_t* box = (rtgui_textbox_t*)wdt;
+ rtgui_event_kbd_t* ekbd = (rtgui_event_kbd_t*)event;
+ rt_size_t length;
+ rt_uint16_t posbak = box->position; + + RT_ASSERT(box != RT_NULL); + RT_ASSERT(ekbd != RT_NULL); + + length = rt_strlen(box->text); + if(ekbd->key == RTGUIK_DELETE) + {//ɾ����������ַ� + if(box->position == length - 1) + { + box->text[box->position] = '\0'; + } + else + { + char *c; + + /* remove character */ + for(c = &box->text[box->position]; c[1] != '\0'; c++) + *c = c[1]; + *c = '\0'; + }
+
+ if(box->on_change)box->on_change(box,RT_NULL); + } + else if(ekbd->key == RTGUIK_BACKSPACE) + {//ɾ�����ǰ����ַ�
+ + if(box->position == length - 1) + { + box->text[box->position] = '\0'; + box->position --; + } + else if(box->position != 0) + { + /* remove current character */ + if(box->position != 0) + { + char *c; + + /* remove character */ + for(c = &box->text[box->position - 1]; c[1] != '\0'; c++) + *c = c[1]; + *c = '\0'; + }
+ box->position --; + }
+
+ if(box->on_change)box->on_change(box,RT_NULL); + } + else if(ekbd->key == RTGUIK_LEFT) + {//��������ƶ�һ���ַ�λ + if(box->position > 0)
+ {
+ box->position --;
+ } + } + else if(ekbd->key == RTGUIK_RIGHT) + {//��������ƶ�һ���ַ�λ + if(box->position < length)
+ {
+ box->position ++;
+ } + } + else if(ekbd->key == RTGUIK_HOME) + {//����ƶ������� + box->position = 0; + } + else if(ekbd->key == RTGUIK_END) + {//����ƶ�����β
+ box->position = length; + } + else if(ekbd->key == RTGUIK_RETURN) + { + if(box->on_enter != RT_NULL) + { + box->on_enter(box, RT_NULL); + } + }
+ else if(ekbd->key == RTGUIK_NUMLOCK)//���ּ���Ч
+ {
+ /* change numlock state */
+ } + else + { + if(isprint(ekbd->key)) + {//�ǿɴ�ӡ�ַ������� + /* no buffer on this line */
+ if(box->flag & RTGUI_TEXTBOX_DIGIT)
+ {//������������
+ if(!isdigit(ekbd->key))
+ {//����'.'��'-'
+ if(ekbd->key != '.' && ekbd->key !='-')return RT_FALSE;
+ if(ekbd->key == '.' && strchr(box->text,'.'))return RT_FALSE;
+
+ if(ekbd->key == '-')
+ {//������ģʽ��,������������
+ if(length+1 > box->line_length) return RT_FALSE; + if(length+1 > box->dis_length) return RT_FALSE;
+
+ if(strchr(box->text,'-'))
+ {//��ǰ�Ѿ���Ϊ����
+ char* c; + for(c = &box->text[0]; c != &box->text[length]; c++) + *c = *(c+1); + box->text[length] = '\0';
+ box->position --;
+ goto _exit;
+ }
+ else
+ {
+ char* c; + for(c = &box->text[length]; c != &box->text[0]; c--) + *c = *(c-1);
+ box->text[0] = '-'; + box->text[length+1] = '\0';
+ box->position ++;
+ goto _exit;
+ }
+ }
+ }
+ //rt_kprintf("%c ",ekbd->key);//debug printf
+ } + if(length+1 > box->line_length) return RT_FALSE; + if(length+1 > box->dis_length) return RT_FALSE;
+ + if(box->position <= length-1) + { + char* c; + + for(c = &box->text[length]; c != &box->text[box->position]; c--) + *c = *(c-1); + box->text[length+1] = '\0'; + }
+ + box->text[box->position] = ekbd->key;
+ box->position ++;
+
+ if(box->on_change)box->on_change(box,RT_NULL); + } + }
+
+_exit: + //�ı���λ��,�����һ��λ����ʾ�˱༭����,�����֮. + if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
+ {
+ rtgui_timer_stop(box->caret_timer);
+
+ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box, posbak);//��ˢ��һ�±༭����,�������ʾ״̬
+
+ rtgui_timer_start(box->caret_timer);
+ }
+ /* set widget focus */ + rtgui_widget_focus(box); + /* set caret to show */ + box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
+ /* re-draw text box */ + rtgui_theme_draw_textbox(box); + /* draw caret ���Ʊ༭���� */ + rtgui_textbox_draw_caret(box,box->position);
+ + return RT_TRUE; +} + +static rt_bool_t rtgui_textbox_onfocus(PVOID wdt, rtgui_event_t* event) +{ + rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_textbox_t* box = (rtgui_textbox_t*)widget; + + /* set caret to show */ + box->flag |= RTGUI_TEXTBOX_CARET_SHOW;//�༭���� + /* start caret timer */ + rtgui_timer_start(box->caret_timer); + + return RT_TRUE; +} + +static rt_bool_t rtgui_textbox_onunfocus(PVOID wdt, rtgui_event_t* event) +{ + rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_textbox_t* box = (rtgui_textbox_t*)widget; + + /* stop caret timer */ + rtgui_timer_stop(box->caret_timer);
+ + /* set caret to hide */ + box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
+ rtgui_textbox_draw_caret(box,box->position);
+
+ if(box->on_enter)box->on_enter(box,event);
+
+ rtgui_theme_draw_textbox(box);
+ + return RT_TRUE; +} + +rt_bool_t rtgui_textbox_event_handler(PVOID wdt, rtgui_event_t* event) +{ + rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_textbox_t* box = (rtgui_textbox_t*)widget; + + switch (event->type) + { + case RTGUI_EVENT_PAINT: + if(widget->on_draw != RT_NULL) widget->on_draw(widget, event); + else + rtgui_theme_draw_textbox(box); + break; + + case RTGUI_EVENT_MOUSE_BUTTON: + if(widget->on_mouseclick != RT_NULL) widget->on_mouseclick(widget, event); + else + rtgui_textbox_onmouse(box, (rtgui_event_mouse_t*)event); + return RT_TRUE; + + case RTGUI_EVENT_KBD: + if(widget->on_key != RT_NULL)
+ widget->on_key(widget, event); + + return RT_TRUE;
+ default:
+ return rtgui_widget_event_handler(widget,event);
+ + } + + return RT_FALSE; +} + +rtgui_textbox_t* rtgui_textbox_create(PVOID parent,const char* text,int left,int top,int w,int h, rt_uint32_t flag) +{ + rtgui_textbox_t* box;
+ + RT_ASSERT(parent != RT_NULL);
+ + box = rtgui_widget_create(RTGUI_TEXTBOX_TYPE); + if(box != RT_NULL) + { + rtgui_rect_t rect;
+ rtgui_widget_get_rect(parent, &rect);
+ rtgui_widget_rect_to_device(parent,&rect);
+ rect.x1 += left;
+ rect.y1 += top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+ rtgui_widget_set_rect(box,&rect);
+
+ /* allocate default line buffer */ + rtgui_textbox_set_value(box, text);
+ + box->flag = flag;
+ //�趨����ʾ�ַ�����
+ box->dis_length = (w-5)/rtgui_font_get_font_width(RTGUI_WIDGET_FONT(box));
+
+ rtgui_container_add_child(parent, box); + } + + return box; +} + +void rtgui_textbox_destroy(rtgui_textbox_t* box) +{ + rtgui_widget_destroy(box); +}
+ +//��һ���ı���������һ��textbox�ؼ�
+void rtgui_textbox_set_value(rtgui_textbox_t* box, const char* text) +{ + if(box->text != RT_NULL) + {//�Ѿ������� + /* free the old text */ + rt_free(box->text); + box->text = RT_NULL; + }
+ + //ԭ��û������ + box->line_length = ((rt_strlen(text)+1)/RTGUI_TEXTBOX_LINE_MAX+1)*RTGUI_TEXTBOX_LINE_MAX; + + /* allocate line buffer */ + box->text = rt_malloc(box->line_length); + rt_memset(box->text, 0, box->line_length); + + /* copy text */ + rt_memcpy(box->text, text, rt_strlen(text) + 1); + + /* set current position */ + box->position = rt_strlen(text); +} + +const char* rtgui_textbox_get_value(rtgui_textbox_t* box) +{ + return (const char*)box->text; +} + +void rtgui_textbox_set_line_length(rtgui_textbox_t* box, rt_size_t length) +{ + rt_uint8_t* new_line; + + RT_ASSERT(box != RT_NULL); + + /* invalid length */ + if(length <= 0) return; + + new_line = rt_malloc(length); + if(length < box->line_length) + { + rt_memcpy(new_line, box->text, length - 1); + new_line[length] = '\0'; + } + else + { + rt_memcpy(new_line, (const char*)box->text, rt_strlen((const char*)box->text)); + } + + /* set line length */ + box->line_length = length; +}
+ +//ȡ��textbox�ؼ����ı���ʾ����
+void rtgui_textbox_get_edit_rect(rtgui_textbox_t *box,rtgui_rect_t *rect)
+{
+ rtgui_widget_get_rect(box, rect);
+ rtgui_rect_inflate(rect,-1);
+}
+
+ |
