Пример #1
0
static rt_bool_t mainmenu_event_handler(struct rtgui_object *object,
                                        rtgui_event_t *event)
{
    switch (event->type)
    {
    case RTGUI_EVENT_PAINT:
        on_draw(RTGUI_WIDGET(object));
        break;
    case RTGUI_EVENT_KBD:
        {
            struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *)event;
            if ((ekbd->key == RTGUIK_RIGHT) && RTGUI_KBD_IS_UP(ekbd))
            {
                next_page(RTGUI_WIDGET(object));
            }
            else if ((ekbd->key == RTGUIK_LEFT) && RTGUI_KBD_IS_UP(ekbd))
            {
                priv_page(RTGUI_WIDGET(object));
            }
            else
            {
                return rtgui_win_event_handler(object, event);
            }
        }
        break;
    case RTGUI_EVENT_MOUSE_BUTTON:
        {
            struct rtgui_event_mouse *emouse;

            emouse = (struct rtgui_event_mouse *)event;
            return app_list_view_onmouse(app_list, emouse);
        }
    case RTGUI_EVENT_GESTURE:
        {
            struct rtgui_event_gesture *gestrure_event =
                (struct rtgui_event_gesture *)event;
            switch (gestrure_event->type)
            {
            case RTGUI_GESTURE_RIGHT:
                priv_page(RTGUI_WIDGET(object));
                break;
            case RTGUI_GESTURE_LEFT:
                next_page(RTGUI_WIDGET(object));
                break;
            }
        }
        break;
    case RTGUI_EVENT_WIN_ACTIVATE:
        statusbar_set_title(RT_NULL);
        statusbar_show_back_button(RT_FALSE);
        return rtgui_win_event_handler(object, event);
    default:
        return rtgui_win_event_handler(object, event);
    }
    return RT_FALSE;
}
Пример #2
0
static rt_bool_t rtgui_slider_onkey(struct rtgui_slider* slider, struct rtgui_event_kbd *event)
{
	RT_ASSERT(slider != RT_NULL);
	RT_ASSERT(event != RT_NULL);

	if (!(RTGUI_KBD_IS_UP(event)))
		return RT_TRUE;

	if (slider->orient == RTGUI_HORIZONTAL)
	{
		if (event->key == RTGUIK_RIGHT)
		{
			if (slider->value > slider->min)
				slider->value++;
		}
		else if (event->key == RTGUIK_LEFT)
		{
			if (slider->value < slider->max)
				slider->value--;
		}
	}
	else
	{
		if (event->key == RTGUIK_UP)
		{
			if (slider->value > slider->min)
				slider->value--;
		}
		else if (event->key == RTGUIK_DOWN)
		{
			if (slider->value < slider->max)
				slider->value++;
		}
	}

	/* update widget */
	rtgui_widget_update(RTGUI_WIDGET(slider));
	if (slider->on_changed != RT_NULL) /* invoke callback function */
		slider->on_changed(RTGUI_WIDGET(slider), RT_NULL);

	return RT_TRUE;
}
rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *event)
{
	if (event->type == RTGUI_EVENT_PAINT)
	{
		_draw_default(object, event);
	}
	else if (event->type == RTGUI_EVENT_KBD)
	{
		struct rtgui_event_kbd *kbd = (struct rtgui_event_kbd*)event;

		if (kbd->key == RTGUIK_LEFT || kbd->key == RTGUIK_RIGHT)
			return RT_FALSE;

		if (RTGUI_KBD_IS_UP(kbd))
		{
			if (running)
			{
				/* stop */
				rtgui_app_set_onidle(RT_NULL);
				_draw_default(object, event);
			}
			else
			{
				/* run */
				rtgui_app_set_onidle(_onidle);
			}

			running = !running;
		}
		return RT_TRUE;
	}
	else
	{
		/* 调用默认的事件处理函数 */
		return rtgui_container_event_handler(object, event);
	}

	return RT_FALSE;
}
Пример #4
0
rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object *object, struct rtgui_event *event)
{
    struct rtgui_radiobox *radiobox;
    RTGUI_WIDGET_EVENT_HANDLER_PREPARE

    radiobox = RTGUI_RADIOBOX(object);
    switch (event->type)
    {
    case RTGUI_EVENT_PAINT:
#ifndef RTGUI_USING_SMALL_SIZE
        if (widget->on_draw != RT_NULL)
            widget->on_draw(RTGUI_OBJECT(widget), event);
        else
#endif
        {
            rtgui_theme_draw_radiobox(radiobox);
        }

        break;

    case RTGUI_EVENT_KBD:
        if (RTGUI_WIDGET_IS_HIDE(radiobox)) return RT_FALSE;

#ifndef RTGUI_USING_SMALL_SIZE
        if (widget->on_key != RT_NULL)
            return widget->on_key(RTGUI_OBJECT(widget), event);
        else
#endif
        {
            struct rtgui_event_kbd *e = (struct rtgui_event_kbd *)event;

            /* set focused */
            rtgui_widget_focus(RTGUI_WIDGET(radiobox));
            if (!(RTGUI_KBD_IS_UP(e))) return RT_FALSE;

            if (radiobox->orient == RTGUI_VERTICAL)
            {
                if (e->key == RTGUIK_UP)
                {
                    if (radiobox->item_selection > 0)
                    {
                        rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
                        return RT_TRUE;
                    }
                }
                else if (e->key == RTGUIK_DOWN)
                {
                    if (radiobox->item_selection < radiobox->item_count - 1)
                    {
                        rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
                        return RT_TRUE;
                    }
                }
            }
            else
            {
                if (e->key == RTGUIK_LEFT)
                {
                    if (radiobox->item_selection > 0)
                    {
                        rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
                        return RT_TRUE;
                    }
                }
                else if (e->key == RTGUIK_RIGHT)
                {
                    if (radiobox->item_selection < radiobox->item_count - 1)
                    {
                        rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
                        return RT_TRUE;
                    }
                }
            }
        }
        break;

    case RTGUI_EVENT_MOUSE_BUTTON:
#ifndef RTGUI_USING_SMALL_SIZE
        if (widget->on_mouseclick != RT_NULL)
            widget->on_mouseclick(RTGUI_OBJECT(widget), event);
        else
#endif
        {
            rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse *)event);
        }
        break;
    default:
        return rtgui_widget_event_handler(object, event);
    }

    return RT_FALSE;
}
Пример #5
0
static rt_bool_t rtgui_textbox_onkey(struct rtgui_object *widget, rtgui_event_t *event)
{
	rtgui_textbox_t *box = RTGUI_TEXTBOX(widget);
	struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *)event;
	rt_size_t length;
	rt_uint16_t posbak = box->position;

	RT_ASSERT(box != RT_NULL);
	RT_ASSERT(ekbd != RT_NULL);

	/* handle the key at down time and nothing to do with up */
	if (RTGUI_KBD_IS_UP(ekbd))
		return RT_TRUE;

	if (box->dis_length == 0)
	{
		rtgui_rect_t rect;

		rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);

		if (box->font_width == 0)
			return RT_FALSE;

		box->dis_length = ((rtgui_rect_width(rect) - 5) / box->font_width) & ~0x1;
	}

	length = rt_strlen((char*)box->text);
	if (ekbd->key == RTGUIK_DELETE)
	{
        int chw;
        unsigned char *c;

        if (TB_ABSPOS(box) == length)
        {
            goto _exit;
        }
        chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box)).char_width;

        /* remove character */
        for (c = &box->text[TB_ABSPOS(box)]; c[chw] != '\0'; c++)
            *c = c[chw];
        *c = '\0';
	}
	else if (ekbd->key == RTGUIK_BACKSPACE)
	{
		/* delete front character */
		if (box->position == 0)
		{
			if(box->first_pos == 0)
                goto _exit;

            if(box->first_pos > box->dis_length)
            {
                int head_fix;
                int chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box) - 1).char_width;

                rt_memmove(box->text + TB_ABSPOS(box) - chw,
                           box->text + TB_ABSPOS(box),
                           length - TB_ABSPOS(box) + 1);

                head_fix = 0;
                /* FIXME: */
                if (box->text[box->first_pos - box->dis_length - chw] > 0x80)
                {
                    int i;

                    for (i = box->first_pos - box->dis_length - chw;
                         i < box->first_pos;
                         i++)
                    {
                        if (box->text[i] > 0x80)
                            head_fix++;
                        else
                            break;
                    }
                    /* if the head is in middle of wide char, move one less
                     * byte */
                    head_fix = head_fix % 2;
                }

                box->first_pos = box->first_pos - box->dis_length
                                 + head_fix - chw;
                box->position  = box->dis_length - head_fix;
            }
            else
            {
                int chw;
                if (box->text[TB_ABSPOS(box) - 1] < 0x80)
                {
                    /* also copy the \0 */
                    rt_memmove(box->text + TB_ABSPOS(box) - 1,
                               box->text + TB_ABSPOS(box),
                                  length - TB_ABSPOS(box) + 1);
                    chw = 1;
                }
                else
                {
                    rt_memmove(box->text + TB_ABSPOS(box) - 2,
                               box->text + TB_ABSPOS(box),
                                  length - TB_ABSPOS(box) + 1);
                    chw = 2;
                }
                box->position = box->first_pos - chw;
                box->first_pos = 0;
            }
		}
		else
		{
            unsigned char *c;
            int chw;

            chw = _string_char_width((char*)box->text, length, TB_ABSPOS(box) - 1).char_width;

            /* remove character */
            for (c = &box->text[TB_ABSPOS(box) - chw]; c[chw] != '\0'; c++)
                *c = c[chw];
            *c = '\0';

            box->position -= chw;
		}
	}
	else if (ekbd->key == RTGUIK_LEFT)
	{
        int chw;

        if (box->first_pos == 0 && box->position == 0)
            goto _exit;

        if (box->text[TB_ABSPOS(box) - 1] > 0x80)
            chw = 2;
        else
            chw = 1;

		/* move to prev */
		if (box->position >= chw)
		{
            box->position -= chw;
		}
		else
		{
            if (box->first_pos >= chw)
                box->first_pos -= chw;
            else
                box->first_pos = 0;
		}
	}
	else if (ekbd->key == RTGUIK_RIGHT)
	{
        int chw;

        if ((TB_ABSPOS(box) + 2) <= length &&
            box->text[TB_ABSPOS(box)] > 0x80)
            chw = 2;
        else
            chw = 1;

		/* move to next */
		if (TB_ABSPOS(box) < length)
		{
			if(box->position + chw <= box->dis_length)
				box->position += chw;
			else
            {
                /* always move one wide char when the first char is wide */
                if (box->text[box->first_pos] > 0x80)
                {
                    box->first_pos += 2;
                    if (chw == 2)
                    {
                        int i;
                        int head_fix = 0;
                        for (i = box->first_pos;
                             i < box->first_pos + box->dis_length;
                             i++)
                        {
                            if (box->text[i] > 0x80)
                                head_fix++;
                        }
                        head_fix %= 2;
                        if (head_fix)
                        {
                            box->first_pos += 2;
                            box->position = box->dis_length - 1;
                        }
                    }
                    else if (chw == 1)
                        /* we have moved the box by 2 bytes but the last one is
                         * a narrow char */
                        box->position -= 1;
                    else
                        RT_ASSERT(0);
                }
                else
                    box->first_pos += chw;
            }
		}
	}
	else if (ekbd->key == RTGUIK_HOME)
	{
		/* move cursor to start */
		box->position = 0;
		box->first_pos = 0;
	}
	else if (ekbd->key == RTGUIK_END)
	{
		/* move cursor to end */
		if(length > box->dis_length)
		{
			box->position = box->dis_length;
			box->first_pos = length - box->dis_length;
		}
		else
		{
			box->position = length;
			box->first_pos = 0;
		}
	}
	else if (ekbd->key == RTGUIK_RETURN)
	{
		if (box->on_enter != RT_NULL)
		{
			box->on_enter(box, event);
		}
	}
	else if (ekbd->key == RTGUIK_NUMLOCK)
	{
		/* change numlock state */
		/*
		extern void update_number_lock(void);
		update_number_lock();
		*/
	}
	else
    {
        rt_uint16_t chr;
        int chw;

        if (!(ekbd->unicode || isprint(ekbd->key)))
            goto _exit;

        if (ekbd->unicode)
        {
            chr = ekbd->unicode;
            chw = 2;
        }
        else
        {
            chr = ekbd->key;
            chw = 1;
        }

        if (box->flag & RTGUI_TEXTBOX_DIGIT)
        {
            /* only input digit */
            if (!isdigit(chr))
            {
                /* exception: '.' and '-' */
                if (chr != '.' && chr != '-')return RT_FALSE;
                if (chr == '.' && strchr((char*)box->text, '.'))return RT_FALSE;

                if (chr == '-')
                {
                    if (length + chw > box->line_length) return RT_FALSE;

                    if (strchr((char*)box->text, '-'))
                    {
                        unsigned char *c;
                        for (c = &box->text[0]; c != &box->text[length]; c++)
                            *c = *(c + 1);
                        box->text[length] = '\0';
                        box->position --;
                        goto _exit;
                    }
                    else
                    {
                        unsigned 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;
                    }
                }
            }
        }

        if (length + chw > box->line_length)
            return RT_FALSE;

        if (TB_ABSPOS(box) <= length - 1)
        {
            unsigned char *c;

            for (c = &box->text[length + chw - 1];
                 c != &box->text[TB_ABSPOS(box)];
                 c -= 1)
                *c = *(c - chw);
        }

        if (chw == 1)
        {
            box->text[TB_ABSPOS(box)] = chr;
        }
        else if (chw == 2)
        {
            box->text[TB_ABSPOS(box)] = chr >> 8;
            box->text[TB_ABSPOS(box)+1] = chr & 0xFF;
        }
        else
        {
Пример #6
0
static void rtgui_event_dump(struct rtgui_app* app, rtgui_event_t *event)
{
    char *sender = "(unknown)";

    if ((event->type == RTGUI_EVENT_TIMER) ||
            (event->type == RTGUI_EVENT_UPDATE_BEGIN) ||
            (event->type == RTGUI_EVENT_MOUSE_MOTION) ||
            (event->type == RTGUI_EVENT_UPDATE_END))
    {
        /* don't dump timer event */
        return ;
    }

    if (event->sender != RT_NULL)
        sender = (char*)event->sender->name;

    if (event->type >= RTGUI_EVENT_COMMAND)
    {
        rt_kprintf("%s -- USER COMMAND EVENT --> %s \n", sender, app->name);
        return ;
    }
    else
    {
        rt_kprintf("%s -- %s --> %s ", sender, rtgui_event_string[event->type], app->name);
    }

    switch (event->type)
    {
    case RTGUI_EVENT_APP_CREATE:
    case RTGUI_EVENT_APP_DESTROY:
    case RTGUI_EVENT_APP_ACTIVATE:
    {
        struct rtgui_event_application *eapp = (struct rtgui_event_application *)event;

        rt_kprintf("app: %s", eapp->app->name);
    }
    break;

    case RTGUI_EVENT_PAINT:
    {
        struct rtgui_event_paint *paint = (struct rtgui_event_paint *)event;

        if (paint->wid != RT_NULL)
            rt_kprintf("win: %s", paint->wid->title);
    }
    break;

    case RTGUI_EVENT_KBD:
    {
        struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *) event;
        if (ekbd->wid != RT_NULL)
            rt_kprintf("win: %s", ekbd->wid->title);
        if (RTGUI_KBD_IS_UP(ekbd)) rt_kprintf(", up");
        else rt_kprintf(", down");
    }
    break;

    case RTGUI_EVENT_CLIP_INFO:
    {
        struct rtgui_event_clip_info *info = (struct rtgui_event_clip_info *)event;

        if (info->wid != RT_NULL)
            rt_kprintf("win: %s", info->wid->title);
    }
    break;

    case RTGUI_EVENT_WIN_CREATE:
    {
        struct rtgui_event_win_create *create = (struct rtgui_event_win_create *)event;

        rt_kprintf(" win: %s at (x1:%d, y1:%d, x2:%d, y2:%d), addr: %p",
                   create->wid->title,
                   RTGUI_WIDGET(create->wid)->extent.x1,
                   RTGUI_WIDGET(create->wid)->extent.y1,
                   RTGUI_WIDGET(create->wid)->extent.x2,
                   RTGUI_WIDGET(create->wid)->extent.y2,
                   create->wid
                  );
    }
    break;

    case RTGUI_EVENT_UPDATE_END:
    {
        struct rtgui_event_update_end *update_end = (struct rtgui_event_update_end *)event;
        rt_kprintf("(x:%d, y1:%d, x2:%d, y2:%d)", update_end->rect.x1,
                   update_end->rect.y1,
                   update_end->rect.x2,
                   update_end->rect.y2);
    }
    break;

    case RTGUI_EVENT_WIN_ACTIVATE:
    case RTGUI_EVENT_WIN_DEACTIVATE:
    case RTGUI_EVENT_WIN_SHOW:
    case RTGUI_EVENT_WIN_HIDE:
    case RTGUI_EVENT_WIN_MODAL_ENTER:
    {
        struct rtgui_event_win *win = (struct rtgui_event_win *)event;

        if (win->wid != RT_NULL)
            rt_kprintf("win: %s", win->wid->title);
    }
    break;

    case RTGUI_EVENT_WIN_MOVE:
    {
        struct rtgui_event_win_move *win = (struct rtgui_event_win_move *)event;

        if (win->wid != RT_NULL)
        {
            rt_kprintf("win: %s", win->wid->title);
            rt_kprintf(" to (x:%d, y:%d)", win->x, win->y);
        }
    }
    break;

    case RTGUI_EVENT_WIN_RESIZE:
    {
        struct rtgui_event_win_resize *win = (struct rtgui_event_win_resize *)event;

        if (win->wid != RT_NULL)
        {
            rt_kprintf("win: %s, rect(x1:%d, y1:%d, x2:%d, y2:%d)", win->wid->title,
                       RTGUI_WIDGET(win->wid)->extent.x1,
                       RTGUI_WIDGET(win->wid)->extent.y1,
                       RTGUI_WIDGET(win->wid)->extent.x2,
                       RTGUI_WIDGET(win->wid)->extent.y2);
        }
    }
    break;

    case RTGUI_EVENT_MOUSE_BUTTON:
    case RTGUI_EVENT_MOUSE_MOTION:
    {
        struct rtgui_event_mouse *mouse = (struct rtgui_event_mouse *)event;

        if (mouse->button & RTGUI_MOUSE_BUTTON_LEFT) rt_kprintf("left ");
        else rt_kprintf("right ");

        if (mouse->button & RTGUI_MOUSE_BUTTON_DOWN) rt_kprintf("down ");
        else rt_kprintf("up ");

        if (mouse->wid != RT_NULL)
            rt_kprintf("win: %s at (%d, %d)", mouse->wid->title,
                       mouse->x, mouse->y);
        else
            rt_kprintf("(%d, %d)", mouse->x, mouse->y);
    }
    break;

    case RTGUI_EVENT_MONITOR_ADD:
    {
        struct rtgui_event_monitor *monitor = (struct rtgui_event_monitor *)event;
        if (monitor->wid != RT_NULL)
        {
            rt_kprintf("win: %s, the rect is:(%d, %d) - (%d, %d)", monitor->wid->title,
                       monitor->rect.x1, monitor->rect.y1,
                       monitor->rect.x2, monitor->rect.y2);
        }
    }
    break;

    default:
    break;
    }

    rt_kprintf("\n");
}
Пример #7
0
Файл: edit.c Проект: amsl/RTGUI
static rt_bool_t rtgui_edit_onkey(pvoid wdt, rtgui_event_t* event)
{
	enum { EDIT_NONE, EDIT_ONDRAW, EDIT_UPDATE };
	struct rtgui_edit *edit = RTGUI_EDIT(wdt);
	struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd*)event;
	struct edit_line *line=RT_NULL;
	rt_bool_t update_type = EDIT_NONE;
	
	RT_ASSERT(edit != RT_NULL);
	RT_ASSERT(ekbd != RT_NULL);

	if (RTGUI_KBD_IS_UP(ekbd))
	{	/* reset function key */
		if(ekbd->key == RTGUIK_RCTRL || ekbd->key == RTGUIK_LCTRL)
			edit->flag &= ~RTGUI_EDIT_CTRL;
		else if(ekbd->key == RTGUIK_RALT || ekbd->key == RTGUIK_LALT)
			edit->flag &= ~RTGUI_EDIT_ALT;
		else if(ekbd->key == RTGUIK_RSHIFT || ekbd->key == RTGUIK_LSHIFT)
			edit->flag &= ~RTGUI_EDIT_SHIFT;
		else if(ekbd->key == RTGUIK_CAPSLOCK)
			edit->flag &= ~RTGUI_EDIT_CAPSLOCK;
		else if(ekbd->key == RTGUIK_NUMLOCK)
			edit->flag &= ~RTGUI_EDIT_NUMLOCK;
		return RT_TRUE;
	}
	
	line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y);
	if(line == RT_NULL) 
		return RT_FALSE;

	/* rt_kprintf("key=%04X ",ekbd->key); */
	if(ekbd->key == RTGUIK_RCTRL || ekbd->key == RTGUIK_LCTRL)
	{	/* use CTRL key */
		edit->flag |= RTGUI_EDIT_CTRL;
		return RT_FALSE;
	}
	else if(ekbd->key == RTGUIK_RALT || ekbd->key == RTGUIK_LALT)
	{	/* use ALT key */
		edit->flag |= RTGUI_EDIT_ALT;
		return RT_FALSE;
	}
	else if(ekbd->key == RTGUIK_RSHIFT || ekbd->key == RTGUIK_LSHIFT)
	{	/* use SHIFT key */
		edit->flag |= RTGUI_EDIT_SHIFT;
		return RT_FALSE;
	}
	else if(ekbd->key == RTGUIK_CAPSLOCK)
	{
		edit->flag |= RTGUI_EDIT_CAPSLOCK;
		return RT_FALSE;
	}
	else if(ekbd->key == RTGUIK_NUMLOCK)
	{
		edit->flag |= RTGUI_EDIT_NUMLOCK;
		return RT_FALSE;
	}
	else if(ekbd->key == RTGUIK_DELETE)
	{	/* delete latter character */
		int ofs = edit->upleft.x + edit->visual.x;
		if(ofs > line->len - 1 || (ofs==0 && line->len==0))
		{	/* will the next line marges into the current line */
			struct edit_line* next_line = line->next;
			if(next_line != RT_NULL)
			{
				struct edit_line *update_end_line;
				
				update_type = EDIT_UPDATE;
				edit->update.start = edit->visual;

				rtgui_edit_connect_line(edit, line, next_line);
				rtgui_edit_delete_line(edit, next_line);

				if(edit->max_rows-edit->upleft.y > edit->row_per_page)
				{
					update_end_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->row_per_page);
					if(update_end_line != RT_NULL)
					{
						edit->update.end.x = edit->col_per_page;
						edit->update.end.y = edit->upleft.y + edit->row_per_page;
					}
				}
				else
				{
					int update_end_index = rtgui_edit_get_index_by_line(edit, edit->tail);
					edit->update.end.x = edit->col_per_page;
					edit->update.end.y = update_end_index+1;
				}
			}
			line->len = rtgui_edit_line_strlen(line->text);
			goto _edit_exit;
		}
		else if(ofs == line->len - 1)
		{
			line->text[ofs] = '\0';
		}
		else
		{
			char *c;
			rt_uint32_t tmp_pos=1;
			identify_double_byte(edit, line, EDIT_IDENT_DIR_RIGHT, &tmp_pos);
			/* remove character */
			for(c = &line->text[ofs]; c[tmp_pos] != '\0'; c++)
				*c = c[tmp_pos];
			*c = '\0';
		}
		update_type = EDIT_UPDATE;
		edit->update.start = edit->visual;
		edit->update.end.x = line->len-edit->upleft.x;
		if (edit->update.end.x > edit->col_per_page)
			edit->update.end.x = edit->col_per_page;
		edit->update.end.y = edit->visual.y;
	}
	else if(ekbd->key == RTGUIK_BACKSPACE)
	{	
		if(edit->visual.x == 0)
		{   /* incorporated into prev line */
			struct rtgui_event_kbd event_kbd;
			struct edit_line* prev_line = line->prev;
			if(prev_line != RT_NULL)
			{
				struct edit_line *update_end_line;
				
				update_type = EDIT_UPDATE;
				edit->visual.x = prev_line->len;

				rtgui_edit_connect_line(edit, prev_line, line);
				kbd_event_set_key(&event_kbd, RTGUIK_UP);
				rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
				rtgui_edit_delete_line(edit, line);

				edit->update.start = edit->visual; /* update.start.y is changed */
				if(edit->max_rows-edit->upleft.y > edit->row_per_page)
				{
					update_end_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->row_per_page);
					if(update_end_line != RT_NULL)
					{
						edit->update.end.x = edit->col_per_page;
						edit->update.end.y = edit->upleft.y + edit->row_per_page;
					}
				}
				else
				{
					int update_end_index = rtgui_edit_get_index_by_line(edit, edit->tail);
					edit->update.end.x = edit->col_per_page;
					edit->update.end.y = update_end_index+1;
				}
			}
			goto _edit_exit;
		}
		
		/* delete front character */
		if(edit->visual.x == line->len)
		{
			rt_uint32_t tmp_pos=1;
			identify_double_byte(edit, line, EDIT_IDENT_DIR_LEFT, &tmp_pos);
			line->text[edit->visual.x-tmp_pos] = '\0';
			edit->visual.x -= tmp_pos;
		}
		else if(edit->visual.x != 0)
		{	/* remove current character */
			char *c;
			rt_uint32_t tmp_pos=1;
			identify_double_byte(edit, line, EDIT_IDENT_DIR_LEFT, &tmp_pos);
			/* remove character */
			for(c = &line->text[edit->visual.x - tmp_pos]; c[tmp_pos] != '\0'; c++)
			{
				*c = c[tmp_pos];
			}
			*c = '\0';
			edit->visual.x -= tmp_pos;
		}
		/* adjusted line buffer length */
		if(rtgui_edit_alloc_len(edit->bzsize, line->len+2) < line->zsize)
		{	
			line->zsize = rtgui_edit_alloc_len(edit->bzsize, line->len+1);
			line->text = rt_realloc(line->text, line->zsize);
		}
		update_type = EDIT_UPDATE;
		edit->update.start = edit->visual; 
		edit->update.end.x = line->len;
		edit->update.end.y = edit->visual.y;
	}
	else if(ekbd->key == RTGUIK_UP)
	{	/* move to prev line */
		struct edit_line* prev_line;
		if(edit->visual.y > 0)
			edit->visual.y --;
		else
		{
			/* change first row */
			if(edit->upleft.y > 0)
			{
				edit->upleft.y --;
				if(edit->first_line->prev != RT_NULL)
					edit->first_line = edit->first_line->prev;
				update_type = EDIT_ONDRAW;
			}
		}
		
		/* The position of the recount X */
		prev_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->visual.y);
		if(prev_line == RT_NULL)
			return RT_FALSE;

		if(edit->upleft.x > 0)
		{
			if(prev_line->len <= edit->upleft.x)
			{
				if(prev_line->len <= edit->col_per_page)
				{
					edit->upleft.x = 0;
					edit->visual.x = prev_line->len;
				}
				else
				{
					edit->upleft.x = prev_line->len - (edit->col_per_page-1);
					edit->visual.x = edit->col_per_page-1;
				}
				update_type = EDIT_ONDRAW;
			}
			else if(prev_line->len - edit->upleft.x < edit->col_per_page)
			{
				if(edit->visual.x > prev_line->len - edit->upleft.x)
					edit->visual.x = prev_line->len - edit->upleft.x;
				else
				{
					rt_uint32_t tmp_pos=0;
					if(identify_double_byte(edit, line, EDIT_IDENT_DIR_LEFT, &tmp_pos))
						edit->visual.x -= (2-tmp_pos);
				}
			}
		}
		else if(edit->visual.x > prev_line->len)
			edit->visual.x = prev_line->len;
		else if(prev_line->len >= 2)
		{
			rt_uint32_t tmp_pos=0;
			if(identify_double_byte(edit, prev_line, EDIT_IDENT_DIR_LEFT, &tmp_pos))
				edit->visual.x -= (2-tmp_pos);
		}

