rt-thread/rtgui/common/caret.c

215 lines
4.5 KiB
C
Raw Normal View History

/*
* File : caret.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/dc.h>
#include <rtgui/caret.h>
#include <rtgui/rtgui_system.h>
#define RTGUI_CARET_WIDTH 2
#ifdef __WIN32__
#define RTGUI_CARET_BLINK 300
#else
#define RTGUI_CARET_BLINK 30
#endif
static void rtgui_caret_blink(struct rtgui_timer* timer, void* parameter)
{
struct rtgui_caret* caret;
rtgui_widget_t* widget;
caret = (struct rtgui_caret*)parameter;
RT_ASSERT(caret != RT_NULL);
if (caret->owner == RT_NULL) return;
/* caret's owner is visible? */
widget = caret->owner;
do
{
if (RTGUI_WIDGET_IS_HIDE(widget) == RT_TRUE) return;
widget = widget->parent;
} while (widget != RT_NULL);
if (caret->is_show == RT_TRUE)
{
/* set to false */
caret->is_show = RT_FALSE;
/* update owner widget */
if (caret->owner != RT_NULL)
{
rtgui_widget_update(caret->owner);
}
}
else
{
/* set to true */
caret->is_show = RT_TRUE;
/* draw caret */
rtgui_caret_draw(caret);
}
}
struct rtgui_caret* rtgui_caret_create(struct rtgui_widget* owner)
{
struct rtgui_caret* caret;
RT_ASSERT(owner != RT_NULL);
caret = (struct rtgui_caret*)rtgui_malloc(sizeof(struct rtgui_caret));
if (caret != RT_NULL)
{
caret->is_show = RT_FALSE;
caret->extent.x1 = 0;
caret->extent.y1 = 0;
caret->extent.x2 = RTGUI_CARET_WIDTH;
caret->extent.y2 = owner->gc.font->height;
caret->owner = owner;
caret->dc = (struct rtgui_dc*)rtgui_dc_buffer_create(RTGUI_CARET_WIDTH, caret->extent.y2);
if (caret->dc == RT_NULL) goto __exit;
rtgui_dc_set_color(caret->dc, black);
rtgui_dc_fill_rect(caret->dc, &(caret->extent));
caret->timer_period = RTGUI_CARET_BLINK;
caret->timer = rtgui_timer_create(caret->timer_period,
RT_TIMER_FLAG_PERIODIC,
rtgui_caret_blink, caret);
if (caret->timer == RT_NULL) goto __exit_dc;
caret->show_point.x = 0;
caret->show_point.y = 0;
}
return caret;
__exit_dc:
rtgui_dc_destory(caret->dc);
__exit:
rtgui_free(caret);
return RT_NULL;
}
void rtgui_caret_destroy(struct rtgui_caret* caret)
{
RT_ASSERT(caret != RT_NULL);
if (caret->is_show == RT_TRUE)
{
/* stop timer */
rtgui_timer_stop(caret->timer);
}
caret->owner = RT_NULL;
rtgui_dc_destory(caret->dc);
rtgui_timer_destory(caret->timer);
rtgui_free(caret);
}
/* show caret on owner widget logic position */
void rtgui_caret_show(struct rtgui_caret* caret, rt_base_t x, rt_base_t y)
{
if (caret->is_show == RT_TRUE)
{
/* set show flag and stop blink timer */
caret->is_show = RT_FALSE;
rtgui_timer_stop(caret->timer);
}
/* set show x and y */
caret->show_point.x = x;
caret->show_point.y = y;
/* set show flag and start blink timer */
caret->is_show = RT_TRUE;
/* draw caret */
rtgui_caret_draw(caret);
/* start blink timer */
rtgui_timer_start(caret->timer);
}
void rtgui_caret_hide(struct rtgui_caret* caret)
{
RT_ASSERT(caret != RT_NULL);
/* set show flag and stop blink timer */
caret->is_show = RT_FALSE;
rtgui_timer_stop(caret->timer);
/* update owner widget */
if (caret->owner != RT_NULL)
{
rtgui_widget_update(caret->owner);
}
}
void rtgui_caret_set_point(struct rtgui_caret* caret, int x, int y)
{
RT_ASSERT(caret != RT_NULL);
if (caret->is_show == RT_TRUE)
{
/* stop the old caret */
rtgui_timer_stop(caret->timer);
/* update owner widget */
if (caret->owner != RT_NULL && caret->is_show)
{
rtgui_widget_update(caret->owner);
}
}
caret->show_point.x = x;
caret->show_point.y = y;
/* draw caret */
rtgui_caret_draw(caret);
/* start blink timer */
rtgui_timer_start(caret->timer);
}
void rtgui_caret_set_box(struct rtgui_caret* caret, int w, int h)
{
RT_ASSERT(caret != RT_NULL);
caret->extent.x2 = caret->extent.x1 + w;
caret->extent.y2 = caret->extent.y1 + h;
}
void rtgui_caret_draw(struct rtgui_caret* caret)
{
RT_ASSERT(caret != RT_NULL);
if (caret->is_show == RT_TRUE && caret->owner->toplevel != RT_NULL)
{
struct rtgui_rect rect = caret->extent;
struct rtgui_point point = {0, 0};
struct rtgui_dc* hw_dc;
rtgui_rect_moveto(&rect, caret->show_point.x, caret->show_point.y);
hw_dc = rtgui_dc_begin_drawing(caret->owner);
rtgui_dc_blit(caret->dc, &point, hw_dc, &rect);
rtgui_dc_end_drawing(hw_dc);
}
}