add multi-text view widget.
git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1455 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
parent
bbf68d15e5
commit
db9e590b90
|
@ -295,3 +295,13 @@ struct rtgui_image_palette* rtgui_image_palette_create(rt_uint32_t ncolors)
|
|||
|
||||
return palette;
|
||||
}
|
||||
|
||||
void rtgui_image_get_rect(struct rtgui_image* image, struct rtgui_rect* rect)
|
||||
{
|
||||
RT_ASSERT(image != RT_NULL);
|
||||
RT_ASSERT(rect != RT_NULL);
|
||||
|
||||
rect->x1 = 0; rect->y1 = 0;
|
||||
rect->x2 = image->w; rect->y2 = image->h;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,6 +66,9 @@ struct rtgui_image* rtgui_image_create(const char* filename, rt_bool_t load);
|
|||
struct rtgui_image* rtgui_image_create_from_mem(const char* type, const rt_uint8_t* data, rt_size_t length, rt_bool_t load);
|
||||
void rtgui_image_destroy(struct rtgui_image* image);
|
||||
|
||||
/* get image's rect */
|
||||
void rtgui_image_get_rect(struct rtgui_image* image, struct rtgui_rect* rect);
|
||||
|
||||
/* register an image engine */
|
||||
void rtgui_image_register_engine(struct rtgui_image_engine* engine);
|
||||
|
||||
|
@ -74,3 +77,4 @@ void rtgui_image_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtg
|
|||
struct rtgui_image_palette* rtgui_image_palette_create(rt_uint32_t ncolors);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,66 +1,66 @@
|
|||
/*
|
||||
* File : list.h
|
||||
* 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
|
||||
*/
|
||||
#ifndef __RTGUI_LIST_H__
|
||||
#define __RTGUI_LIST_H__
|
||||
|
||||
#include <rtgui/rtgui.h>
|
||||
|
||||
struct rtgui_list_node
|
||||
{
|
||||
struct rtgui_list_node* next;
|
||||
};
|
||||
typedef struct rtgui_list_node rtgui_list_t;
|
||||
|
||||
rt_inline void rtgui_list_init(rtgui_list_t *l)
|
||||
{
|
||||
l->next = (struct rtgui_list_node *)0;
|
||||
}
|
||||
/*
|
||||
* File : list.h
|
||||
* 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
|
||||
*/
|
||||
#ifndef __RTGUI_LIST_H__
|
||||
#define __RTGUI_LIST_H__
|
||||
|
||||
rt_inline void rtgui_list_append(rtgui_list_t *l, rtgui_list_t *n)
|
||||
{
|
||||
struct rtgui_list_node* node;
|
||||
|
||||
node = l;
|
||||
while (node->next) node = node->next;
|
||||
|
||||
/* append the node to the tail */
|
||||
node->next = n;
|
||||
n->next = (struct rtgui_list_node*) 0;
|
||||
}
|
||||
|
||||
rt_inline void rtgui_list_insert(rtgui_list_t *l, rtgui_list_t *n)
|
||||
{
|
||||
n->next = l->next;
|
||||
l->next = n;
|
||||
}
|
||||
|
||||
rt_inline rtgui_list_t* rtgui_list_remove(rtgui_list_t *l, rtgui_list_t *n)
|
||||
{
|
||||
/* remove slist head */
|
||||
struct rtgui_list_node* node = l;
|
||||
while (node->next && node->next != n) node = node->next;
|
||||
|
||||
/* remove node */
|
||||
if (node->next != (rtgui_list_t *)0) node->next = node->next->next;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
#define rtgui_list_entry(node, type, member) \
|
||||
((type *)((char*)(node)-(unsigned long)(&((type *)0)->member)))
|
||||
|
||||
#define rtgui_list_foreach(node, list) \
|
||||
for ((node) = (list)->next; (node) != RT_NULL; (node) = (node)->next)
|
||||
|
||||
#endif
|
||||
#include <rtgui/rtgui.h>
|
||||
|
||||
struct rtgui_list_node
|
||||
{
|
||||
struct rtgui_list_node* next;
|
||||
};
|
||||
typedef struct rtgui_list_node rtgui_list_t;
|
||||
|
||||
rt_inline void rtgui_list_init(rtgui_list_t *l)
|
||||
{
|
||||
l->next = (struct rtgui_list_node *)0;
|
||||
}
|
||||
|
||||
rt_inline void rtgui_list_append(rtgui_list_t *l, rtgui_list_t *n)
|
||||
{
|
||||
struct rtgui_list_node* node;
|
||||
|
||||
node = l;
|
||||
while (node->next) node = node->next;
|
||||
|
||||
/* append the node to the tail */
|
||||
node->next = n;
|
||||
n->next = (struct rtgui_list_node*) 0;
|
||||
}
|
||||
|
||||
rt_inline void rtgui_list_insert(rtgui_list_t *l, rtgui_list_t *n)
|
||||
{
|
||||
n->next = l->next;
|
||||
l->next = n;
|
||||
}
|
||||
|
||||
rt_inline rtgui_list_t* rtgui_list_remove(rtgui_list_t *l, rtgui_list_t *n)
|
||||
{
|
||||
/* remove slist head */
|
||||
struct rtgui_list_node* node = l;
|
||||
while (node->next && node->next != n) node = node->next;
|
||||
|
||||
/* remove node */
|
||||
if (node->next != (rtgui_list_t *)0) node->next = node->next->next;
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
#define rtgui_list_entry(node, type, member) \
|
||||
((type *)((char*)(node)-(unsigned long)(&((type *)0)->member)))
|
||||
|
||||
#define rtgui_list_foreach(node, list) \
|
||||
for ((node) = (list)->next; (node) != RT_NULL; (node) = (node)->next)
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* File : textview.h
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006 - 2011, 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
|
||||
* 2011-03-05 Bernard first version
|
||||
*/
|
||||
#ifndef __RTGUI_TEXTVIEW_H__
|
||||
#define __RTGUI_TEXTVIEW_H__
|
||||
|
||||
#include <rtgui/widgets/widget.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @defgroup rtgui_textview
|
||||
* @{
|
||||
*/
|
||||
|
||||
DECLARE_CLASS_TYPE(textview);
|
||||
|
||||
/** Gets the type of a textview */
|
||||
#define RTGUI_TEXTVIEW_TYPE (RTGUI_TYPE(textview))
|
||||
/** Casts the object to an rtgui_textview */
|
||||
#define RTGUI_TEXTVIEW(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTVIEW_TYPE, rtgui_textview_t))
|
||||
/** Checks if the object is an rtgui_textview */
|
||||
#define RTGUI_IS_TEXTVIEW(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TEXTVIEW_TYPE))
|
||||
|
||||
/*
|
||||
* the textview widget
|
||||
*/
|
||||
struct rtgui_textview
|
||||
{
|
||||
/* inherit from widget */
|
||||
struct rtgui_widget parent;
|
||||
|
||||
rt_uint16_t line_width;
|
||||
rt_uint16_t line_count;
|
||||
|
||||
char* lines;
|
||||
|
||||
rt_int16_t line_current;
|
||||
rt_uint16_t line_page_count;
|
||||
};
|
||||
typedef struct rtgui_textview rtgui_textview_t;
|
||||
|
||||
rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect);
|
||||
void rtgui_textview_destroy(rtgui_textview_t* textview);
|
||||
|
||||
rt_bool_t rtgui_textview_event_handler(struct rtgui_widget* widget, struct rtgui_event* event);
|
||||
void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text);
|
||||
|
||||
/** @} */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -66,11 +66,7 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
|
|||
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_theme_draw_button(btn);
|
||||
rtgui_theme_draw_button(btn);
|
||||
break;
|
||||
|
||||
case RTGUI_EVENT_KBD:
|
||||
|
|
|
@ -95,6 +95,9 @@ void rtgui_label_set_text(rtgui_label_t* label, const char* text)
|
|||
|
||||
if (label->text != RT_NULL)
|
||||
{
|
||||
/* it's a same text string */
|
||||
if (rt_strncmp(text, label->text, rt_strlen(text)) == 0) return;
|
||||
|
||||
/* release old text memory */
|
||||
rt_free(label->text);
|
||||
}
|
||||
|
@ -105,3 +108,4 @@ void rtgui_label_set_text(rtgui_label_t* label, const char* text)
|
|||
/* update widget */
|
||||
rtgui_theme_draw_label(label);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,10 +41,10 @@ DEFINE_CLASS_TYPE(listbox, "listbox",
|
|||
|
||||
void rtgui_listbox_ondraw(struct rtgui_listbox* box)
|
||||
{
|
||||
struct rtgui_rect rect, item_rect;
|
||||
struct rtgui_dc* dc;
|
||||
rt_uint16_t page_index, index;
|
||||
const struct rtgui_listbox_item* item;
|
||||
struct rtgui_rect rect, item_rect, image_rect;
|
||||
|
||||
dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
|
||||
if (dc == RT_NULL) return;
|
||||
|
@ -83,7 +83,10 @@ void rtgui_listbox_ondraw(struct rtgui_listbox* box)
|
|||
|
||||
if (item->image != RT_NULL)
|
||||
{
|
||||
rtgui_image_blit(item->image, dc, &item_rect);
|
||||
rtgui_image_get_rect(item->image, &image_rect);
|
||||
rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
|
||||
|
||||
rtgui_image_blit(item->image, dc, &image_rect);
|
||||
item_rect.x1 += item->image->w + 2;
|
||||
}
|
||||
/* draw text */
|
||||
|
@ -104,7 +107,7 @@ static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t o
|
|||
{
|
||||
struct rtgui_dc* dc;
|
||||
const struct rtgui_listbox_item* item;
|
||||
rtgui_rect_t rect, item_rect;
|
||||
rtgui_rect_t rect, item_rect, image_rect;
|
||||
|
||||
if ((old_item == -1) || (old_item/box->page_items != box->current_item/box->page_items))
|
||||
{
|
||||
|
@ -134,7 +137,10 @@ static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t o
|
|||
item = &(box->items[old_item]);
|
||||
if (item->image != RT_NULL)
|
||||
{
|
||||
rtgui_image_blit(item->image, dc, &item_rect);
|
||||
rtgui_image_get_rect(item->image, &image_rect);
|
||||
rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
|
||||
|
||||
rtgui_image_blit(item->image, dc, &image_rect);
|
||||
item_rect.x1 += item->image->w + 2;
|
||||
}
|
||||
rtgui_dc_draw_text(dc, item->name, &item_rect);
|
||||
|
@ -155,7 +161,10 @@ static void rtgui_listbox_update_current(struct rtgui_listbox* box, rt_int16_t o
|
|||
item = &(box->items[box->current_item]);
|
||||
if (item->image != RT_NULL)
|
||||
{
|
||||
rtgui_image_blit(item->image, dc, &item_rect);
|
||||
rtgui_image_get_rect(item->image, &image_rect);
|
||||
rtgui_rect_moveto_align(&item_rect, &image_rect, RTGUI_ALIGN_CENTER_VERTICAL);
|
||||
|
||||
rtgui_image_blit(item->image, dc, &image_rect);
|
||||
item_rect.x1 += (item->image->w + 2);
|
||||
}
|
||||
rtgui_dc_draw_text(dc, item->name, &item_rect);
|
||||
|
|
|
@ -81,10 +81,18 @@ static void _rtgui_menu_onitem(struct rtgui_widget* widget, struct rtgui_event*
|
|||
}
|
||||
else /* other menu item */
|
||||
{
|
||||
rt_ubase_t index;
|
||||
|
||||
/* invoke action */
|
||||
if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL)
|
||||
menu->items[menu->items_list->current_item].on_menuaction(RTGUI_WIDGET(menu), RT_NULL);
|
||||
|
||||
/* hide all of sub-menu */
|
||||
for (index = 0; index < menu->items_count; index ++)
|
||||
{
|
||||
if (menu->items[index].submenu != RT_NULL)
|
||||
rtgui_menu_hiden(menu->items[index].submenu);
|
||||
}
|
||||
rtgui_menu_hiden(menu);
|
||||
}
|
||||
}
|
||||
|
@ -138,7 +146,7 @@ static void _rtgui_menu_item_ondraw(struct rtgui_listctrl *list, struct rtgui_dc
|
|||
}
|
||||
|
||||
DEFINE_CLASS_TYPE(menu, "menu",
|
||||
RTGUI_WIDGET_TYPE,
|
||||
RTGUI_WIN_TYPE,
|
||||
_rtgui_menu_constructor,
|
||||
_rtgui_menu_destructor,
|
||||
sizeof(struct rtgui_menu));
|
||||
|
@ -170,6 +178,9 @@ static rt_bool_t rtgui_menu_on_deactivate(rtgui_widget_t* widget, rtgui_event_t*
|
|||
menu->on_menuhide(RTGUI_WIDGET(menu), RT_NULL);
|
||||
}
|
||||
|
||||
/* un-select item */
|
||||
menu->items_list->current_item = -1;
|
||||
|
||||
/* if it's a submenu, try to hide parent menu */
|
||||
if (menu->parent_menu != RT_NULL &&
|
||||
rtgui_win_is_activated(RTGUI_WIN(menu->parent_menu)) == RT_FALSE)
|
||||
|
@ -258,7 +269,10 @@ void rtgui_menu_pop(struct rtgui_menu* menu, int x, int y)
|
|||
void rtgui_menu_hiden(struct rtgui_menu* menu)
|
||||
{
|
||||
rtgui_win_hiden(RTGUI_WIN(menu));
|
||||
/* un-select item */
|
||||
menu->items_list->current_item = -1;
|
||||
|
||||
if (menu->parent_menu != RT_NULL)
|
||||
rtgui_menu_hiden(menu->parent_menu);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,7 +72,7 @@ void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *rect)
|
|||
|
||||
/* vertical scroll bar */
|
||||
rect->x1 = scrollbar_rect.x1;
|
||||
rect->x2 = scrollbar_rect.x2;
|
||||
rect->x2 = scrollbar_rect.x2 - 1;
|
||||
rect->y1 = scrollbar_rect.y1 + btn_width + _rtgui_scrollbar_get_thumb_position(bar);
|
||||
rect->y2 = rect->y1 + btn_width;
|
||||
}
|
||||
|
@ -85,7 +85,7 @@ void rtgui_scrollbar_get_thumb_rect(rtgui_scrollbar_t *bar, rtgui_rect_t *rect)
|
|||
rect->x2 = rect->x1 + btn_height;
|
||||
|
||||
rect->y1 = scrollbar_rect.y1;
|
||||
rect->y2 = scrollbar_rect.y2;
|
||||
rect->y2 = scrollbar_rect.y2 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,352 @@
|
|||
/*
|
||||
* File : textview.c
|
||||
* This file is part of RT-Thread RTOS
|
||||
* COPYRIGHT (C) 2006 - 2011, 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
|
||||
* 2011-03-05 Bernard first version
|
||||
*/
|
||||
#include <rtgui/dc.h>
|
||||
#include <rtgui/rtgui_system.h>
|
||||
#include <rtgui/widgets/textview.h>
|
||||
|
||||
rt_inline unsigned char* _get_line_text(rtgui_textview_t *textview, rt_uint16_t index)
|
||||
{
|
||||
unsigned char* line;
|
||||
if (index < textview->line_count)
|
||||
{
|
||||
line = textview->lines + (index * textview->line_width);
|
||||
return line;
|
||||
}
|
||||
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
static void _calc_line(rtgui_textview_t *textview, const char* text)
|
||||
{
|
||||
unsigned char* line;
|
||||
const unsigned char* ptr;
|
||||
rt_ubase_t line_index, line_position;
|
||||
|
||||
if (textview->lines != RT_NULL)
|
||||
{
|
||||
rt_free(textview->lines);
|
||||
textview->lines = RT_NULL;
|
||||
textview->line_count = 0;
|
||||
}
|
||||
|
||||
/* get line count */
|
||||
line_index = 0; line_position = 0;
|
||||
ptr = (const unsigned char*)text;
|
||||
if (*ptr == 0) return;
|
||||
|
||||
while (*ptr != '\0')
|
||||
{
|
||||
if (*ptr == '\n')
|
||||
{
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
}
|
||||
else if (*ptr == '\r')
|
||||
{
|
||||
ptr ++;
|
||||
continue;
|
||||
}
|
||||
else if (*ptr == '\t')
|
||||
{
|
||||
line_position += 4;
|
||||
if (line_position >= textview->line_width - 1)
|
||||
{
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*ptr) >= 0x80)
|
||||
{
|
||||
/* fill cjk character */
|
||||
if (line_position + 1 >= (textview->line_width - 1))
|
||||
{
|
||||
/* split to next line */
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
}
|
||||
|
||||
line_position ++;
|
||||
line_position ++;
|
||||
}
|
||||
else
|
||||
{
|
||||
line_position ++;
|
||||
}
|
||||
|
||||
if (line_position >= textview->line_width - 1)
|
||||
{
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ptr ++;
|
||||
}
|
||||
|
||||
/* set line count */
|
||||
textview->line_count = line_index + 1;
|
||||
|
||||
/* allocate lines */
|
||||
textview->lines = rt_malloc(textview->line_count * textview->line_width);
|
||||
rt_memset(textview->lines, 0, (textview->line_count * textview->line_width));
|
||||
|
||||
/* fill lines */
|
||||
line_index = 0; line_position = 0;
|
||||
ptr = (const unsigned char*)text;
|
||||
line = _get_line_text(textview, line_index);
|
||||
while (*ptr)
|
||||
{
|
||||
if (*ptr == '\n')
|
||||
{
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
line = _get_line_text(textview, line_index);
|
||||
}
|
||||
else if (*ptr == '\r')
|
||||
{
|
||||
/* ignore '\r' */
|
||||
ptr ++;
|
||||
continue;
|
||||
}
|
||||
else if (*ptr == '\t')
|
||||
{
|
||||
line[line_position++] = ' ';
|
||||
line[line_position++] = ' ';
|
||||
line[line_position++] = ' ';
|
||||
line[line_position++] = ' ';
|
||||
if (line_position >= textview->line_width - 1)
|
||||
{
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
line = _get_line_text(textview, line_index);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((*ptr) >= 0x80)
|
||||
{
|
||||
/* fill cjk character */
|
||||
if (line_position + 1 >= (textview->line_width - 1))
|
||||
{
|
||||
/* split to next line */
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
line = _get_line_text(textview, line_index);
|
||||
}
|
||||
|
||||
line[line_position ++] = *ptr ++;
|
||||
line[line_position ++] = *ptr;
|
||||
}
|
||||
else
|
||||
{
|
||||
line[line_position ++] = *ptr;
|
||||
}
|
||||
|
||||
if (line_position >= textview->line_width - 1)
|
||||
{
|
||||
line_index ++;
|
||||
line_position = 0;
|
||||
line = _get_line_text(textview, line_index);
|
||||
}
|
||||
}
|
||||
|
||||
ptr ++;
|
||||
}
|
||||
|
||||
textview->line_current = 0;
|
||||
}
|
||||
|
||||
static void _calc_width(rtgui_textview_t *textview)
|
||||
{
|
||||
rtgui_rect_t rect;
|
||||
rt_uint16_t width, height;
|
||||
|
||||
width = rtgui_rect_width(RTGUI_WIDGET(textview)->extent) - 6;
|
||||
height = rtgui_rect_height(RTGUI_WIDGET(textview)->extent);
|
||||
|
||||
rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &rect);
|
||||
textview->line_width = width / rtgui_rect_width(rect) + 1;
|
||||
textview->line_page_count = height / (rtgui_rect_height(rect) + 3);
|
||||
|
||||
/* set minimal value */
|
||||
if (textview->line_page_count == 0) textview->line_page_count = 1;
|
||||
}
|
||||
|
||||
static void _draw_textview(rtgui_textview_t *textview)
|
||||
{
|
||||
struct rtgui_dc* dc;
|
||||
struct rtgui_rect rect, font_rect;
|
||||
char* line;
|
||||
rt_ubase_t line_index, item_height;
|
||||
|
||||
rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(textview)), "W", &font_rect);
|
||||
item_height = rtgui_rect_height(font_rect) + 3;
|
||||
|
||||
dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(textview));
|
||||
if (dc == RT_NULL) return ;
|
||||
|
||||
/* fill rect */
|
||||
rtgui_widget_get_rect(RTGUI_WIDGET(textview), &rect);
|
||||
rtgui_dc_fill_rect(dc, &rect);
|
||||
|
||||
rect.x1 += 3;
|
||||
rect.x2 -= 3;
|
||||
|
||||
for (line_index = textview->line_current;
|
||||
(line_index < textview->line_current + textview->line_page_count) &&
|
||||
(line_index < textview->line_count);
|
||||
line_index ++)
|
||||
{
|
||||
line = (char* )_get_line_text(textview, line_index);
|
||||
rtgui_dc_draw_text(dc, line, &rect);
|
||||
|
||||
rect.y1 += item_height;
|
||||
}
|
||||
|
||||
rtgui_dc_end_drawing(dc);
|
||||
}
|
||||
|
||||
static void _rtgui_textview_constructor(rtgui_textview_t *textview)
|
||||
{
|
||||
/* init widget and set event handler */
|
||||
rtgui_widget_set_event_handler(RTGUI_WIDGET(textview), rtgui_textview_event_handler);
|
||||
RTGUI_WIDGET(textview)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
|
||||
|
||||
/* set field */
|
||||
textview->line_count = 0;
|
||||
textview->lines = RT_NULL;
|
||||
|
||||
textview->line_current = -1;
|
||||
textview->line_page_count = 1;
|
||||
}
|
||||
|
||||
static void _rtgui_textview_destructor(rtgui_textview_t *textview)
|
||||
{
|
||||
/* release line memory */
|
||||
rt_free(textview->lines);
|
||||
textview->lines = RT_NULL;
|
||||
}
|
||||
|
||||
DEFINE_CLASS_TYPE(textview, "textview",
|
||||
RTGUI_WIDGET_TYPE,
|
||||
_rtgui_textview_constructor,
|
||||
_rtgui_textview_destructor,
|
||||
sizeof(struct rtgui_textview));
|
||||
|
||||
rt_bool_t rtgui_textview_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
|
||||
{
|
||||
struct rtgui_textview* textview;
|
||||
|
||||
RT_ASSERT(widget != RT_NULL);
|
||||
|
||||
textview = (struct rtgui_textview*) widget;
|
||||
switch (event->type)
|
||||
{
|
||||
case RTGUI_EVENT_PAINT:
|
||||
_draw_textview(textview);
|
||||
break;
|
||||
|
||||
case RTGUI_EVENT_KBD:
|
||||
{
|
||||
struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
|
||||
if (ekbd->type == RTGUI_KEYDOWN)
|
||||
{
|
||||
rt_int16_t line_current_update;
|
||||
line_current_update = textview->line_current;
|
||||
if (ekbd->key == RTGUIK_LEFT)
|
||||
{
|
||||
if (textview->line_current > textview->line_page_count)
|
||||
{
|
||||
line_current_update -= textview->line_page_count;
|
||||
}
|
||||
else if (textview->line_current > 0)
|
||||
{
|
||||
line_current_update = 0;
|
||||
}
|
||||
}
|
||||
else if (ekbd->key == RTGUIK_RIGHT)
|
||||
{
|
||||
if (textview->line_current + textview->line_page_count < textview->line_count - 1)
|
||||
{
|
||||
line_current_update += textview->line_page_count;
|
||||
}
|
||||
}
|
||||
else if (ekbd->key == RTGUIK_UP)
|
||||
{
|
||||
if (textview->line_current > 0)
|
||||
{
|
||||
line_current_update --;
|
||||
}
|
||||
}
|
||||
else if (ekbd->key == RTGUIK_DOWN)
|
||||
{
|
||||
if (textview->line_current + textview->line_page_count < textview->line_count - 1)
|
||||
{
|
||||
line_current_update ++;
|
||||
}
|
||||
}
|
||||
|
||||
if (textview->line_current != line_current_update)
|
||||
{
|
||||
textview->line_current = line_current_update;
|
||||
rtgui_widget_update(widget);
|
||||
return RT_TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return RT_FALSE;
|
||||
}
|
||||
|
||||
rtgui_textview_t* rtgui_textview_create(const char* text, const rtgui_rect_t *rect)
|
||||
{
|
||||
struct rtgui_textview* textview;
|
||||
|
||||
textview = (struct rtgui_textview*) rtgui_widget_create(RTGUI_TEXTVIEW_TYPE);
|
||||
if (textview != RT_NULL)
|
||||
{
|
||||
rtgui_widget_set_rect(RTGUI_WIDGET(textview), rect);
|
||||
|
||||
/* calculate line width and line page count */
|
||||
_calc_width(textview);
|
||||
|
||||
/* set text */
|
||||
_calc_line(textview, text);
|
||||
}
|
||||
|
||||
return textview;
|
||||
}
|
||||
|
||||
void rtgui_textview_destroy(rtgui_textview_t* textview)
|
||||
{
|
||||
rtgui_widget_destroy(RTGUI_WIDGET(textview));
|
||||
}
|
||||
|
||||
void rtgui_textview_set_text(rtgui_textview_t* textview, const char* text)
|
||||
{
|
||||
RT_ASSERT(textview != RT_NULL);
|
||||
|
||||
/* calculate line width and line page count */
|
||||
_calc_width(textview);
|
||||
|
||||
/* set text */
|
||||
_calc_line(textview, text);
|
||||
|
||||
/* update widget */
|
||||
rtgui_widget_update(RTGUI_WIDGET(textview));
|
||||
}
|
Loading…
Reference in New Issue