#ifdef RTGUI_EDIT_USING_SCROLL		
		/* update vscroll */
		if(edit->vscroll && !RTGUI_WIDGET_IS_HIDE(edit))
		{
			if(!RTGUI_WIDGET_IS_HIDE(edit->vscroll))
				rtgui_scrollbar_set_value(edit->vscroll,edit->upleft.y);
		}
#endif
	}
	else if(ekbd->key == RTGUIK_DOWN)
	{	
		struct edit_line *tail_line, *next_line;
		tail_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y);
		if(tail_line != RT_NULL)
		{	/* it is tail line */
			if(tail_line == edit->tail) return RT_FALSE;
		}
		/* move to next line */
		if(edit->visual.y < edit->row_per_page - 2)
		{
			edit->visual.y ++;
		}
		else if(edit->visual.y+edit->upleft.y < edit->max_rows-1)
		{
			/* change first row */
			edit->upleft.y++;
			if(edit->first_line->next != RT_NULL)
				edit->first_line = edit->first_line->next;
			update_type = EDIT_ONDRAW;
		}
		
		/* adjust next line end position */
		next_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->visual.y);
		if(next_line == RT_NULL)	
			return RT_FALSE;
		
		if(edit->upleft.x > 0)
		{
			if(next_line->len <= edit->upleft.x)
			{
				if(next_line->len <= edit->col_per_page)
				{
					edit->upleft.x = 0;
					edit->visual.x = next_line->len;
				}
				else
				{
					edit->upleft.x = next_line->len - (edit->col_per_page-1);
					edit->visual.x = edit->col_per_page-1;
				}
				update_type = EDIT_ONDRAW;
			}
			else if(next_line->len - edit->upleft.x < edit->col_per_page)
			{
				if(edit->visual.x > next_line->len - edit->upleft.x)
					edit->visual.x = next_line->len - edit->upleft.x;
				else
				{
					rt_uint32_t tmp_pos=0;
					if(identify_double_byte(edit, next_line, EDIT_IDENT_DIR_LEFT, &tmp_pos))
						edit->visual.x -= (2-tmp_pos);
				}
			}
		}
		else if(edit->visual.x > next_line->len)
			edit->visual.x = next_line->len;
		else if(next_line->len >= 2)
		{
			rt_uint32_t tmp_pos=0;
			if(identify_double_byte(edit, next_line, EDIT_IDENT_DIR_LEFT, &tmp_pos))
				edit->visual.x -= (2-tmp_pos);
		}

#ifdef RTGUI_EDIT_USING_SCROLL		
		/* update vscroll */
		if(edit->vscroll && !RTGUI_WIDGET_IS_HIDE(edit))
		{
			if(!RTGUI_WIDGET_IS_HIDE(edit->vscroll))
				rtgui_scrollbar_set_value(edit->vscroll,edit->upleft.y);
		}
#endif
	}
	else if(ekbd->key == RTGUIK_LEFT)
	{	/* move to prev char */
		if(edit->visual.x > 0)
		{
			rt_uint32_t tmp_pos=1;
			identify_double_byte(edit, line, EDIT_IDENT_DIR_LEFT, &tmp_pos);
			edit->visual.x -= tmp_pos;
			if(edit->visual.x == -1)
			{
				edit->visual.x = 0;
				edit->upleft.x -= 1;
				update_type = EDIT_ONDRAW;
			}
		}
		else
		{
			if(edit->upleft.x > 0)
			{
				rt_uint32_t tmp_pos=1;
				identify_double_byte(edit, line, EDIT_IDENT_DIR_LEFT, &tmp_pos);
				edit->upleft.x -= tmp_pos;
				update_type = EDIT_ONDRAW;
			}
			else
			{	
				struct rtgui_event_kbd event_kbd;
				struct edit_line* first_line;
				first_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y);
				if(first_line != RT_NULL)
				{	/* it is head line */
					if(first_line == edit->head) return RT_FALSE;
				}
				/* move the caret to the prev line end */
				kbd_event_set_key(&event_kbd, RTGUIK_UP);
				rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
				kbd_event_set_key(&event_kbd, RTGUIK_END);
				rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
			}
		}
	}
	else if(ekbd->key == RTGUIK_RIGHT)
	{	/* move to next char */
		if(line->len >= edit->col_per_page)
		{
			if(edit->upleft.x+edit->col_per_page <= line->len)
			{
				if(edit->visual.x < edit->col_per_page-1)
				{
					rt_uint32_t tmp_pos=1;
					identify_double_byte(edit, line, EDIT_IDENT_DIR_RIGHT, &tmp_pos);
					edit->visual.x += tmp_pos;
				}
				else if(edit->visual.x == edit->col_per_page-1)
				{
					if(edit->upleft.x+edit->col_per_page < line->len)
						edit->upleft.x ++;
					else
						edit->upleft.x = line->len - edit->col_per_page + 1;
					update_type = EDIT_ONDRAW;
				}
			}
			else
			{
				struct rtgui_event_kbd event_kbd;
				/* move to next head */
				kbd_event_set_key(&event_kbd, RTGUIK_DOWN);
				rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
				kbd_event_set_key(&event_kbd, RTGUIK_HOME);
				rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
			}
		}
		else
		{
			if(edit->visual.x < line->len)
			{
				rt_uint32_t tmp_pos=1;
				identify_double_byte(edit, line, EDIT_IDENT_DIR_RIGHT, &tmp_pos);
				edit->visual.x += tmp_pos;
			}
			else
			{
				struct rtgui_event_kbd event_kbd;
				struct edit_line* tail_line;
				tail_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y + edit->visual.y);
				if(tail_line != RT_NULL)
				{	/* it is tail line */
					if(tail_line == edit->tail) return RT_FALSE;
				}
				/* move the caret to the next line head */
				kbd_event_set_key(&event_kbd, RTGUIK_DOWN);
				rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
				kbd_event_set_key(&event_kbd, RTGUIK_HOME);
				rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
			}
		}
	}
	else if(ekbd->key == RTGUIK_HOME)
	{	/* move cursor to line head */
		edit->visual.x = 0;
		if(edit->upleft.x > 0)
		{
			edit->upleft.x = 0;
			update_type = EDIT_ONDRAW;
		}
	}
	else if(ekbd->key == RTGUIK_END)
	{	/* move cursor to line tail */
		if(line->len >= edit->col_per_page)
		{
			edit->visual.x = edit->col_per_page - 1;
			edit->upleft.x = line->len - (edit->col_per_page-1);
			update_type = EDIT_ONDRAW;
		}
		else
			edit->visual.x = line->len;
	}
	else if(ekbd->key == RTGUIK_TAB)
	{
		int space_nums;
		struct rtgui_event_kbd event_kbd;

		/* using spaces to replace TAB */
		space_nums = edit->tabsize - (edit->upleft.x+edit->visual.x) % edit->tabsize;
		while(space_nums--)
		{
			kbd_event_set_key(&event_kbd, RTGUIK_SPACE);
			rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
		}
	}
	else if(ekbd->key == RTGUIK_PAGEUP)
	{
		if(edit->max_rows <= edit->row_per_page)
			return RT_FALSE;
	}
	else if(ekbd->key == RTGUIK_PAGEDOWN)
	{
		if(edit->max_rows <= edit->row_per_page)
			return RT_FALSE;
	}
	else if(ekbd->key == RTGUIK_RETURN)
	{
		struct edit_line *update_end_line;
		struct rtgui_event_kbd event_kbd;
	
		/* insert a new line buffer */
		rtgui_edit_insert_line(edit, line, line->text + edit->upleft.x + edit->visual.x);
		line->text[edit->upleft.x + edit->visual.x] = '\0';
		line->len = rtgui_edit_line_strlen(line->text);
		
		/* adjust update line end position */
		if((edit->max_rows-edit->upleft.y) > edit->row_per_page)
		{
			update_type = EDIT_UPDATE;
			edit->update.start = edit->visual;
			update_end_line = rtgui_edit_get_line_by_index(edit, edit->upleft.y+edit->row_per_page-1);
			if(update_end_line != RT_NULL)
			{
				edit->update.end.x = update_end_line->len;
				edit->update.end.y = edit->upleft.y + edit->row_per_page;
			}
		}
		else if((edit->max_rows-edit->upleft.y) < edit->row_per_page)
		{
			int update_end_index = rtgui_edit_get_index_by_line(edit, edit->tail);
			update_type = EDIT_UPDATE;
			edit->update.start = edit->visual;
			edit->update.end.x = edit->tail->len;
			edit->update.end.y = update_end_index;
		}
		
		/* move the caret to the next line head */
		kbd_event_set_key(&event_kbd, RTGUIK_DOWN);
		rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
		kbd_event_set_key(&event_kbd, RTGUIK_HOME);
		rtgui_edit_onkey(edit, (rtgui_event_t*)&event_kbd);
	}
	else
	{
		if(isprint((unsigned char)ekbd->key))
		{	/* it's may print character */
			update_type = EDIT_UPDATE;
			edit->update.start = edit->visual;
			
			if(edit->flag & RTGUI_EDIT_SHIFT)
				ekbd->key = query_shift_code(ekbd->key);
			if(edit->flag & RTGUI_EDIT_CAPSLOCK)
				ekbd->key = query_caps_code(ekbd->key);

			if(line->len < line->zsize-1)
			{
				int ofs = edit->upleft.x + edit->visual.x;
				if(edit->visual.x >= edit->col_per_page-1)
				{
					edit->upleft.x ++;
					update_type = EDIT_ONDRAW;
				}

				if(ofs < line->len)
				{
					char* c;
					for(c = &line->text[line->len]; c != &line->text[ofs]; c--)
						*c = *(c-1);
				}
				line->text[ofs] = ekbd->key;
				if(edit->visual.x < edit->col_per_page-1)
					edit->visual.x ++;
				line->text[line->len+1] = '\0';
				line->len = rtgui_edit_line_strlen(line->text);
				edit->update.end.x = line->len;
				if(edit->update.end.x > edit->col_per_page)
					edit->update.end.x = edit->col_per_page;
				edit->update.end.y = edit->visual.y;
			}
			else
			{	/* adjust line buffer's zone size */
				line->zsize = rtgui_edit_alloc_len(edit->bzsize, line->len+1);
				line->text = rt_realloc(line->text, line->zsize);
				rtgui_edit_onkey(edit, event); /* reentry */
			}
		}
		else
		{
			/* Is small keyboard ? */
			if(edit->flag & RTGUI_EDIT_NUMLOCK)
			{
				if(is_small_keyboard(&ekbd->key))
					rtgui_edit_onkey(edit, event);
				/* small keyboard another value reserved */
			}
		}
	}
	line->len = rtgui_edit_line_strlen(line->text); 

_edit_exit:
	if(edit->flag & RTGUI_EDIT_CARET)
	{
		if(edit->caret_timer != RT_NULL)
			rtgui_timer_stop(edit->caret_timer);

		edit->flag &= ~RTGUI_EDIT_CARET;
		rtgui_edit_draw_caret(edit);/* refresh it */
		if(edit->caret_timer != RT_NULL)
			rtgui_timer_start(edit->caret_timer);
	}

	/* re-draw edit widget */
	if(update_type == EDIT_ONDRAW)
		rtgui_edit_ondraw(edit);
	else if(update_type == EDIT_UPDATE)
		rtgui_edit_update(edit);

	if(RTGUI_WIDGET_IS_FOCUSED(edit))
	{
		rtgui_edit_init_caret(edit, edit->visual);
		edit->flag |= RTGUI_EDIT_CARET;
		rtgui_edit_draw_caret(edit);
	}
	return RT_TRUE;
}
Пример #8
0
static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t* event)
{
	char* sender = "(unknown)";

	if (event->sender != RT_NULL) sender = event->sender->name;

	if ((event->type == RTGUI_EVENT_TIMER) ||
		(event->type == RTGUI_EVENT_UPDATE_BEGIN) ||
		(event->type == RTGUI_EVENT_UPDATE_END))
	{
		/* don't dump timer event */
		return ;
	}

	rt_kprintf("%s -- %s --> %s ", sender, event_string[event->type], tid->name);
	switch (event->type)
	{
	case RTGUI_EVENT_PAINT:
		{
			struct rtgui_event_paint *paint = (struct rtgui_event_paint *)event;

			if(paint->wid != RT_NULL)
				rt_kprintf("win: %s", paint->wid->title);
		}
		break;

	case RTGUI_EVENT_KBD:
		{
			struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd*) event;
			if (ekbd->wid != RT_NULL)
				rt_kprintf("win: %s", ekbd->wid->title);
			if (RTGUI_KBD_IS_UP(ekbd)) rt_kprintf(", up");
			else rt_kprintf(", down");
		}
		break;

	case RTGUI_EVENT_CLIP_INFO:
		{
			struct rtgui_event_clip_info *info = (struct rtgui_event_clip_info *)event;

			if(info->wid != RT_NULL)
				rt_kprintf("win: %s", info->wid->title);
		}
		break;

	case RTGUI_EVENT_WIN_CREATE:
		{
			struct rtgui_event_win_create *create = (struct rtgui_event_win_create*)event;

			rt_kprintf(" win: %s at (x1:%d, y1:%d, x2:%d, y2:%d)",
#ifdef RTGUI_USING_SMALL_SIZE
				create->wid->title,
				RTGUI_WIDGET(create->wid)->extent.x1,
				RTGUI_WIDGET(create->wid)->extent.y1,
				RTGUI_WIDGET(create->wid)->extent.x2,
				RTGUI_WIDGET(create->wid)->extent.y2);
#else
				create->title,
				create->extent.x1,
				create->extent.y1,
				create->extent.x2,
				create->extent.y2);
#endif
		}
		break;

	case RTGUI_EVENT_UPDATE_END:
		{
			struct rtgui_event_update_end* update_end = (struct rtgui_event_update_end*)event;
			rt_kprintf("(x:%d, y1:%d, x2:%d, y2:%d)", update_end->rect.x1,
				update_end->rect.y1,
				update_end->rect.x2,
				update_end->rect.y2);
		}
		break;

	case RTGUI_EVENT_WIN_ACTIVATE:
	case RTGUI_EVENT_WIN_DEACTIVATE:
	case RTGUI_EVENT_WIN_SHOW:
		{
			struct rtgui_event_win *win = (struct rtgui_event_win *)event;

			if(win->wid != RT_NULL)
				rt_kprintf("win: %s", win->wid->title);
		}
		break;

	case RTGUI_EVENT_WIN_MOVE:
		{
			struct rtgui_event_win_move *win = (struct rtgui_event_win_move *)event;

			if(win->wid != RT_NULL)
			{
				rt_kprintf("win: %s", win->wid->title);
				rt_kprintf(" to (x:%d, y:%d)", win->x, win->y);
			}
		}
		break;

	case RTGUI_EVENT_WIN_RESIZE:
		{
			struct rtgui_event_win_resize* win = (struct rtgui_event_win_resize *)event;

			if (win->wid != RT_NULL)
			{
				rt_kprintf("win: %s, rect(x1:%d, y1:%d, x2:%d, y2:%d)", win->wid->title,
					RTGUI_WIDGET(win->wid)->extent.x1,
					RTGUI_WIDGET(win->wid)->extent.y1,
					RTGUI_WIDGET(win->wid)->extent.x2,
					RTGUI_WIDGET(win->wid)->extent.y2);
			}
		}
		break;

	case RTGUI_EVENT_MOUSE_BUTTON:
	case RTGUI_EVENT_MOUSE_MOTION:
		{
			struct rtgui_event_mouse *mouse = (struct rtgui_event_mouse*)event;

			if (mouse->button & RTGUI_MOUSE_BUTTON_LEFT) rt_kprintf("left ");
			else rt_kprintf("right ");

			if (mouse->button & RTGUI_MOUSE_BUTTON_DOWN) rt_kprintf("down ");
			else rt_kprintf("up ");

			if (mouse->wid != RT_NULL)
				rt_kprintf("win: %s at (%d, %d)", mouse->wid->title,
				mouse->x, mouse->y);
			else
				rt_kprintf("(%d, %d)", mouse->x, mouse->y);
		}
		break;

	case RTGUI_EVENT_MONITOR_ADD:
		{
			struct rtgui_event_monitor *monitor = (struct rtgui_event_monitor*)event;
			if (monitor->panel != RT_NULL)
			{
#if 0
				rt_kprintf("panel: %s, the rect is:(%d, %d) - (%d, %d)", monitor->panel->name,
					monitor->rect.x1, monitor->rect.y1,
					monitor->rect.x2, monitor->rect.y2);
#endif
				rt_kprintf("the rect is:(%d, %d) - (%d, %d)",
					monitor->rect.x1, monitor->rect.y1,
					monitor->rect.x2, monitor->rect.y2);
			}
			else if (monitor->wid != RT_NULL)
			{
				rt_kprintf("win: %s, the rect is:(%d, %d) - (%d, %d)", monitor->wid->title,
					monitor->rect.x1, monitor->rect.y1,
					monitor->rect.x2, monitor->rect.y2);
			}
		}
		break;
	}

	rt_kprintf("\n");
}
Пример #9
0
static rt_bool_t rtgui_textbox_onkey(struct rtgui_object *widget, rtgui_event_t *event)
{
	rtgui_textbox_t *box = RTGUI_TEXTBOX(widget);
	struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd *)event;
	rt_size_t length;
	rt_uint16_t posbak = box->position;

	RT_ASSERT(box != RT_NULL);
	RT_ASSERT(ekbd != RT_NULL);

	/* handle the key at down time and nothing to do with up */
	if (RTGUI_KBD_IS_UP(ekbd))
		return RT_TRUE;

	if (box->dis_length == 0)
	{
		rtgui_rect_t rect;

		rtgui_widget_get_rect(RTGUI_WIDGET(box), &rect);

		if (box->font_width == 0)
			return RT_FALSE;

		box->dis_length = (rtgui_rect_width(rect) - 5) / box->font_width;
	}

	length = rt_strlen(box->text);
	if (ekbd->key == RTGUIK_DELETE)
	{
		/* delete latter character */
		if (box->first_pos + box->position == length - 1)
		{
			box->text[box->first_pos + box->position] = '\0';
		}
		else
		{
			char *c;

			/* remove character */
			for (c = &box->text[box->first_pos + box->position]; c[1] != '\0'; c++)
				*c = c[1];
			*c = '\0';
		}
	}
	else if (ekbd->key == RTGUIK_BACKSPACE)
	{
		/* delete front character */
		if (box->position == 0)
		{
			if(box->first_pos > 0)
			{
				if(box->first_pos > box->dis_length)
				{
					box->first_pos -= box->dis_length;
					box->position = box->dis_length;
				}
				else
				{
					box->position = box->first_pos;
					box->first_pos = 0;
				}
			}
		}
		else if (box->position == length-box->first_pos)
		{
			box->text[box->first_pos + box->position - 1] = '\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 --;
		}
	}
	else if (ekbd->key == RTGUIK_LEFT)
	{
		/* move to prev */
		if (box->position > 0)
		{
			box->position --;
		}
		else
		{
			if(box->first_pos > 0)
				box->first_pos -= 1;//DEBUG
		}
	}
	else if (ekbd->key == RTGUIK_RIGHT)
	{
		/* move to next */
		if (box->first_pos + box->position < length)
		{
			if(box->position < box->dis_length)
				box->position ++;
			else 
				box->first_pos += 1;//DEBUG
		}
	}
	else if (ekbd->key == RTGUIK_HOME)
	{
		/* move cursor to start */
		box->position = 0;
		box->first_pos = 0;
	}
	else if (ekbd->key == RTGUIK_END)
	{
		/* move cursor to end */
		if(length > box->dis_length)
		{
			box->position = box->dis_length;
			box->first_pos = length - box->dis_length;
		}
		else
		{
			box->position = length;
			box->first_pos = 0;
		}
	}
	else if (ekbd->key == RTGUIK_RETURN)
	{
		if (box->on_enter != RT_NULL)
		{
			box->on_enter(box, event);
		}
	}
	else if (ekbd->key == RTGUIK_NUMLOCK)
	{
		/* change numlock state */
		/*
		extern void update_number_lock(void);
		update_number_lock();
		*/
	}
	else
	{
		if (isprint(ekbd->key))
		{
			/* it's may print character */
			/* no buffer on this line */
			if (box->flag & RTGUI_TEXTBOX_DIGIT)
			{
				/* only input digit */
				if (!isdigit(ekbd->key))
				{
					/* exception: '.' and '-' */
					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 (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;
						}
					}
				}
			}
			if (length + 1 > box->line_length) return RT_FALSE;

			if (box->first_pos + box->position <= length - 1)
			{
				char *c;

				for (c = &box->text[length]; c != &box->text[box->first_pos + box->position]; c--)
					*c = *(c - 1);
				box->text[length + 1] = '\0';
			}

			box->text[box->first_pos + box->position] = ekbd->key;
			if(box->position < box->dis_length)
				box->position ++;
			else
				box->first_pos ++;
		}
	}

_exit:
	if (box->flag & RTGUI_TEXTBOX_CARET_SHOW)
	{
		if (box->caret_timer != RT_NULL)
			rtgui_timer_stop(box->caret_timer);

		box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
		rtgui_textbox_draw_caret(box, posbak);/* refresh it */
		if (box->caret_timer != RT_NULL)
			rtgui_timer_start(box->caret_timer);
	}

	/* re-draw text box */
	rtgui_textbox_ondraw(box);

	rtgui_textbox_init_caret(box, box->position);
	box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
	rtgui_textbox_draw_caret(box, box->position);

	return RT_TRUE;
}