sync with RTGUI c074ff2898b9e

Full log is in GitHub.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@2222 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
chaos.proton@gmail.com 2012-07-20 12:37:56 +00:00
parent c2868be90d
commit 92a50c838d
78 changed files with 3650 additions and 2263 deletions

View File

@ -9,6 +9,7 @@ common/rtgui_object.c
common/rtgui_system.c common/rtgui_system.c
common/rtgui_theme.c common/rtgui_theme.c
common/rtgui_xml.c common/rtgui_xml.c
common/rtgui_app.c
common/dc.c common/dc.c
common/dc_hw.c common/dc_hw.c
common/dc_buffer.c common/dc_buffer.c
@ -34,7 +35,6 @@ common/pixel_driver.c
""") """)
server_src = Split(""" server_src = Split("""
server/rtgui_application.c
server/driver.c server/driver.c
server/mouse.c server/mouse.c
server/server.c server/server.c
@ -63,10 +63,10 @@ widgets/toplevel.c
widgets/notebook.c widgets/notebook.c
widgets/container.c widgets/container.c
widgets/list_view.c widgets/list_view.c
widgets/about_view.c
widgets/filelist_view.c widgets/filelist_view.c
widgets/widget.c widgets/widget.c
widgets/window.c widgets/window.c
widgets/panel.c
""") """)
# The set of source files associated with this SConscript file. # The set of source files associated with this SConscript file.

View File

@ -1,3 +1,9 @@
/*
* Change Logs:
* Date Author Notes
* 2012-01-24 onelife add one more blit table which exchanges the
* positions of R and B color components in output
*/
#include <rtgui/rtgui.h> #include <rtgui/rtgui.h>
#include <rtgui/blit.h> #include <rtgui/blit.h>
@ -305,3 +311,63 @@ rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp)
return _blit_table[dst_bpp][src_bpp]; return _blit_table[dst_bpp][src_bpp];
} }
static void rtgui_blit_line_3_2_inv(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_uint16_t* dst;
dst = (rt_uint16_t*)dst_ptr;
line = line / 3;
while (line)
{
*dst = (((*src_ptr << 8) & 0x0000F800) |
((*(src_ptr + 1) << 3) & 0x000007E0) |
((*(src_ptr + 2) >> 3) & 0x0000001F));
src_ptr += 3;
dst ++;
line --;
}
return;
}
void rtgui_blit_line_2_2_inv(rt_uint8_t* dst_ptr, rt_uint8_t* src_ptr, int line)
{
rt_uint16_t *dst, *src;
dst = (rt_uint16_t *)dst_ptr;
src = (rt_uint16_t *)src_ptr;
line = line / 2;
while (line)
{
*dst = ((*src << 11) & 0xF800) | (*src & 0x07E0) | ((*src >> 11) & 0x001F);
src ++;
dst ++;
line --;
}
}
static const rtgui_blit_line_func _blit_table_inv[5][5] =
{
/* 0_0, 1_0, 2_0, 3_0, 4_0 */
{RT_NULL, RT_NULL, RT_NULL, RT_NULL, RT_NULL },
/* 0_1, 1_1, 2_1, 3_1, 4_1 */
{RT_NULL, rtgui_blit_line_direct, rtgui_blit_line_2_1, rtgui_blit_line_3_1, rtgui_blit_line_4_1 },
/* 0_2, 1_2, 2_2, 3_2, 4_2 */
{RT_NULL, rtgui_blit_line_1_2, rtgui_blit_line_2_2_inv, rtgui_blit_line_3_2_inv, rtgui_blit_line_4_2 },
/* 0_3, 1_3, 2_3, 3_3, 4_3 */
{RT_NULL, rtgui_blit_line_1_3, rtgui_blit_line_2_3, rtgui_blit_line_direct, rtgui_blit_line_4_3 },
/* 0_4, 1_4, 2_4, 3_4, 4_4 */
{RT_NULL, rtgui_blit_line_1_4, rtgui_blit_line_2_4, rtgui_blit_line_3_4, rtgui_blit_line_direct },
};
rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp)
{
RT_ASSERT(dst_bpp>0 && dst_bpp < 5);
RT_ASSERT(src_bpp>0 && src_bpp < 5);
return _blit_table_inv[dst_bpp][src_bpp];
}

View File

@ -138,12 +138,12 @@ void rtgui_dc_draw_vertical_line(struct rtgui_dc* dc, int x, int y1, int y2)
color = RTGUI_DC_FC(dc); color = RTGUI_DC_FC(dc);
RTGUI_DC_FC(dc) = dark_grey; RTGUI_DC_FC(dc) = dark_grey;
rtgui_dc_draw_hline(dc, x, y1, y2); rtgui_dc_draw_vline(dc, x, y1, y2);
x ++; x ++;
RTGUI_DC_FC(dc) = high_light; RTGUI_DC_FC(dc) = high_light;
rtgui_dc_draw_hline(dc, x, y1, y2); rtgui_dc_draw_vline(dc, x, y1, y2);
/* restore color */ /* restore color */
RTGUI_DC_FC(dc) = color; RTGUI_DC_FC(dc) = color;

View File

@ -21,7 +21,7 @@
#include <rtgui/driver.h> #include <rtgui/driver.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/rtgui_server.h> #include <rtgui/rtgui_server.h>
#include <rtgui/widgets/container.h> #include <rtgui/widgets/container.h>
#include <rtgui/widgets/window.h> #include <rtgui/widgets/window.h>
@ -139,7 +139,7 @@ struct rtgui_dc* rtgui_dc_client_create(rtgui_widget_t* owner)
#endif #endif
} }
} }
else if (RTGUI_IS_APPLICATION(owner->toplevel)) else if (RTGUI_IS_APP(owner->toplevel))
{ {
RT_ASSERT(0); RT_ASSERT(0);
} }
@ -207,7 +207,7 @@ static rt_bool_t rtgui_dc_client_fini(struct rtgui_dc* dc)
#endif #endif
} }
} }
else if (RTGUI_IS_APPLICATION(owner->toplevel) || else if (RTGUI_IS_APP(owner->toplevel) ||
RTGUI_IS_WIN(owner->toplevel)) RTGUI_IS_WIN(owner->toplevel))
{ {
rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel); rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);

View File

@ -15,7 +15,7 @@
#include <rtgui/dc_hw.h> #include <rtgui/dc_hw.h>
#include <rtgui/driver.h> #include <rtgui/driver.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/rtgui_server.h> #include <rtgui/rtgui_server.h>
#include <rtgui/widgets/container.h> #include <rtgui/widgets/container.h>
@ -117,7 +117,7 @@ struct rtgui_dc* rtgui_dc_hw_create(rtgui_widget_t* owner)
#endif #endif
} }
} }
else if (RTGUI_IS_APPLICATION(owner->toplevel) || else if (RTGUI_IS_APP(owner->toplevel) ||
RTGUI_IS_WIN(owner->toplevel)) RTGUI_IS_WIN(owner->toplevel))
{ {
rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel); rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);
@ -184,7 +184,7 @@ static rt_bool_t rtgui_dc_hw_fini(struct rtgui_dc* dc)
#endif #endif
} }
} }
else if (RTGUI_IS_APPLICATION(owner->toplevel) || else if (RTGUI_IS_APP(owner->toplevel) ||
RTGUI_IS_WIN(owner->toplevel)) RTGUI_IS_WIN(owner->toplevel))
{ {
rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel); rtgui_toplevel_t* top = RTGUI_TOPLEVEL(owner->toplevel);

View File

@ -1,3 +1,8 @@
/*
* Change Logs:
* Date Author Notes
* 2012-01-24 onelife fix a bug in framebuffer_draw_raw_hline
*/
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/driver.h> #include <rtgui/driver.h>
@ -108,7 +113,7 @@ static void framebuffer_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y
rt_uint8_t *dst; rt_uint8_t *dst;
dst = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint8_t); dst = GET_PIXEL(rtgui_graphic_get_device(), x1, y, rt_uint8_t);
rt_memcpy(dst, pixels, (x2 - x1) * (rtgui_graphic_get_device()->bits_per_pixel/8)); rt_memcpy(dst, pixels, (x2 - x1 + 1) * (rtgui_graphic_get_device()->bits_per_pixel/8));
} }
const struct rtgui_graphic_driver_ops _framebuffer_rgb565_ops = const struct rtgui_graphic_driver_ops _framebuffer_rgb565_ops =

View File

@ -10,6 +10,7 @@
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2009-10-16 Bernard first version * 2009-10-16 Bernard first version
* 2012-01-24 onelife add TJpgDec (Tiny JPEG Decompressor) support
*/ */
#include <rtthread.h> #include <rtthread.h>
#include <rtgui/image.h> #include <rtgui/image.h>
@ -27,7 +28,7 @@
#ifdef RTGUI_IMAGE_BMP #ifdef RTGUI_IMAGE_BMP
#include <rtgui/image_bmp.h> #include <rtgui/image_bmp.h>
#endif #endif
#ifdef RTGUI_IMAGE_JPEG #if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD))
#include <rtgui/image_jpeg.h> #include <rtgui/image_jpeg.h>
#endif #endif
#ifdef RTGUI_IMAGE_PNG #ifdef RTGUI_IMAGE_PNG
@ -50,7 +51,7 @@ void rtgui_system_image_init(void)
rtgui_image_bmp_init(); rtgui_image_bmp_init();
#endif #endif
#ifdef RTGUI_IMAGE_JPEG #if (defined(RTGUI_IMAGE_JPEG) || defined(RTGUI_IMAGE_TJPGD))
rtgui_image_jpeg_init(); rtgui_image_jpeg_init();
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,8 @@
/*
* Change Logs:
* Date Author Notes
* 2012-01-24 onelife add TJpgDec (Tiny JPEG Decompressor) support
*/
#include <rtthread.h> #include <rtthread.h>
#include <rtgui/rtgui.h> #include <rtgui/rtgui.h>
@ -494,3 +499,477 @@ static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file)
} }
#endif #endif
#if defined(RTGUI_IMAGE_TJPGD)
/***************************************************************************//**
* @file image_jpg.c
* @brief JPEG decoder using TJpgDec module (elm-chan.org)
* COPYRIGHT (C) 2012, RT-Thread Development Team
* @author onelife
* @version 1.0
*******************************************************************************
* @section License
* 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
*******************************************************************************
* @section Change Logs
* Date Author Notes
* 2012-01-24 onelife Initial creation for limited memory devices
******************************************************************************/
/***************************************************************************//**
* @addtogroup TJpgDec
* @{
******************************************************************************/
/* Includes ------------------------------------------------------------------*/
#include "tjpgd.h"
#include <rtgui/rtgui_system.h>
#include <rtgui/filerw.h>
#include <rtgui/blit.h>
#include <rtgui/image_jpeg.h>
#ifdef RTGUI_USING_DFS_FILERW
#include <dfs_posix.h>
#endif
/* Private typedef -----------------------------------------------------------*/
struct rtgui_image_jpeg
{
struct rtgui_filerw* filerw;
struct rtgui_dc *dc;
rt_uint16_t dst_x, dst_y;
rt_uint16_t dst_w, dst_h;
rt_bool_t is_loaded;
rt_bool_t to_buffer;
rt_uint8_t scale;
rt_uint8_t byte_per_pixel;
JDEC tjpgd; /* jpeg structure */
void *pool;
rt_uint8_t *pixels;
};
/* Private define ------------------------------------------------------------*/
#define TJPGD_WORKING_BUFFER_SIZE (3100)
#define TJPGD_MAX_MCU_WIDTH_ON_DISP (2 * 8 * 4) /* Y component: 2x2; Display: 4-byte per pixel */
#define TJPGD_MAX_SCALING_FACTOR (3)
#define hw_driver (rtgui_graphic_driver_get_default())
/* Private macro -------------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file,
rt_uint16_t *width, rt_uint16_t *height);
static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image,
struct rtgui_filerw* file, rt_uint8_t scale, rt_bool_t load); */
static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file);
static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load);
static void rtgui_image_jpeg_unload(struct rtgui_image* image);
static void rtgui_image_jpeg_blit(struct rtgui_image* image,
struct rtgui_dc* dc, struct rtgui_rect* dst_rect);
/* Private variables ---------------------------------------------------------*/
struct rtgui_image_engine rtgui_image_jpeg_engine =
{
"jpeg",
{RT_NULL},
rtgui_image_jpeg_check,
rtgui_image_jpeg_load,
rtgui_image_jpeg_unload,
rtgui_image_jpeg_blit
};
struct rtgui_image_engine rtgui_image_jpg_engine =
{
"jpg",
{RT_NULL},
rtgui_image_jpeg_check,
rtgui_image_jpeg_load,
rtgui_image_jpeg_unload,
rtgui_image_jpeg_blit
};
/* Private functions ---------------------------------------------------------*/
void rtgui_image_jpeg_init()
{
/* register jpeg on image system */
rtgui_image_register_engine(&rtgui_image_jpeg_engine);
/* register jpg on image system */
rtgui_image_register_engine(&rtgui_image_jpg_engine);
}
static UINT tjpgd_in_func(JDEC *jdec, BYTE *buff, UINT ndata)
{
struct rtgui_filerw *file = *(struct rtgui_filerw **)jdec->device;
if (buff == RT_NULL)
{
return rtgui_filerw_seek(file, ndata, RTGUI_FILE_SEEK_CUR);
}
return rtgui_filerw_read(file, (void *)buff, 1, ndata);
}
static UINT tjpgd_out_func(JDEC *jdec, void *bitmap, JRECT *rect)
{
struct rtgui_image_jpeg *jpeg = (struct rtgui_image_jpeg *)jdec->device;
rt_uint16_t w, h, y;
rt_uint16_t rectWidth; /* Width of source rectangular (bytes) */
rt_uint8_t *src, *dst;
/* Put progress indicator */
if (rect->left == 0)
{
rt_kprintf("\r%lu%%", (rect->top << jpeg->scale) * 100UL / jdec->height);
}
/* Copy the decompressed RGB rectanglar to the frame buffer */
rectWidth = (rect->right - rect->left + 1) * jpeg->byte_per_pixel;
src = (rt_uint8_t *)bitmap;
if (jpeg->to_buffer)
{
rt_uint16_t imageWidth; /* Width of image (bytes) */
imageWidth = (jdec->width >> jdec->scale) * jpeg->byte_per_pixel;
dst = jpeg->pixels + rect->top * imageWidth + rect->left * jpeg->byte_per_pixel;
/* Left-top of destination rectangular */
for (h = rect->top; h <= rect->bottom; h++)
{
rt_memcpy(dst, src, rectWidth);
src += rectWidth;
dst += imageWidth; /* Next line */
}
}
else
{
rtgui_blit_line_func blit_line = RT_NULL;
w = rect->right < jpeg->dst_w ? rect->right : jpeg->dst_w;
w = w - rect->left + 1;
h = rect->bottom < jpeg->dst_h ? rect->bottom : jpeg->dst_h;
h = h - rect->top + 1;
if (jpeg->byte_per_pixel == hw_driver->bits_per_pixel / 8)
{
if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
{
blit_line = rtgui_blit_line_get_inv(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel);
}
}
else
{
blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel);
}
if (blit_line)
{
rt_uint8_t line_buf[TJPGD_MAX_MCU_WIDTH_ON_DISP];
for (y = 0; y < h; y++)
{
blit_line(line_buf, src, w * jpeg->byte_per_pixel);
jpeg->dc->engine->blit_line(jpeg->dc,
jpeg->dst_x + rect->left, jpeg->dst_x + rect->left + w - 1,
jpeg->dst_y + rect->top + y,
line_buf);
src += rectWidth;
}
}
else
{
for (y = 0; y < h; y++)
{
jpeg->dc->engine->blit_line(jpeg->dc,
jpeg->dst_x + rect->left, jpeg->dst_x + rect->left + w - 1,
jpeg->dst_y + rect->top + y,
src);
src += rectWidth;
}
}
}
return 1; /* Continue to decompress */
}
static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file)
//static rt_bool_t rtgui_image_jpeg_check(struct rtgui_filerw* file,
// rt_uint32_t *width, rt_uint32_t *height)
{
rt_bool_t is_JPG;
JDEC tjpgd;
void *pool;
is_JPG = RT_FALSE;
do
{
if (!file )
{
break;
}
pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE);
if (pool == RT_NULL)
{
rt_kprintf("TJPGD err: no mem\n");
break;
}
if (rtgui_filerw_seek(file, 0, SEEK_SET) == -1)
{
break;
}
if (jd_prepare(&tjpgd, tjpgd_in_func, pool,
TJPGD_WORKING_BUFFER_SIZE, (void *)&file) == JDR_OK)
{
// *width = (rt_uint32_t)tjpgd.width;
// *height = (rt_uint32_t)tjpgd.height;
is_JPG = RT_TRUE;
}
rt_kprintf("TJPGD: check OK\n");
} while(0);
rt_free(pool);
return is_JPG;
}
static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image, struct rtgui_filerw* file, rt_bool_t load)
//static rt_bool_t rtgui_image_jpeg_load(struct rtgui_image* image,
// struct rtgui_filerw* file, rt_uint8_t scale, rt_bool_t load)
{
rt_uint8_t scale = 2;
rt_bool_t res = RT_FALSE;
struct rtgui_image_jpeg *jpeg;
JRESULT ret;
if (scale > TJPGD_MAX_SCALING_FACTOR)
{
return RT_FALSE;
}
do
{
jpeg = (struct rtgui_image_jpeg *)rt_malloc(sizeof(struct rtgui_image_jpeg));
if (jpeg == RT_NULL)
{
break;
}
jpeg->filerw = file;
jpeg->is_loaded = RT_FALSE;
jpeg->to_buffer = load;
jpeg->scale = scale;
#if (JD_FORMAT == 0)
jpeg->byte_per_pixel = 3;
#elif (JD_FORMAT == 1)
jpeg->byte_per_pixel = 2;
#endif
jpeg->pool = RT_NULL;
jpeg->pixels = RT_NULL;
jpeg->pool = rt_malloc(TJPGD_WORKING_BUFFER_SIZE);
if (jpeg->pool == RT_NULL)
{
rt_kprintf("TJPGD err: no mem (%d)\n", TJPGD_WORKING_BUFFER_SIZE);
break;
}
if (rtgui_filerw_seek(jpeg->filerw, 0, SEEK_SET) == -1)
{
break;
}
ret = jd_prepare(&jpeg->tjpgd, tjpgd_in_func, jpeg->pool,
TJPGD_WORKING_BUFFER_SIZE, (void *)jpeg);
if (ret != JDR_OK)
{
if (ret == JDR_FMT3)
{
rt_kprintf("TJPGD: not supported format\n");
}
break;
}
rt_kprintf("TJPGD: prepare OK\n");
image->w = (rt_uint16_t)jpeg->tjpgd.width >> jpeg->scale;
image->h = (rt_uint16_t)jpeg->tjpgd.height >> jpeg->scale;
/* set image private data and engine */
image->data = jpeg;
image->engine = &rtgui_image_jpeg_engine;
if (jpeg->to_buffer == RT_TRUE)
{
jpeg->pixels = (rt_uint8_t *)rtgui_malloc(
jpeg->byte_per_pixel * image->w * image->h);
if (jpeg->pixels == RT_NULL)
{
rt_kprintf("TJPGD err: no mem to load (%d)\n",
jpeg->byte_per_pixel * image->w * image->h);
break;
}
ret = jd_decomp(&jpeg->tjpgd, tjpgd_out_func, jpeg->scale);
if (ret != JDR_OK)
{
break;
}
rtgui_filerw_close(jpeg->filerw);
jpeg->is_loaded = RT_TRUE;
rt_kprintf("TJPGD: load to RAM\n");
}
res = RT_TRUE;
} while(0);
if (!res || jpeg->is_loaded)
{
rt_free(jpeg->pool);
}
if (!res)
{
rtgui_free(jpeg->pixels);
rt_free(jpeg);
}
/* create jpeg image successful */
return res;
}
static void rtgui_image_jpeg_unload(struct rtgui_image* image)
{
if (image != RT_NULL)
{
struct rtgui_image_jpeg* jpeg;
jpeg = (struct rtgui_image_jpeg*) image->data;
RT_ASSERT(jpeg != RT_NULL);
if (jpeg->to_buffer == RT_TRUE)
{
if (jpeg->is_loaded == RT_TRUE)
{
rtgui_free(jpeg->pixels);
}
if (jpeg->is_loaded != RT_TRUE)
{
rtgui_filerw_close(jpeg->filerw);
}
}
else
{
rt_free(jpeg->pool);
rtgui_filerw_close(jpeg->filerw);
}
rt_free(jpeg);
}
rt_kprintf("TJPGD: unload\n");
}
static void rtgui_image_jpeg_blit(struct rtgui_image* image,
struct rtgui_dc* dc, struct rtgui_rect* dst_rect)
{
rt_uint16_t w, h, y;
struct rtgui_image_jpeg *jpeg;
jpeg = (struct rtgui_image_jpeg *) image->data;
RT_ASSERT(image != RT_NULL || dc != RT_NULL || dst_rect != RT_NULL || jpeg != RT_NULL);
do
{
/* this dc is not visible */
if (rtgui_dc_get_visible(dc) != RT_TRUE)
{
break;
}
jpeg->dc= dc;
/* the minimum rect */
if (image->w < rtgui_rect_width(*dst_rect))
{
w = image->w;
}
else
{
w = rtgui_rect_width(*dst_rect);
}
if (image->h < rtgui_rect_height(*dst_rect))
{
h = image->h;
}
else
{
h = rtgui_rect_height(*dst_rect);
}
if (!jpeg->is_loaded)
{
JRESULT ret;
jpeg->dst_x = dst_rect->x1;
jpeg->dst_y = dst_rect->y1;
jpeg->dst_w = w;
jpeg->dst_h = h;
ret = jd_decomp(&jpeg->tjpgd, tjpgd_out_func, jpeg->scale);
if (ret != JDR_OK)
{
break;
}
rt_kprintf("TJPGD: load to display\n");
}
else
{
rt_uint8_t* src = jpeg->pixels;
rt_uint16_t imageWidth = image->w * jpeg->byte_per_pixel;
rtgui_blit_line_func blit_line = RT_NULL;
if (jpeg->byte_per_pixel == hw_driver->bits_per_pixel / 8)
{
if (hw_driver->pixel_format == RTGRAPHIC_PIXEL_FORMAT_RGB565)
{
blit_line = rtgui_blit_line_get_inv(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel);
}
}
else
{
blit_line = rtgui_blit_line_get(hw_driver->bits_per_pixel / 8, jpeg->byte_per_pixel);
}
if (blit_line)
{
rt_uint16_t x;
rt_uint8_t temp[4];
for (y = 0; y < h; y++)
{
for (x = 0; x < w; x++)
{
blit_line(temp, src, jpeg->byte_per_pixel);
src += jpeg->byte_per_pixel;
dc->engine->blit_line(dc,
dst_rect->x1 + x, dst_rect->x1 + x,
dst_rect->y1 + y,
temp);
}
}
}
else
{
for (y = 0; y < h; y++)
{
dc->engine->blit_line(dc,
dst_rect->x1, dst_rect->x1 + w - 1,
dst_rect->y1 + y,
src);
src += imageWidth;
}
}
}
} while(0);
}
#endif /* defined(RTGUI_IMAGE_TJPGD) */
/***************************************************************************//**
* @}
******************************************************************************/

View File

@ -242,9 +242,16 @@ static void rtgui_image_png_unload(struct rtgui_image* image)
static void rtgui_image_png_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect) static void rtgui_image_png_blit(struct rtgui_image* image, struct rtgui_dc* dc, struct rtgui_rect* rect)
{ {
struct rtgui_graphic_driver* hwdev = rtgui_graphic_get_device();
rt_uint16_t x, y, w, h; rt_uint16_t x, y, w, h;
rtgui_color_t* ptr; rtgui_color_t* ptr;
struct rtgui_image_png* png; struct rtgui_image_png* png;
int fg_maxsample;
int ialpha;
float alpha;
rtgui_color_t color;
rtgui_color_t c, bgcolor;
int fc[3], bc[3];
RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL); RT_ASSERT(image != RT_NULL && dc != RT_NULL && rect != RT_NULL);
RT_ASSERT(image->data != RT_NULL); RT_ASSERT(image->data != RT_NULL);
@ -255,21 +262,56 @@ static void rtgui_image_png_blit(struct rtgui_image* image, struct rtgui_dc* dc,
else w = rtgui_rect_width(*rect); else w = rtgui_rect_width(*rect);
if (image->h < rtgui_rect_height(*rect)) h = image->h; if (image->h < rtgui_rect_height(*rect)) h = image->h;
else h = rtgui_rect_height(*rect); else h = rtgui_rect_height(*rect);
fg_maxsample = (1 << png->info_ptr->bit_depth) - 1;
if (png->pixels != RT_NULL) if (png->pixels != RT_NULL)
{ {
ptr = (rtgui_color_t*)png->pixels; ptr = (rtgui_color_t*)png->pixels;
/* draw each point within dc */ bgcolor = rtgui_color_from_565(RTGUI_DC_BC(dc));
bc[0] = RTGUI_RGB_R(bgcolor);
bc[1] = RTGUI_RGB_G(bgcolor);
bc[2] = RTGUI_RGB_B(bgcolor);
/* draw each point within dc */
for (y = 0; y < h; y ++) for (y = 0; y < h; y ++)
{ {
for (x = 0; x < w; x++) for (x = 0; x < w; x++)
{ {
/* not alpha */ c = *ptr;
if ((*ptr >> 24) != 255) ialpha = RTGUI_RGB_A(c);
{ if(ialpha == 0)
rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, *ptr); {
} /*
* Foreground image is transparent hear.
* If the background image is already in the frame
* buffer, there is nothing to do.
*/
}
else if (ialpha == fg_maxsample)
{
/*
* Copy foreground pixel to frame buffer.
*/
rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, c);
}
else
{ /* output = alpha * foreground + (1-alpha) * background */
/*
* Compositing is necessary.
* Get floating-point alpha and its complement.
* Note: alpha is always linear: gamma does not
* affect it.
*/
fc[0] = RTGUI_RGB_R(c);
fc[1] = RTGUI_RGB_G(c);
fc[2] = RTGUI_RGB_B(c);
alpha = (float) ialpha / fg_maxsample;
color = RTGUI_RGB( (rt_uint8_t)(fc[0]*alpha + bc[0]*(1-alpha)),
(rt_uint8_t)(fc[1]*alpha + bc[1]*(1-alpha)),
(rt_uint8_t)(fc[2]*alpha + bc[2]*(1-alpha)));
rtgui_dc_draw_color_point(dc, x + rect->x1, y + rect->y1, color);
}
/* move to next color buffer */ /* move to next color buffer */
ptr ++; ptr ++;
} }

View File

@ -1,9 +1,23 @@
/*
* Change Logs:
* Date Author Notes
* 2012-01-24 onelife add mono color support
* 2012-01-24 onelife fix a bug in _pixel_draw_raw_hline
*/
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/driver.h> #include <rtgui/driver.h>
#define gfx_device (rtgui_graphic_get_device()->device) #define gfx_device (rtgui_graphic_get_device()->device)
#define gfx_device_ops rt_graphix_ops(gfx_device) #define gfx_device_ops rt_graphix_ops(gfx_device)
static void _pixel_mono_set_pixel(rtgui_color_t *c, int x, int y)
{
rt_uint8_t pixel;
pixel = rtgui_color_to_mono(*c);
gfx_device_ops->set_pixel((char*)&pixel, x, y);
}
static void _pixel_rgb565p_set_pixel(rtgui_color_t *c, int x, int y) static void _pixel_rgb565p_set_pixel(rtgui_color_t *c, int x, int y)
{ {
rt_uint16_t pixel; rt_uint16_t pixel;
@ -28,6 +42,14 @@ static void _pixel_rgb888_set_pixel(rtgui_color_t *c, int x, int y)
gfx_device_ops->set_pixel((char*)&pixel, x, y); gfx_device_ops->set_pixel((char*)&pixel, x, y);
} }
static void _pixel_mono_get_pixel(rtgui_color_t *c, int x, int y)
{
rt_uint8_t pixel;
gfx_device_ops->get_pixel((char*)&pixel, x, y);
*c = rtgui_color_from_mono(pixel);
}
static void _pixel_rgb565p_get_pixel(rtgui_color_t *c, int x, int y) static void _pixel_rgb565p_get_pixel(rtgui_color_t *c, int x, int y)
{ {
rt_uint16_t pixel; rt_uint16_t pixel;
@ -52,6 +74,14 @@ static void _pixel_rgb888_get_pixel(rtgui_color_t *c, int x, int y)
*c = rtgui_color_from_888(pixel); *c = rtgui_color_from_888(pixel);
} }
static void _pixel_mono_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
{
rt_uint8_t pixel;
pixel = rtgui_color_to_mono(*c);
gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
}
static void _pixel_rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y) static void _pixel_rgb565p_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
{ {
rt_uint16_t pixel; rt_uint16_t pixel;
@ -76,6 +106,14 @@ static void _pixel_rgb888_draw_hline(rtgui_color_t *c, int x1, int x2, int y)
gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y); gfx_device_ops->draw_hline((char*)&pixel, x1, x2, y);
} }
static void _pixel_mono_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
{
rt_uint8_t pixel;
pixel = rtgui_color_to_mono(*c);
gfx_device_ops->draw_vline((char*)&pixel, x, y1, y2);
}
static void _pixel_rgb565p_draw_vline(rtgui_color_t *c, int x, int y1, int y2) static void _pixel_rgb565p_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
{ {
rt_uint16_t pixel; rt_uint16_t pixel;
@ -102,13 +140,19 @@ static void _pixel_rgb888_draw_vline(rtgui_color_t *c, int x, int y1, int y2)
static void _pixel_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y) static void _pixel_draw_raw_hline(rt_uint8_t *pixels, int x1, int x2, int y)
{ {
if (x2 > x1) gfx_device_ops->blit_line((char*)pixels, x1, x2, y);
gfx_device_ops->blit_line((char*)pixels, x1, y, (x2 - x1));
else
gfx_device_ops->blit_line((char*)pixels, x2, y, (x1 - x2));
} }
/* pixel device */ /* pixel device */
const struct rtgui_graphic_driver_ops _pixel_mono_ops =
{
_pixel_mono_set_pixel,
_pixel_mono_get_pixel,
_pixel_mono_draw_hline,
_pixel_mono_draw_vline,
_pixel_draw_raw_hline,
};
const struct rtgui_graphic_driver_ops _pixel_rgb565p_ops = const struct rtgui_graphic_driver_ops _pixel_rgb565p_ops =
{ {
_pixel_rgb565p_set_pixel, _pixel_rgb565p_set_pixel,
@ -140,6 +184,9 @@ const struct rtgui_graphic_driver_ops *rtgui_pixel_device_get_ops(int pixel_form
{ {
switch (pixel_format) switch (pixel_format)
{ {
case RTGRAPHIC_PIXEL_FORMAT_MONO:
return &_pixel_mono_ops;
case RTGRAPHIC_PIXEL_FORMAT_RGB565: case RTGRAPHIC_PIXEL_FORMAT_RGB565:
return &_pixel_rgb565_ops; return &_pixel_rgb565_ops;

View File

@ -0,0 +1,380 @@
/*
* File : rtgui_application.c
* This file is part of RTGUI in RT-Thread RTOS
* COPYRIGHT (C) 2012, 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
* 2012-01-13 Grissiom first version(just a prototype of application API)
* 2012-07-07 Bernard move the send/recv message to the rtgui_system.c
*/
#include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_app.h>
#include <rtgui/widgets/window.h>
static void _rtgui_app_constructor(struct rtgui_app *app)
{
/* set event handler */
rtgui_object_set_event_handler(RTGUI_OBJECT(app),
rtgui_app_event_handler);
app->name = RT_NULL;
/* set EXITED so we can destroy an application that just created */
app->state_flag = RTGUI_APP_FLAG_EXITED;
app->ref_count = 0;
app->exit_code = 0;
app->tid = RT_NULL;
app->server = RT_NULL;
app->mq = RT_NULL;
app->modal_object = RT_NULL;
app->main_object = RT_NULL;
app->on_idle = RT_NULL;
}
static void _rtgui_app_destructor(struct rtgui_app *app)
{
RT_ASSERT(app != RT_NULL);
rt_free(app->name);
app->name = RT_NULL;
}
DEFINE_CLASS_TYPE(application, "application",
RTGUI_OBJECT_TYPE,
_rtgui_app_constructor,
_rtgui_app_destructor,
sizeof(struct rtgui_app));
struct rtgui_app* rtgui_app_create(
rt_thread_t tid,
const char *title)
{
rt_thread_t srv_tid;
struct rtgui_app *app;
struct rtgui_event_application event;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(title != RT_NULL);
/* create application */
app = RTGUI_APP(rtgui_object_create(RTGUI_APP_TYPE));
if (app == RT_NULL)
return RT_NULL;
/* one thread only can create one rtgui application */
RT_ASSERT(tid->user_data == 0);
app->tid = tid;
/* set user thread */
tid->user_data = (rt_uint32_t)app;
app->mq = rt_mq_create("rtgui", sizeof(union rtgui_event_generic), 32, RT_IPC_FLAG_FIFO);
if (app->mq == RT_NULL)
{
rt_kprintf("create msgq failed.\n");
goto __mq_err;
}
/* set application title */
app->name = (unsigned char*)rt_strdup((char*)title);
if (app->name == RT_NULL)
goto __err;
/* send a message to notify rtgui server */
srv_tid = rtgui_get_server();
if (srv_tid == RT_NULL)
{
rt_kprintf("gui server is not running.\n");
goto __err;
}
/* create the rtgui server application */
if (srv_tid == rt_thread_self())
return app;
RTGUI_EVENT_APP_CREATE_INIT(&event);
event.app = app;
/* notify rtgui server to one application has been created */
if (rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)) == RT_EOK)
{
return app;
}
__err:
__mq_err:
rtgui_object_destroy(RTGUI_OBJECT(app));
tid->user_data = 0;
return RT_NULL;
}
#define _rtgui_application_check(app) \
do { \
RT_ASSERT(app != RT_NULL); \
RT_ASSERT(app->tid != RT_NULL); \
RT_ASSERT(app->tid->user_data != 0); \
RT_ASSERT(app->mq != RT_NULL); \
} while (0)
void rtgui_app_destroy(struct rtgui_app *app)
{
rt_thread_t srv_tid;
_rtgui_application_check(app);
if (!(app->state_flag & RTGUI_APP_FLAG_EXITED))
{
rt_kprintf("cannot destroy a running application: %s.\n",
app->name);
return;
}
/* send a message to notify rtgui server */
srv_tid = rtgui_get_server();
if (srv_tid != rt_thread_self()) /* must not the server thread */
{
struct rtgui_event_application event;
RTGUI_EVENT_APP_DESTROY_INIT(&event);
event.app = app;
if (rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event)) != RT_EOK)
{
rt_kprintf("destroy an application in server failed\n");
return ;
}
}
app->tid->user_data = 0;
rt_mq_delete(app->mq);
rtgui_object_destroy(RTGUI_OBJECT(app));
}
struct rtgui_app* rtgui_app_self(void)
{
struct rtgui_app *app;
rt_thread_t self;
/* get current thread */
self = rt_thread_self();
app = (struct rtgui_app*)(self->user_data);
return app;
}
void rtgui_app_set_onidle(rtgui_idle_func_t onidle)
{
struct rtgui_app *app;
app = rtgui_app_self();
if (app != RT_NULL)
app->on_idle = onidle;
}
rtgui_idle_func_t rtgui_app_get_onidle(void)
{
struct rtgui_app *app;
app = rtgui_app_self();
if (app != RT_NULL)
return app->on_idle;
else
return RT_NULL;
}
rt_inline rt_bool_t _rtgui_application_dest_handle(
struct rtgui_app *app,
struct rtgui_event *event)
{
struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
struct rtgui_object* dest_object = RTGUI_OBJECT(wevent->wid);
if (dest_object != RT_NULL)
{
if (dest_object->event_handler != RT_NULL)
return dest_object->event_handler(RTGUI_OBJECT(dest_object), event);
else
return RT_FALSE;
}
else
{
rt_kprintf("RTGUI ERROR:server sent a event(%d) without wid\n", event->type);
return RT_FALSE;
}
}
rt_bool_t rtgui_app_event_handler(struct rtgui_object* object, rtgui_event_t* event)
{
struct rtgui_app* app;
RT_ASSERT(object != RT_NULL);
RT_ASSERT(event != RT_NULL);
app = RTGUI_APP(object);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
case RTGUI_EVENT_CLIP_INFO:
case RTGUI_EVENT_WIN_ACTIVATE:
case RTGUI_EVENT_WIN_DEACTIVATE:
case RTGUI_EVENT_WIN_CLOSE:
case RTGUI_EVENT_WIN_MOVE:
case RTGUI_EVENT_KBD:
_rtgui_application_dest_handle(app, event);
break;
case RTGUI_EVENT_APP_ACTIVATE:
if (app->main_object != RT_NULL)
{
rtgui_win_activate(RTGUI_WIN(app->main_object));
if (app->modal_object != RT_NULL)
rtgui_win_activate(RTGUI_WIN(app->modal_object));
}
else if (app->modal_object != RT_NULL)
{
rtgui_win_activate(RTGUI_WIN(app->modal_object));
}
break;
case RTGUI_EVENT_MOUSE_BUTTON:
case RTGUI_EVENT_MOUSE_MOTION:
{
struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
struct rtgui_object* dest_object = RTGUI_OBJECT(wevent->wid);
// FIXME: let application determine the dest_wiget but not in sever
// so we can combine this handler with above one
if (app->modal_object != RT_NULL &&
dest_object != app->modal_object)
{
// rt_kprintf("discard event %s that is not sent to modal object\n",
// event_string[event->type]);
}
else
{
_rtgui_application_dest_handle(app, event);
}
}
break;
case RTGUI_EVENT_TIMER:
{
struct rtgui_timer* timer;
struct rtgui_event_timer* etimer = (struct rtgui_event_timer*) event;
timer = etimer->timer;
if (timer->timeout != RT_NULL)
{
/* call timeout function */
timer->timeout(timer, timer->user_data);
}
}
break;
case RTGUI_EVENT_COMMAND:
{
struct rtgui_event_command *ecmd = (struct rtgui_event_command*)event;
if (ecmd->wid != RT_NULL)
return _rtgui_application_dest_handle(app, event);
}
default:
return rtgui_object_event_handler(object, event);
}
return RT_TRUE;
}
rt_inline void _rtgui_application_event_loop(struct rtgui_app *app)
{
rt_err_t result;
rt_uint16_t current_ref;
struct rtgui_event *event;
_rtgui_application_check(app);
/* point to event buffer */
event = (struct rtgui_event*)app->event_buffer;
current_ref = ++app->ref_count;
while (current_ref <= app->ref_count)
{
RT_ASSERT(current_ref == app->ref_count);
if (app->on_idle != RT_NULL)
{
result = rtgui_recv_nosuspend(event, sizeof(union rtgui_event_generic));
if (result == RT_EOK)
RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
else if (result == -RT_ETIMEOUT)
app->on_idle(RTGUI_OBJECT(app), RT_NULL);
}
else
{
result = rtgui_recv(event, sizeof(union rtgui_event_generic));
if (result == RT_EOK)
RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
}
}
}
rt_base_t rtgui_app_run(struct rtgui_app *app)
{
_rtgui_application_check(app);
app->state_flag &= ~RTGUI_APP_FLAG_EXITED;
_rtgui_application_event_loop(app);
if (app->ref_count == 0)
app->state_flag |= RTGUI_APP_FLAG_EXITED;
return app->exit_code;
}
void rtgui_app_exit(struct rtgui_app* app, rt_uint16_t code)
{
--app->ref_count;
app->exit_code = code;
}
/**
* set this application as window manager
*/
rt_err_t rtgui_app_set_as_wm(void)
{
rt_thread_t srv_tid;
struct rtgui_event_set_wm event;
struct rtgui_app* app;
srv_tid = rtgui_get_server();
app = rtgui_app_self();
if (app != RT_NULL && srv_tid != RT_NULL)
{
/* notify rtgui server, this is a window manager */
RTGUI_EVENT_SET_WM_INIT(&event);
event.app = app;
rtgui_send_sync(srv_tid, RTGUI_EVENT(&event), sizeof(event));
return RT_EOK;
}
return RT_ERROR;
}
void rtgui_app_set_main_win(struct rtgui_win* win)
{
struct rtgui_app *app;
app = rtgui_app_self();
if (app != RT_NULL)
{
app->main_object = RTGUI_OBJECT(win);
}
}

View File

@ -16,7 +16,7 @@
#include <rtgui/image.h> #include <rtgui/image.h>
#include <rtgui/font.h> #include <rtgui/font.h>
#include <rtgui/event.h> #include <rtgui/event.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/rtgui_server.h> #include <rtgui/rtgui_server.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/widgets/window.h> #include <rtgui/widgets/window.h>
@ -26,7 +26,7 @@
#define RTGUI_MEM_TRACE #define RTGUI_MEM_TRACE
#endif #endif
void rtgui_system_server_init(void) void rtgui_system_server_init()
{ {
/* init image */ /* init image */
rtgui_system_image_init(); rtgui_system_image_init();
@ -59,7 +59,7 @@ static void rtgui_time_out(void* parameter)
event.timer = timer; event.timer = timer;
rtgui_application_send(timer->tid, &(event.parent), sizeof(rtgui_event_timer_t)); rtgui_send(timer->tid, &(event.parent), sizeof(rtgui_event_timer_t));
} }
rtgui_timer_t* rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeout_func timeout, void* parameter) rtgui_timer_t* rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeout_func timeout, void* parameter)
@ -285,3 +285,416 @@ void rtgui_free(void* ptr)
rt_free(ptr); rt_free(ptr);
} }
#if defined(RTGUI_MEM_TRACE) && defined(RT_USING_FINSH)
#include <finsh.h>
void list_mem(void)
{
rt_kprintf("Current Used: %d, Maximal Used: %d\n", mem_info.allocated_size, mem_info.max_allocated);
}
FINSH_FUNCTION_EXPORT(list_mem, display memory information);
#endif
/************************************************************************/
/* RTGUI Event Dump */
/************************************************************************/
#ifdef _WIN32
#define RTGUI_EVENT_DEBUG
#endif
#ifdef RTGUI_EVENT_DEBUG
const char *event_string[] =
{
/* application event */
"APP_CREATE", /* create an application */
"APP_DESTROY", /* destroy an application */
"APP_ACTIVATE", /* activate an application */
/* window event */
"WIN_CREATE", /* create a window */
"WIN_DESTROY", /* destroy a window */
"WIN_SHOW", /* show a window */
"WIN_HIDE", /* hide a window */
"WIN_ACTIVATE", /* activate a window */
"WIN_DEACTIVATE", /* deactivate a window */
"WIN_CLOSE", /* close a window */
"WIN_MOVE", /* move a window */
"WIN_RESIZE", /* resize a window */
"WIN_MODAL_ENTER", /* a window modals */
"SET_WM", /* set window manager */
"UPDATE_BEGIN", /* begin of update rect */
"UPDATE_END", /* end of update rect */
"MONITOR_ADD", /* add a monitor rect */
"MONITOR_REMOVE", /* remove a monitor rect*/
"SHOW", /* the widget is going to be shown */
"HIDE", /* the widget is going to be hidden */
"PAINT", /* paint on screen */
"TIMER", /* timer */
/* clip rect information */
"CLIP_INFO", /* clip rect info */
/* mouse and keyboard event */
"MOUSE_MOTION", /* mouse motion */
"MOUSE_BUTTON", /* mouse button info */
"KBD", /* keyboard info */
/* user command event */
"COMMAND", /* user command */
/* request's status event */
"STATUS", /* request result */
"SCROLLED", /* scroll bar scrolled */
"RESIZE", /* widget resize */
};
#define DBG_MSG(x) rt_kprintf x
static void rtgui_event_dump(rt_thread_t tid, 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 = event->sender->name;
rt_kprintf("%s -- %s --> %s ", sender, event_string[event->type], tid->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",
#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
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_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;
}
rt_kprintf("\n");
}
#else
#define DBG_MSG(x)
#define rtgui_event_dump(tid, event)
#endif
/************************************************************************/
/* RTGUI IPC APIs */
/************************************************************************/
rt_err_t rtgui_send(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
{
rt_err_t result;
struct rtgui_app *app;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event);
/* find struct rtgui_application */
app = (struct rtgui_app*) (tid->user_data);
if (app == RT_NULL)
return -RT_ERROR;
result = rt_mq_send(app->mq, event, event_size);
if (result != RT_EOK)
{
if (event->type != RTGUI_EVENT_TIMER)
rt_kprintf("send event to %s failed\n", app->tid->name);
}
return result;
}
rt_err_t rtgui_send_urgent(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
{
rt_err_t result;
struct rtgui_app *app;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event);
/* find rtgui_application */
app = (struct rtgui_app*) (tid->user_data);
if (app == RT_NULL)
return -RT_ERROR;
result = rt_mq_urgent(app->mq, event, event_size);
if (result != RT_EOK)
rt_kprintf("send ergent event failed\n");
return result;
}
rt_err_t rtgui_send_sync(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
{
rt_err_t r;
struct rtgui_app *app;
rt_int32_t ack_buffer, ack_status;
struct rt_mailbox ack_mb;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event);
/* init ack mailbox */
r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0);
if (r!= RT_EOK)
goto __return;
app = (struct rtgui_app*) (tid->user_data);
if (app == RT_NULL)
{
r = -RT_ERROR;
goto __return;
}
event->ack = &ack_mb;
r = rt_mq_send(app->mq, event, event_size);
if (r != RT_EOK)
{
rt_kprintf("send sync event failed\n");
goto __return;
}
r = rt_mb_recv(&ack_mb, (rt_uint32_t*)&ack_status, RT_WAITING_FOREVER);
if (r!= RT_EOK)
goto __return;
if (ack_status != RTGUI_STATUS_OK)
r = -RT_ERROR;
else
r = RT_EOK;
__return:
/* fini ack mailbox */
rt_mb_detach(&ack_mb);
return r;
}
rt_err_t rtgui_ack(rtgui_event_t* event, rt_int32_t status)
{
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event->ack != RT_NULL);
rt_mb_send(event->ack, status);
return RT_EOK;
}
rt_err_t rtgui_recv(rtgui_event_t* event, rt_size_t event_size)
{
struct rtgui_app* app;
rt_err_t r;
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
app = (struct rtgui_app*) (rt_thread_self()->user_data);
if (app == RT_NULL)
return -RT_ERROR;
r = rt_mq_recv(app->mq, event, event_size, RT_WAITING_FOREVER);
return r;
}
rt_err_t rtgui_recv_nosuspend(rtgui_event_t* event, rt_size_t event_size)
{
struct rtgui_app *app;
rt_err_t r;
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event != 0);
app = (struct rtgui_app*) (rt_thread_self()->user_data);
if (app == RT_NULL)
return -RT_ERROR;
r = rt_mq_recv(app->mq, event, event_size, 0);
return r;
}
rt_err_t rtgui_recv_filter(rt_uint32_t type, rtgui_event_t* event, rt_size_t event_size)
{
struct rtgui_app *app;
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
app = (struct rtgui_app*) (rt_thread_self()->user_data);
if (app == RT_NULL)
return -RT_ERROR;
while (rt_mq_recv(app->mq, event, event_size, RT_WAITING_FOREVER) == RT_EOK)
{
if (event->type == type)
{
return RT_EOK;
}
else
{
if (RTGUI_OBJECT(app)->event_handler != RT_NULL)
{
RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
}
}
}
return -RT_ERROR;
}
rt_thread_t rtgui_get_server(void)
{
return rt_thread_find("rtgui");
}

View File

@ -14,3 +14,5 @@ slider 处理上下键,上面的值小,下面的值大。
6, view 不再提供 show 方法。如果想单独显示控件,请用 window 包含之。 6, view 不再提供 show 方法。如果想单独显示控件,请用 window 包含之。
7, 若窗口在销毁(destroy)时没有关闭,则 RTGUI 会先关闭之。也会调用 on_close 函数
但是此函数的返回值会被忽略。

View File

@ -46,9 +46,9 @@ mq 的模式。rtgui_application 记录当前依附的 panel和 panel 的 ext
10, 在 widget 中添加 on_show 和 on_hide 事件回调函数。(Done) 10, 在 widget 中添加 on_show 和 on_hide 事件回调函数。(Done)
11, 添加 EVENT_WIN_MODAL_ENTER 和 EVENT_WIN_MODAL_EXIT 事件,用来通知窗口管理器 11, 添加 EVENT_WIN_MODAL_ENTER 和 EVENT_WIN_MODAL_EXIT 事件,用来通知窗口管理器
(topwin)一个窗口进入模态。窗口管理器根据这个进行相应的设置。 (topwin)一个窗口进入模态。窗口管理器根据这个进行相应的设置。(Done)
12, rtgui_filelist_view 不必继承自 container。 12, rtgui_filelist_view 不必继承自 container。(Deprecated)
13, 添加 desktop window 支持。(Done) 13, 添加 desktop window 支持。(Done)
概念与名词: 概念与名词:

View File

@ -5,5 +5,6 @@
typedef void (*rtgui_blit_line_func)(rt_uint8_t* dst, rt_uint8_t* src, int line); typedef void (*rtgui_blit_line_func)(rt_uint8_t* dst, rt_uint8_t* src, int line);
rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp); rtgui_blit_line_func rtgui_blit_line_get(int dst_bpp, int src_bpp);
rtgui_blit_line_func rtgui_blit_line_get_inv(int dst_bpp, int src_bpp);
#endif #endif

View File

@ -10,6 +10,7 @@
* Change Logs: * Change Logs:
* Date Author Notes * Date Author Notes
* 2009-10-16 Bernard first version * 2009-10-16 Bernard first version
* 2012-01-24 onelife add mono color support
*/ */
#ifndef __RTGUI_COLOR_H__ #ifndef __RTGUI_COLOR_H__
#define __RTGUI_COLOR_H__ #define __RTGUI_COLOR_H__
@ -45,6 +46,30 @@ extern const rtgui_color_t light_grey;
* BBBB BBBB GGGG GGGG RRRR RRRR * BBBB BBBB GGGG GGGG RRRR RRRR
*/ */
/* convert rtgui color to mono */
rt_inline rt_uint8_t rtgui_color_to_mono(rtgui_color_t c)
{
rt_uint8_t pixel;
pixel = (RTGUI_RGB_R(c) | RTGUI_RGB_G(c) | RTGUI_RGB_B(c)) ? 0x01 : 0x00;
return pixel;
}
rt_inline rtgui_color_t rtgui_color_from_mono(rt_uint8_t pixel)
{
rtgui_color_t color;
if (pixel)
{
color = white;
}
else
{
color = black;
}
return color;
}
/* convert rtgui color to BBBBBGGGGGGRRRRR */ /* convert rtgui color to BBBBBGGGGGGRRRRR */
rt_inline rt_uint16_t rtgui_color_to_565(rtgui_color_t c) rt_inline rt_uint16_t rtgui_color_to_565(rtgui_color_t c)
{ {

View File

@ -54,6 +54,7 @@ struct rtgui_graphic_driver* rtgui_graphic_driver_get_default(void);
void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect); void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect);
void rtgui_graphic_driver_screen_update(const struct rtgui_graphic_driver* driver, rtgui_rect_t *rect); void rtgui_graphic_driver_screen_update(const struct rtgui_graphic_driver* driver, rtgui_rect_t *rect);
rt_uint8_t* rtgui_graphic_driver_get_framebuffer(const struct rtgui_graphic_driver* driver); rt_uint8_t* rtgui_graphic_driver_get_framebuffer(const struct rtgui_graphic_driver* driver);
rt_uint8_t* rtgui_graphic_driver_get_default_framebuffer(void);
rt_err_t rtgui_graphic_set_device(rt_device_t device); rt_err_t rtgui_graphic_set_device(rt_device_t device);

View File

@ -21,6 +21,11 @@
* rtgui_event_generic */ * rtgui_event_generic */
enum _rtgui_event_type enum _rtgui_event_type
{ {
/* applications event */
RTGUI_EVENT_APP_CREATE, /* create an application */
RTGUI_EVENT_APP_DESTROY, /* destroy an application */
RTGUI_EVENT_APP_ACTIVATE, /* activate an application */
/* window event */ /* window event */
RTGUI_EVENT_WIN_CREATE, /* create a window */ RTGUI_EVENT_WIN_CREATE, /* create a window */
RTGUI_EVENT_WIN_DESTROY, /* destroy a window */ RTGUI_EVENT_WIN_DESTROY, /* destroy a window */
@ -43,6 +48,8 @@ enum _rtgui_event_type
RTGUI_EVENT_UPDATE_END, /* update a rect */ RTGUI_EVENT_UPDATE_END, /* update a rect */
RTGUI_EVENT_MONITOR_ADD, /* add a monitor rect */ RTGUI_EVENT_MONITOR_ADD, /* add a monitor rect */
RTGUI_EVENT_MONITOR_REMOVE, /* remove a monitor rect */ RTGUI_EVENT_MONITOR_REMOVE, /* remove a monitor rect */
RTGUI_EVENT_SHOW, /* the widget is going to be shown */
RTGUI_EVENT_HIDE, /* the widget is going to be hidden */
RTGUI_EVENT_PAINT, /* paint on screen */ RTGUI_EVENT_PAINT, /* paint on screen */
RTGUI_EVENT_TIMER, /* timer */ RTGUI_EVENT_TIMER, /* timer */
@ -94,6 +101,24 @@ typedef struct rtgui_event rtgui_event_t;
(e)->ack = RT_NULL; \ (e)->ack = RT_NULL; \
} while (0) } while (0)
/*
* RTGUI Application Event
*/
struct rtgui_event_application
{
struct rtgui_event parent;
struct rtgui_app* app;
};
/* gui application init */
#define RTGUI_EVENT_APP_CREATE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_APP_CREATE)
#define RTGUI_EVENT_APP_DESTROY_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_APP_DESTROY)
#define RTGUI_EVENT_APP_ACTIVATE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_APP_ACTIVATE)
/*
* RTGUI Window Event
*/
#define _RTGUI_EVENT_WIN_ELEMENTS \ #define _RTGUI_EVENT_WIN_ELEMENTS \
struct rtgui_event parent; \ struct rtgui_event parent; \
struct rtgui_win *wid; struct rtgui_win *wid;
@ -151,6 +176,16 @@ struct rtgui_event_win_resize
#define RTGUI_EVENT_WIN_RESIZE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_RESIZE) #define RTGUI_EVENT_WIN_RESIZE_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_RESIZE)
#define RTGUI_EVENT_WIN_MODAL_ENTER_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MODAL_ENTER) #define RTGUI_EVENT_WIN_MODAL_ENTER_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_WIN_MODAL_ENTER)
/*
* RTGUI set window manager
*/
struct rtgui_event_set_wm
{
struct rtgui_event parent;
struct rtgui_app *app;
};
#define RTGUI_EVENT_SET_WM_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_SET_WM);
/* /*
* RTGUI Other Event * RTGUI Other Event
*/ */
@ -214,6 +249,12 @@ struct rtgui_event_clip_info
#define RTGUI_EVENT_PAINT_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PAINT) #define RTGUI_EVENT_PAINT_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_PAINT)
#define RTGUI_EVENT_TIMER_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_TIMER) #define RTGUI_EVENT_TIMER_INIT(e) RTGUI_EVENT_INIT(&((e)->parent), RTGUI_EVENT_TIMER)
#define rtgui_event_show rtgui_event
#define rtgui_event_hide rtgui_event
#define RTGUI_EVENT_SHOW_INIT(e) RTGUI_EVENT_INIT((e), RTGUI_EVENT_SHOW)
#define RTGUI_EVENT_HIDE_INIT(e) RTGUI_EVENT_INIT((e), RTGUI_EVENT_HIDE)
/* /*
* RTGUI Mouse and Keyboard Event * RTGUI Mouse and Keyboard Event
*/ */
@ -325,6 +366,12 @@ struct rtgui_event_resize
union rtgui_event_generic union rtgui_event_generic
{ {
struct rtgui_event base; struct rtgui_event base;
struct rtgui_event_application app_create;
struct rtgui_event_application app_destroy;
struct rtgui_event_application app_activate;
struct rtgui_event_set_wm set_wm;
struct rtgui_event_win win_base; struct rtgui_event_win win_base;
struct rtgui_event_win_create win_create; struct rtgui_event_win_create win_create;
struct rtgui_event_win_move win_move; struct rtgui_event_win_move win_move;

View File

@ -30,7 +30,7 @@ struct rtgui_font;
typedef struct rtgui_win rtgui_win_t; typedef struct rtgui_win rtgui_win_t;
typedef struct rtgui_workbench rtgui_workbench_t; typedef struct rtgui_workbench rtgui_workbench_t;
typedef rt_bool_t (*rtgui_event_handler_ptr)(struct rtgui_object* widget, struct rtgui_event* event); typedef rt_bool_t (*rtgui_event_handler_ptr)(struct rtgui_object* object, struct rtgui_event* event);
typedef void (*rtgui_onbutton_func_t)(struct rtgui_object* object, struct rtgui_event* event); typedef void (*rtgui_onbutton_func_t)(struct rtgui_object* object, struct rtgui_event* event);
struct rtgui_point struct rtgui_point

View File

@ -0,0 +1,88 @@
/*
* File : rtgui_application.h
* This file is part of RTGUI in 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
* 2012-01-13 Grissiom first version
*/
#ifndef __RTGUI_APPLICATION_H__
#define __RTGUI_APPLICATION_H__
#include <rtthread.h>
#include <rtgui/rtgui.h>
#include <rtgui/event.h>
#include <rtgui/rtgui_system.h>
DECLARE_CLASS_TYPE(application);
/** Gets the type of a application */
#define RTGUI_APP_TYPE (RTGUI_TYPE(application))
/** Casts the object to an rtgui_workbench */
#define RTGUI_APP(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_APP_TYPE, struct rtgui_app))
/** Checks if the object is an rtgui_workbench */
#define RTGUI_IS_APP(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_APP_TYPE))
enum rtgui_app_flag
{
RTGUI_APP_FLAG_EXITED = 0x04,
RTGUI_APP_FLAG_SHOWN = 0x08
};
typedef void (*rtgui_idle_func_t)(struct rtgui_object* obj, struct rtgui_event *event);
struct rtgui_app
{
struct rtgui_object parent;
/* application name */
unsigned char *name;
struct rtgui_image* icon;
enum rtgui_app_flag state_flag;
rt_uint16_t ref_count;
rt_uint16_t exit_code;
/* the thread id */
rt_thread_t tid;
/* the RTGUI server id */
rt_thread_t server;
/* the message queue of thread */
rt_mq_t mq;
/* event buffer */
rt_uint8_t event_buffer[sizeof(union rtgui_event_generic)];
/* if not RT_NULL, the application is in modal state by modal_object. If is
* RT_NULL, nothing modal windows. */
struct rtgui_object *modal_object;
struct rtgui_object *main_object;
/* on idle event handler */
rtgui_idle_func_t on_idle;
};
/**
* create an application named @myname on thread @param tid
*/
struct rtgui_app* rtgui_app_create(rt_thread_t tid, const char *title);
void rtgui_app_destroy(struct rtgui_app *app);
rt_bool_t rtgui_app_event_handler(struct rtgui_object* obj, rtgui_event_t* event);
rt_base_t rtgui_app_run(struct rtgui_app *app);
void rtgui_app_exit(struct rtgui_app *app, rt_uint16_t code);
void rtgui_app_set_onidle(rtgui_idle_func_t onidle);
rtgui_idle_func_t rtgui_app_get_onidle(void);
struct rtgui_app* rtgui_app_self(void);
rt_err_t rtgui_app_set_as_wm(void);
void rtgui_app_set_main_win(struct rtgui_win* win);
#endif /* end of include guard: RTGUI_APPLICATION_H */

View File

@ -1,99 +0,0 @@
/*
* File : rtgui_application.h
* This file is part of RTGUI in 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
* 2012-01-13 Grissiom first version
*/
#ifndef __RTGUI_APPLICATION_H__
#define __RTGUI_APPLICATION_H__
#include <rtthread.h>
#include <rtgui/rtgui.h>
#include <rtgui/event.h>
#include <rtgui/rtgui_system.h>
DECLARE_CLASS_TYPE(application);
/** Gets the type of a application */
#define RTGUI_APPLICATION_TYPE (RTGUI_TYPE(application))
/** Casts the object to an rtgui_workbench */
#define RTGUI_APPLICATION(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_APPLICATION_TYPE, struct rtgui_application))
/** Checks if the object is an rtgui_workbench */
#define RTGUI_IS_APPLICATION(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_APPLICATION_TYPE))
enum rtgui_application_flag
{
RTGUI_APPLICATION_FLAG_EXITED = 0x04,
RTGUI_APPLICATION_FLAG_SHOWN = 0x08
};
typedef void (*rtgui_idle_func)(struct rtgui_object* obj, struct rtgui_event *event);
struct rtgui_application
{
struct rtgui_object parent;
/* application name */
unsigned char *name;
enum rtgui_application_flag state_flag;
rt_uint16_t ref_count;
rt_uint16_t exit_code;
/* the thread id */
rt_thread_t tid;
rt_thread_t server;
/* the message queue of thread */
rt_mq_t mq;
/* event buffer */
rt_uint8_t event_buffer[sizeof(union rtgui_event_generic)];
/* if not RT_NULL, the application is modaled by modal_object. If is
* RT_NULL, nothing modals. */
struct rtgui_object *modal_object;
/* on idle event handler */
rtgui_idle_func on_idle;
};
/**
* create an application named @myname on thread @param tid
*/
struct rtgui_application* rtgui_application_create(
rt_thread_t tid,
const char *myname);
void rtgui_application_destroy(struct rtgui_application *app);
rt_err_t rtgui_application_show(struct rtgui_application *app);
rt_err_t rtgui_application_hide(struct rtgui_application *app);
rt_base_t rtgui_application_run(struct rtgui_application *app);
void rtgui_application_exit(struct rtgui_application *app, rt_uint16_t code);
void rtgui_application_set_onidle(rtgui_idle_func onidle);
rtgui_idle_func rtgui_application_get_onidle(void);
struct rtgui_application* rtgui_application_self(void);
rt_thread_t rtgui_application_get_server(void);
void rtgui_application_set_root_object(struct rtgui_object* object);
struct rtgui_object* rtgui_application_get_root_object(void);
struct rtgui_event;
rt_err_t rtgui_application_send(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_application_send_urgent(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_application_send_sync(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_application_ack(struct rtgui_event* event, rt_int32_t status);
rt_err_t rtgui_application_recv(struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_application_recv_nosuspend(struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_application_recv_filter(rt_uint32_t type, struct rtgui_event* event, rt_size_t event_size);
#endif /* end of include guard: RTGUI_APPLICATION_H */

View File

@ -77,5 +77,6 @@
//#define RTGUI_USING_DESKTOP_WINDOW //#define RTGUI_USING_DESKTOP_WINDOW
#define RTGUI_EVENT_DEBUG #define RTGUI_EVENT_DEBUG
#undef RTGUI_USING_SMALL_SIZE // #undef RTGUI_USING_SMALL_SIZE
#endif #endif

View File

@ -31,7 +31,7 @@ extern "C" {
/** Casts the function pointer to an rtgui_constructor */ /** Casts the function pointer to an rtgui_constructor */
#define RTGUI_DESTRUCTOR(destructor) ((rtgui_destructor_t)(destructor)) #define RTGUI_DESTRUCTOR(destructor) ((rtgui_destructor_t)(destructor))
/* pre-definetion */ /* pre-definition */
struct rtgui_object; struct rtgui_object;
typedef struct rtgui_object rtgui_object_t; typedef struct rtgui_object rtgui_object_t;
typedef void (*rtgui_constructor_t)(rtgui_object_t *object); typedef void (*rtgui_constructor_t)(rtgui_object_t *object);
@ -125,9 +125,6 @@ rt_bool_t rtgui_object_event_handler(struct rtgui_object *object, struct rtgui_e
/* supress compiler warning */ \ /* supress compiler warning */ \
widget = widget; widget = widget;
void rtgui_object_name_set(rtgui_object_t *object, const char *name);
const char *rtgui_object_name_get(rtgui_object_t *object);
rtgui_object_t *rtgui_object_check_cast(rtgui_object_t *object, rtgui_type_t *type, const char* func, int line); rtgui_object_t *rtgui_object_check_cast(rtgui_object_t *object, rtgui_type_t *type, const char* func, int line);
rtgui_type_t *rtk_object_object_type_get(rtgui_object_t *object); rtgui_type_t *rtk_object_object_type_get(rtgui_object_t *object);

View File

@ -20,7 +20,7 @@
/* RTGUI server definitions */ /* RTGUI server definitions */
/* top window definitions in server */ /* top window definitions in server */
enum enum rtgui_topwin_flag
{ {
WINTITLE_NO = 0x01, WINTITLE_NO = 0x01,
WINTITLE_BORDER = 0x02, WINTITLE_BORDER = 0x02,
@ -34,7 +34,9 @@ enum
/* window is modaled by other window */ /* window is modaled by other window */
WINTITLE_MODALED = 0x80, WINTITLE_MODALED = 0x80,
/* window is modaling other window */ /* window is modaling other window */
WINTITLE_MODALING = 0x100 WINTITLE_MODALING = 0x100,
WINTITLE_ONTOP = 0x200,
WINTITLE_ONBTM = 0x400,
}; };
#define WINTITLE_HEIGHT 20 #define WINTITLE_HEIGHT 20
@ -45,7 +47,7 @@ enum
struct rtgui_topwin struct rtgui_topwin
{ {
/* the window flag */ /* the window flag */
rt_uint32_t flag; enum rtgui_topwin_flag flag;
/* event mask */ /* event mask */
rt_uint32_t mask; rt_uint32_t mask;

View File

@ -53,5 +53,16 @@ void* rtgui_realloc(void* ptr, rt_size_t size);
#define rtgui_enter_critical rt_enter_critical #define rtgui_enter_critical rt_enter_critical
#define rtgui_exit_critical rt_exit_critical #define rtgui_exit_critical rt_exit_critical
rt_thread_t rtgui_get_server(void);
struct rtgui_event;
rt_err_t rtgui_send(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_send_urgent(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_send_sync(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_ack(struct rtgui_event* event, rt_int32_t status);
rt_err_t rtgui_recv(struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_recv_nosuspend(struct rtgui_event* event, rt_size_t event_size);
rt_err_t rtgui_recv_filter(rt_uint32_t type, struct rtgui_event* event, rt_size_t event_size);
#endif #endif

View File

@ -1,44 +0,0 @@
/*
* File : list_view.h
* This file is part of RTGUI in RT-Thread RTOS
* COPYRIGHT (C) 2010, 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
* 2010-01-06 Bernard first version
*/
#ifndef __RTGUI_ABOUT_VIEW_H__
#define __RTGUI_ABOUT_VIEW_H__
#include <rtgui/rtgui.h>
#include <rtgui/image.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/container.h>
DECLARE_CLASS_TYPE(aboutview);
/** Gets the type of a about view */
#define RTGUI_ABOUT_VIEW_TYPE (RTGUI_TYPE(aboutview))
/** Casts the object to a about view */
#define RTGUI_ABOUT_VIEW(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_ABOUT_VIEW_TYPE, rtgui_about_view_t))
/** Checks if the object is a about view */
#define RTGUI_IS_ABOUT_VIEW(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_ABOUT_VIEW_TYPE))
struct rtgui_about_view
{
struct rtgui_container parent;
/* widget private data */
rtgui_image_t* logo;
const char* description;
};
typedef struct rtgui_about_view rtgui_about_view_t;
rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description);
rt_bool_t rtgui_about_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event);
#endif

View File

@ -33,26 +33,23 @@ DECLARE_CLASS_TYPE(box);
struct rtgui_box struct rtgui_box
{ {
struct rtgui_container parent; struct rtgui_object parent;
rt_uint16_t orient; rt_uint16_t orient;
rt_uint16_t border_size; rt_uint16_t border_size;
struct rtgui_container* container;
}; };
typedef struct rtgui_box rtgui_box_t; typedef struct rtgui_box rtgui_box_t;
struct rtgui_box* rtgui_box_create(int orientation, rtgui_rect_t* rect); struct rtgui_box* rtgui_box_create(int orientation, int border_size);
void rtgui_box_destroy(struct rtgui_box* box); void rtgui_box_destroy(struct rtgui_box* box);
rt_bool_t rtgui_box_event_handler(struct rtgui_object* object, rtgui_event_t* event);
void rtgui_box_append(rtgui_box_t* box, rtgui_widget_t* widget);
void rtgui_box_layout(rtgui_box_t* box); void rtgui_box_layout(rtgui_box_t* box);
rt_uint32_t rtgui_box_get_width(rtgui_box_t* box);
rt_uint32_t rtgui_box_get_height(rtgui_box_t* box);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif #endif

View File

@ -15,6 +15,7 @@
#define __RTGUI_CONTAINER_H__ #define __RTGUI_CONTAINER_H__
#include <rtgui/widgets/widget.h> #include <rtgui/widgets/widget.h>
#include <rtgui/widgets/box.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
@ -35,6 +36,9 @@ struct rtgui_container
{ {
struct rtgui_widget parent; struct rtgui_widget parent;
/* layout box */
struct rtgui_box* layout_box;
rtgui_list_t children; rtgui_list_t children;
}; };
typedef struct rtgui_container rtgui_container_t; typedef struct rtgui_container rtgui_container_t;
@ -44,12 +48,9 @@ void rtgui_container_destroy(rtgui_container_t* container);
rt_bool_t rtgui_container_event_handler(struct rtgui_object* widget, struct rtgui_event* event); rt_bool_t rtgui_container_event_handler(struct rtgui_object* widget, struct rtgui_event* event);
#ifndef RTGUI_USING_SMALL_SIZE /* set layout box */
struct rtgui_box;
void rtgui_container_set_box(struct rtgui_container* container, struct rtgui_box* box); void rtgui_container_set_box(struct rtgui_container* container, struct rtgui_box* box);
#endif void rtgui_container_layout(struct rtgui_container* container);
void rtgui_container_hide(rtgui_container_t* container);
void rtgui_container_add_child(rtgui_container_t *container, rtgui_widget_t* child); void rtgui_container_add_child(rtgui_container_t *container, rtgui_widget_t* child);
void rtgui_container_remove_child(rtgui_container_t *container, rtgui_widget_t* child); void rtgui_container_remove_child(rtgui_container_t *container, rtgui_widget_t* child);

View File

@ -49,7 +49,7 @@ rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory,
const rtgui_rect_t* rect); const rtgui_rect_t* rect);
void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view); void rtgui_filelist_view_destroy(rtgui_filelist_view_t* view);
rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event); rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_object* object, struct rtgui_event* event);
void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory); void rtgui_filelist_view_set_directory(rtgui_filelist_view_t* view, const char* directory);
void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len); void rtgui_filelist_view_get_fullpath(rtgui_filelist_view_t* view, char* path, rt_size_t len);

View File

@ -29,7 +29,7 @@ struct rtgui_menu_item
rt_uint16_t submenu_count; rt_uint16_t submenu_count;
/* menu action */ /* menu action */
rt_bool_t (*on_menuaction)(rtgui_widget_t* widget, rtgui_event_t* event); rt_bool_t (*on_menuaction)(struct rtgui_object* object, struct rtgui_event* event);
}; };
typedef struct rtgui_menu_item rtgui_menu_item_t; typedef struct rtgui_menu_item rtgui_menu_item_t;

View File

@ -0,0 +1,45 @@
/*
* File : panel.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_PANEL_H__
#define __RTGUI_PANEL_H__
#include <rtgui/rtgui.h>
#include <rtgui/widgets/container.h>
DECLARE_CLASS_TYPE(panel);
/** Gets the type of a panel */
#define RTGUI_PANEL_TYPE (RTGUI_TYPE(panel))
/** Casts the object to an panel */
#define RTGUI_PANEL(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_PANEL_TYPE, rtgui_panel_t))
/** Checks if the object is an rtgui_button */
#define RTGUI_IS_PANEL(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_PANEL_TYPE))
/*
* the panel widget
*/
struct rtgui_panel
{
struct rtgui_container parent;
int border_style;
};
typedef struct rtgui_panel rtgui_panel_t;
rtgui_panel_t* rtgui_panel_create(int border_style);
void rtgui_panel_destroy(rtgui_panel_t* panel);
rt_bool_t rtgui_panel_event_handler(struct rtgui_object* object, struct rtgui_event* event);
#endif

View File

@ -14,32 +14,34 @@
#ifndef __RTGUI_TEXTBOX_H__ #ifndef __RTGUI_TEXTBOX_H__
#define __RTGUI_TEXTBOX_H__ #define __RTGUI_TEXTBOX_H__
#include <rtgui/rtgui.h> #include <rtgui/rtgui_system.h>
#include <rtgui/widgets/widget.h> #include <rtgui/widgets/widget.h>
#include <rtgui/widgets/container.h>
#ifdef __cplusplus
extern "C" {
#endif
DECLARE_CLASS_TYPE(textbox); DECLARE_CLASS_TYPE(textbox);
/** Gets the type of a textbox */ /** Gets the type of a textbox */
#define RTGUI_TEXTBOX_TYPE (RTGUI_TYPE(textbox)) #define RTGUI_TEXTBOX_TYPE (RTGUI_TYPE(textbox))
/** Casts the object to a rtgui_textbox */ /** Casts the object to a rtgui_textbox_t */
#define RTGUI_TEXTBOX(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTBOX_TYPE, rtgui_textbox_t)) #define RTGUI_TEXTBOX(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_TEXTBOX_TYPE, rtgui_textbox_t))
/** Checks if the object is a rtgui_textbox */ /** Checks if the object is a rtgui_textbox_t */
#define RTGUI_IS_TEXTBOX(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TEXTBOX_TYPE)) #define RTGUI_IS_TEXTBOX(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_TEXTBOX_TYPE))
#define RTGUI_TEXTBOX_DEFAULT_WIDTH 80 #define RTGUI_TEXTBOX_DEFAULT_WIDTH 80
#define RTGUI_TEXTBOX_DEFAULT_HEIGHT 20 #define RTGUI_TEXTBOX_DEFAULT_HEIGHT 20
#define RTGUI_TEXTBOX_SINGLE 0x00 #define RTGUI_TEXTBOX_SINGLE 0x00
#define RTGUI_TEXTBOX_MULTI 0x01 #define RTGUI_TEXTBOX_MULTI 0x01 /* multiline */
#define RTGUI_TEXTBOX_MASK 0x02 #define RTGUI_TEXTBOX_MASK 0x02 /* ciphertext */
#define RTGUI_TEXTBOX_CARET_SHOW 0x10 #define RTGUI_TEXTBOX_DIGIT 0x04 /* digit */
#define RTGUI_TEXTBOX_CARET_HIDE 0x00 #define RTGUI_TEXTBOX_CARET_SHOW 0x10
#define RTGUI_TEXTBOX_CARET_STAT 0x20 /* unused */
struct rtgui_textbox_line #define RTGUI_TEXTBOX_LINE_MAX 128 /* text line cache */
{
char* line_text;
struct rtgui_textbox_line *prev, *next;
};
struct rtgui_textbox struct rtgui_textbox
{ {
@ -47,22 +49,24 @@ struct rtgui_textbox
struct rtgui_widget parent; struct rtgui_widget parent;
/* text box flag */ /* text box flag */
rt_uint8_t flag; rt_uint32_t flag;
/* current line and position */ /* current line and position */
rt_uint16_t line, line_begin, position, line_length; rt_uint16_t line, line_begin, position, line_length;
rt_uint16_t dis_length; /*may be display length.*/
char* text; char* text;
rt_size_t font_width; rt_size_t font_width;
struct rtgui_timer* caret_timer; rtgui_timer_t *caret_timer;
rtgui_color_t *caret;
rtgui_rect_t caret_rect;
/* widget private data */ /* textbox private data */
rt_bool_t (*on_enter) (struct rtgui_widget* widget, struct rtgui_event* event); rt_bool_t (*on_enter) (struct rtgui_textbox *box, rtgui_event_t* event);
}; };
typedef struct rtgui_textbox rtgui_textbox_t; typedef struct rtgui_textbox rtgui_textbox_t;
struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint8_t flag); struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint32_t flag);
void rtgui_textbox_destroy(struct rtgui_textbox* box); void rtgui_textbox_destroy(struct rtgui_textbox* box);
rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event); rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event);
@ -72,4 +76,11 @@ const char* rtgui_textbox_get_value(struct rtgui_textbox* box);
void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length); void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length);
void rtgui_textbox_get_edit_rect(struct rtgui_textbox *box,rtgui_rect_t *rect);
void rtgui_textbox_ondraw(rtgui_textbox_t* box);
#ifdef __cplusplus
}
#endif
#endif #endif

View File

@ -26,16 +26,16 @@ extern "C" {
#endif #endif
#define RTGUI_WIDGET_FLAG_DEFAULT 0x0000 #define RTGUI_WIDGET_FLAG_DEFAULT 0x0000
#define RTGUI_WIDGET_FLAG_HIDE 0x0001 #define RTGUI_WIDGET_FLAG_SHOWN 0x0001
#define RTGUI_WIDGET_FLAG_DISABLE 0x0002 #define RTGUI_WIDGET_FLAG_DISABLE 0x0002
#define RTGUI_WIDGET_FLAG_FOCUS 0x0004 #define RTGUI_WIDGET_FLAG_FOCUS 0x0004
#define RTGUI_WIDGET_FLAG_TRANSPARENT 0x0008 #define RTGUI_WIDGET_FLAG_TRANSPARENT 0x0008
#define RTGUI_WIDGET_FLAG_FOCUSABLE 0x0010 #define RTGUI_WIDGET_FLAG_FOCUSABLE 0x0010
#define RTGUI_WIDGET_FLAG_DC_VISIBLE 0x0100 #define RTGUI_WIDGET_FLAG_DC_VISIBLE 0x0100
#define RTGUI_WIDGET_UNHIDE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_HIDE #define RTGUI_WIDGET_UNHIDE(w) (w)->flag |= RTGUI_WIDGET_FLAG_SHOWN
#define RTGUI_WIDGET_HIDE(w) (w)->flag |= RTGUI_WIDGET_FLAG_HIDE #define RTGUI_WIDGET_HIDE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_SHOWN
#define RTGUI_WIDGET_IS_HIDE(w) ((w)->flag & RTGUI_WIDGET_FLAG_HIDE) #define RTGUI_WIDGET_IS_HIDE(w) (!((w)->flag & RTGUI_WIDGET_FLAG_SHOWN))
#define RTGUI_WIDGET_ENABLE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_DISABLE #define RTGUI_WIDGET_ENABLE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_DISABLE
#define RTGUI_WIDGET_DISABLE(w) (w)->flag |= RTGUI_WIDGET_FLAG_DISABLE #define RTGUI_WIDGET_DISABLE(w) (w)->flag |= RTGUI_WIDGET_FLAG_DISABLE
@ -52,12 +52,13 @@ extern "C" {
#define RTGUI_WIDGET_DC_SET_UNVISIBLE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_DC_VISIBLE #define RTGUI_WIDGET_DC_SET_UNVISIBLE(w) (w)->flag &= ~RTGUI_WIDGET_FLAG_DC_VISIBLE
#define RTGUI_WIDGET_DC(w) ((struct rtgui_dc*)&((w)->dc_type)) #define RTGUI_WIDGET_DC(w) ((struct rtgui_dc*)&((w)->dc_type))
/* get rtgui widget object */ /* rtgui widget attribute */
#define RTGUI_WIDGET_FOREGROUND(w) ((w)->gc.foreground) #define RTGUI_WIDGET_FOREGROUND(w) (RTGUI_WIDGET(w)->gc.foreground)
#define RTGUI_WIDGET_BACKGROUND(w) ((w)->gc.background) #define RTGUI_WIDGET_BACKGROUND(w) (RTGUI_WIDGET(w)->gc.background)
#define RTGUI_WIDGET_TEXTALIGN(w) ((w)->gc.textalign) #define RTGUI_WIDGET_TEXTALIGN(w) (RTGUI_WIDGET(w)->gc.textalign)
#define RTGUI_WIDGET_FONT(w) ((w)->gc.font) #define RTGUI_WIDGET_FONT(w) (RTGUI_WIDGET(w)->gc.font)
#define RTGUI_WIDGET_FLAG(w) ((w)->flag) #define RTGUI_WIDGET_FLAG(w) (RTGUI_WIDGET(w)->flag)
#define RTGUI_WIDGET_ALIGN(w) (RTGUI_WIDGET(w)->align)
DECLARE_CLASS_TYPE(widget); DECLARE_CLASS_TYPE(widget);
@ -96,14 +97,10 @@ struct rtgui_widget
/* the widget extent */ /* the widget extent */
rtgui_rect_t extent; rtgui_rect_t extent;
#ifndef RTGUI_USING_SMALL_SIZE
/* minimal width and height of widget */ /* minimal width and height of widget */
rt_int16_t mini_width, mini_height; rt_int16_t mini_width, mini_height;
rt_int16_t margin, margin_style;
/* widget align */ /* widget align */
rt_int32_t align; rt_int32_t align;
#endif
/* the rect clip */ /* the rect clip */
rtgui_region_t clip; rtgui_region_t clip;
@ -189,7 +186,9 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget);
struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget); struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget);
void rtgui_widget_show(rtgui_widget_t* widget); void rtgui_widget_show(rtgui_widget_t* widget);
rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event);
void rtgui_widget_hide(rtgui_widget_t* widget); void rtgui_widget_hide(rtgui_widget_t* widget);
rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *event);
void rtgui_widget_update(rtgui_widget_t* widget); void rtgui_widget_update(rtgui_widget_t* widget);
/* get parent color */ /* get parent color */

View File

@ -37,16 +37,8 @@ DECLARE_CLASS_TYPE(win);
#define RTGUI_WIN_STYLE_MINIBOX 0x010 /* window has the mini button */ #define RTGUI_WIN_STYLE_MINIBOX 0x010 /* window has the mini button */
#define RTGUI_WIN_STYLE_DESTROY_ON_CLOSE 0x020 /* window is destroyed when closed */ #define RTGUI_WIN_STYLE_DESTROY_ON_CLOSE 0x020 /* window is destroyed when closed */
#ifdef RTGUI_USING_DESKTOP_WINDOW #define RTGUI_WIN_STYLE_ONTOP 0x040 /* window is in the top layer */
/* A desktop window is a full screen window which will beneath all other windows. #define RTGUI_WIN_STYLE_ONBTM 0x080 /* window is in the bottom layer */
* There will be only one desktop window in a system. And this window should be
* created _before_ any other windows.
*/
#define RTGUI_WIN_STYLE_DESKTOP 0x8000
#define RTGUI_WIN_STYLE_DESKTOP_DEFAULT RTGUI_WIN_STYLE_DESKTOP |\
RTGUI_WIN_STYLE_NO_BORDER |\
RTGUI_WIN_STYLE_NO_TITLE
#endif
#define RTGUI_WIN_STYLE_DEFAULT (RTGUI_WIN_STYLE_CLOSEBOX | RTGUI_WIN_STYLE_MINIBOX) #define RTGUI_WIN_STYLE_DEFAULT (RTGUI_WIN_STYLE_CLOSEBOX | RTGUI_WIN_STYLE_MINIBOX)
@ -84,7 +76,7 @@ struct rtgui_win
/* the widget that will grab the focus in current window */ /* the widget that will grab the focus in current window */
struct rtgui_widget *focused_widget; struct rtgui_widget *focused_widget;
/* top window style */ /* window style */
rt_uint16_t style; rt_uint16_t style;
/* window state flag */ /* window state flag */
@ -133,7 +125,7 @@ rt_bool_t rtgui_win_close(struct rtgui_win* win);
rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal); rt_base_t rtgui_win_show(struct rtgui_win *win, rt_bool_t is_modal);
void rtgui_win_hiden(rtgui_win_t* win); void rtgui_win_hiden(rtgui_win_t* win);
void rtgui_win_end_modal(rtgui_win_t* win, rtgui_modal_code_t modal_code); void rtgui_win_end_modal(rtgui_win_t* win, rtgui_modal_code_t modal_code);
rt_err_t rtgui_win_activate(struct rtgui_win *win);
rt_bool_t rtgui_win_is_activated(struct rtgui_win* win); rt_bool_t rtgui_win_is_activated(struct rtgui_win* win);
void rtgui_win_move(struct rtgui_win* win, int x, int y); void rtgui_win_move(struct rtgui_win* win, int x, int y);

View File

@ -88,3 +88,7 @@ rt_uint8_t* rtgui_graphic_driver_get_framebuffer(const struct rtgui_graphic_driv
return (rt_uint8_t*)driver->framebuffer; return (rt_uint8_t*)driver->framebuffer;
} }
rt_uint8_t* rtgui_graphic_driver_get_default_framebuffer(void)
{
return rtgui_graphic_driver_get_framebuffer(&_driver);
}

View File

@ -52,9 +52,6 @@ struct rtgui_cursor
rt_uint8_t *win_top, *win_bottom; rt_uint8_t *win_top, *win_bottom;
rt_bool_t win_rect_show, win_rect_has_saved; rt_bool_t win_rect_show, win_rect_has_saved;
#endif #endif
/* screen framebuffer */
rt_uint8_t* framebuffer;
}; };
struct rtgui_cursor* _rtgui_cursor; struct rtgui_cursor* _rtgui_cursor;
@ -140,7 +137,6 @@ void rtgui_mouse_init()
/* init cursor */ /* init cursor */
_rtgui_cursor->bpp = gd->bits_per_pixel/8; _rtgui_cursor->bpp = gd->bits_per_pixel/8;
_rtgui_cursor->framebuffer = rtgui_graphic_driver_get_framebuffer(gd);
_rtgui_cursor->screen_pitch = _rtgui_cursor->bpp * gd->width; _rtgui_cursor->screen_pitch = _rtgui_cursor->bpp * gd->width;
#ifdef RTGUI_USING_MOUSE_CURSOR #ifdef RTGUI_USING_MOUSE_CURSOR
@ -300,7 +296,7 @@ static void rtgui_cursor_restore()
rt_base_t idx, height, cursor_pitch; rt_base_t idx, height, cursor_pitch;
rt_uint8_t *cursor_ptr, *fb_ptr; rt_uint8_t *cursor_ptr, *fb_ptr;
fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch fb_ptr = rtgui_graphic_driver_get_default_framebuffer() + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch
+ _rtgui_cursor->cx * _rtgui_cursor->bpp; + _rtgui_cursor->cx * _rtgui_cursor->bpp;
cursor_ptr = _rtgui_cursor->cursor_saved; cursor_ptr = _rtgui_cursor->cursor_saved;
@ -327,7 +323,7 @@ static void rtgui_cursor_save()
rt_base_t idx, height, cursor_pitch; rt_base_t idx, height, cursor_pitch;
rt_uint8_t *cursor_ptr, *fb_ptr; rt_uint8_t *cursor_ptr, *fb_ptr;
fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch + fb_ptr = _driver_get_default_framebuffer() + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch +
_rtgui_cursor->cx * _rtgui_cursor->bpp; _rtgui_cursor->cx * _rtgui_cursor->bpp;
cursor_ptr = _rtgui_cursor->cursor_saved; cursor_ptr = _rtgui_cursor->cursor_saved;
@ -488,10 +484,11 @@ static void rtgui_winrect_show()
static void rtgui_winrect_restore() static void rtgui_winrect_restore()
{ {
rt_uint8_t *winrect_ptr, *fb_ptr; rt_uint8_t *winrect_ptr, *fb_ptr, *driver_fb;
int winrect_pitch, idx; int winrect_pitch, idx;
rtgui_rect_t screen_rect, win_rect; rtgui_rect_t screen_rect, win_rect;
driver_fb = rtgui_graphic_driver_get_default_framebuffer();
win_rect = _rtgui_cursor->win_rect; win_rect = _rtgui_cursor->win_rect;
rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
@ -499,7 +496,7 @@ static void rtgui_winrect_restore()
rtgui_rect_intersect(&screen_rect, &win_rect); rtgui_rect_intersect(&screen_rect, &win_rect);
/* restore winrect left */ /* restore winrect left */
fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
win_rect.x1 * _rtgui_cursor->bpp; win_rect.x1 * _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_left; winrect_ptr = _rtgui_cursor->win_left;
winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
@ -507,7 +504,7 @@ static void rtgui_winrect_restore()
(win_rect.y2 - win_rect.y1), winrect_pitch); (win_rect.y2 - win_rect.y1), winrect_pitch);
/* restore winrect right */ /* restore winrect right */
fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
(win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp; (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_right; winrect_ptr = _rtgui_cursor->win_right;
winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
@ -515,7 +512,7 @@ static void rtgui_winrect_restore()
(win_rect.y2 - win_rect.y1), winrect_pitch); (win_rect.y2 - win_rect.y1), winrect_pitch);
/* restore winrect top */ /* restore winrect top */
fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
(win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp; (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_top; winrect_ptr = _rtgui_cursor->win_top;
winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp; winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
@ -523,7 +520,7 @@ static void rtgui_winrect_restore()
WIN_MOVE_BORDER, winrect_pitch); WIN_MOVE_BORDER, winrect_pitch);
/* restore winrect bottom */ /* restore winrect bottom */
fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
(win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp; (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_bottom; winrect_ptr = _rtgui_cursor->win_bottom;
display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch, display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
@ -532,10 +529,11 @@ static void rtgui_winrect_restore()
static void rtgui_winrect_save() static void rtgui_winrect_save()
{ {
rt_uint8_t *winrect_ptr, *fb_ptr; rt_uint8_t *winrect_ptr, *fb_ptr, *driver_fb;
int winrect_pitch, idx; int winrect_pitch, idx;
rtgui_rect_t screen_rect, win_rect; rtgui_rect_t screen_rect, win_rect;
driver_fb = rtgui_graphic_driver_get_default_framebuffer();
win_rect = _rtgui_cursor->win_rect; win_rect = _rtgui_cursor->win_rect;
rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
@ -546,7 +544,7 @@ static void rtgui_winrect_save()
_rtgui_cursor->win_rect_has_saved = RT_TRUE; _rtgui_cursor->win_rect_has_saved = RT_TRUE;
/* save winrect left */ /* save winrect left */
fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
win_rect.x1 * _rtgui_cursor->bpp; win_rect.x1 * _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_left; winrect_ptr = _rtgui_cursor->win_left;
winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
@ -554,7 +552,7 @@ static void rtgui_winrect_save()
(win_rect.y2 - win_rect.y1), winrect_pitch); (win_rect.y2 - win_rect.y1), winrect_pitch);
/* save winrect right */ /* save winrect right */
fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
(win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp; (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_right; winrect_ptr = _rtgui_cursor->win_right;
winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp; winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
@ -562,7 +560,7 @@ static void rtgui_winrect_save()
(win_rect.y2 - win_rect.y1), winrect_pitch); (win_rect.y2 - win_rect.y1), winrect_pitch);
/* save winrect top */ /* save winrect top */
fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
(win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp; (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_top; winrect_ptr = _rtgui_cursor->win_top;
winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp; winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
@ -570,7 +568,7 @@ static void rtgui_winrect_save()
WIN_MOVE_BORDER, winrect_pitch); WIN_MOVE_BORDER, winrect_pitch);
/* save winrect bottom */ /* save winrect bottom */
fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch + fb_ptr = driver_fb + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
(win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp; (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
winrect_ptr = _rtgui_cursor->win_bottom; winrect_ptr = _rtgui_cursor->win_bottom;
display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch, display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,

View File

@ -1,677 +0,0 @@
/*
* File : rtgui_application.c
* This file is part of RTGUI in RT-Thread RTOS
* COPYRIGHT (C) 2012, 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
* 2012-01-13 Grissiom first version(just a prototype of application API)
*/
#include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_application.h>
#include <rtgui/widgets/window.h>
#ifdef _WIN32
#define RTGUI_EVENT_DEBUG
#endif
#ifdef RTGUI_EVENT_DEBUG
const char *event_string[] =
{
/* window event */
"WIN_CREATE", /* create a window */
"WIN_DESTROY", /* destroy a window */
"WIN_SHOW", /* show a window */
"WIN_HIDE", /* hide a window */
"WIN_ACTIVATE", /* activate a window */
"WIN_DEACTIVATE", /* deactivate a window */
"WIN_CLOSE", /* close a window */
"WIN_MOVE", /* move a window */
"WIN_RESIZE", /* resize a window */
"WIN_MODAL_ENTER", /* a window modals */
"SET_WM", /* set window manager */
"UPDATE_BEGIN", /* begin of update rect */
"UPDATE_END", /* end of update rect */
"MONITOR_ADD", /* add a monitor rect */
"MONITOR_REMOVE", /* remove a monitor rect*/
"PAINT", /* paint on screen */
"TIMER", /* timer */
/* clip rect information */
"CLIP_INFO", /* clip rect info */
/* mouse and keyboard event */
"MOUSE_MOTION", /* mouse motion */
"MOUSE_BUTTON", /* mouse button info */
"KBD", /* keyboard info */
/* user command event */
"COMMAND", /* user command */
/* request's status event */
"STATUS", /* request result */
"SCROLLED", /* scroll bar scrolled */
"RESIZE", /* widget resize */
};
#define DBG_MSG(x) rt_kprintf x
static void rtgui_event_dump(rt_thread_t tid, 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 = event->sender->name;
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), addr: %p",
#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
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_MODAL_ENTER:
case RTGUI_EVENT_WIN_HIDE:
{
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");
}
#else
#define DBG_MSG(x)
#define rtgui_event_dump(tid, event)
#endif
rt_bool_t rtgui_application_event_handler(struct rtgui_object* obj, rtgui_event_t* event);
static void _rtgui_application_constructor(struct rtgui_application *app)
{
/* set event handler */
rtgui_object_set_event_handler(RTGUI_OBJECT(app),
rtgui_application_event_handler);
app->name = RT_NULL;
/* set EXITED so we can destroy an application that just created */
app->state_flag = RTGUI_APPLICATION_FLAG_EXITED;
app->ref_count = 0;
app->exit_code = 0;
app->tid = RT_NULL;
app->server = RT_NULL;
app->mq = RT_NULL;
app->modal_object = RT_NULL;
app->on_idle = RT_NULL;
}
static void _rtgui_application_destructor(struct rtgui_application *app)
{
RT_ASSERT(app != RT_NULL);
rt_free(app->name);
app->name = RT_NULL;
}
DEFINE_CLASS_TYPE(application, "application",
RTGUI_OBJECT_TYPE,
_rtgui_application_constructor,
_rtgui_application_destructor,
sizeof(struct rtgui_application));
struct rtgui_application* rtgui_application_create(
rt_thread_t tid,
const char *myname)
{
struct rtgui_application *app;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(myname != RT_NULL);
/* create application */
app = RTGUI_APPLICATION(rtgui_object_create(RTGUI_APPLICATION_TYPE));
if (app == RT_NULL)
return RT_NULL;
DBG_MSG(("register a rtgui application(%s) on thread %s\n", myname, tid->name));
app->tid = tid;
/* set user thread */
tid->user_data = (rt_uint32_t)app;
app->mq = rt_mq_create("rtgui", sizeof(union rtgui_event_generic), 32, RT_IPC_FLAG_FIFO);
if (app->mq == RT_NULL)
{
rt_kprintf("mq err\n");
goto __mq_err;
}
/* set application title */
app->name = (unsigned char*)rt_strdup((char*)myname);
if (app->name != RT_NULL)
return app;
__mq_err:
rtgui_object_destroy(RTGUI_OBJECT(app));
tid->user_data = 0;
return RT_NULL;
}
#define _rtgui_application_check(app) \
do { \
RT_ASSERT(app != RT_NULL); \
RT_ASSERT(app->tid != RT_NULL); \
RT_ASSERT(app->tid->user_data != 0); \
RT_ASSERT(app->mq != RT_NULL); \
} while (0)
void rtgui_application_destroy(struct rtgui_application *app)
{
_rtgui_application_check(app);
if (!(app->state_flag & RTGUI_APPLICATION_FLAG_EXITED))
{
rt_kprintf("cannot destroy a running application: %s.\n",
app->name);
return;
}
app->tid->user_data = 0;
rt_mq_delete(app->mq);
rtgui_object_destroy(RTGUI_OBJECT(app));
}
struct rtgui_application* rtgui_application_self(void)
{
struct rtgui_application *app;
rt_thread_t self;
/* get current thread */
self = rt_thread_self();
app = (struct rtgui_application*)(self->user_data);
return app;
}
void rtgui_application_set_onidle(rtgui_idle_func onidle)
{
struct rtgui_application *app;
app = rtgui_application_self();
if (app != RT_NULL)
app->on_idle = onidle;
}
rtgui_idle_func rtgui_application_get_onidle(void)
{
struct rtgui_application *app;
app = rtgui_application_self();
if (app != RT_NULL)
return app->on_idle;
else
return RT_NULL;
}
extern rt_thread_t rt_thread_find(char* name);
rt_thread_t rtgui_application_get_server(void)
{
return rt_thread_find("rtgui");
}
rt_err_t rtgui_application_send(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
{
rt_err_t result;
struct rtgui_application *app;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event);
/* find struct rtgui_application */
app = (struct rtgui_application*) (tid->user_data);
if (app == RT_NULL)
return -RT_ERROR;
result = rt_mq_send(app->mq, event, event_size);
if (result != RT_EOK)
{
if (event->type != RTGUI_EVENT_TIMER)
rt_kprintf("send event to %s failed\n", app->tid->name);
}
return result;
}
rt_err_t rtgui_application_send_urgent(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
{
rt_err_t result;
struct rtgui_application *app;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event);
/* find rtgui_application */
app = (struct rtgui_application*) (tid->user_data);
if (app == RT_NULL)
return -RT_ERROR;
result = rt_mq_urgent(app->mq, event, event_size);
if (result != RT_EOK)
rt_kprintf("send ergent event failed\n");
return result;
}
rt_err_t rtgui_application_send_sync(rt_thread_t tid, rtgui_event_t* event, rt_size_t event_size)
{
rt_err_t r;
struct rtgui_application *app;
rt_int32_t ack_buffer, ack_status;
struct rt_mailbox ack_mb;
RT_ASSERT(tid != RT_NULL);
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
rtgui_event_dump(tid, event);
/* init ack mailbox */
r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0);
if (r!= RT_EOK)
goto __return;
app = (struct rtgui_application*) (tid->user_data);
if (app == RT_NULL)
{
r = -RT_ERROR;
goto __return;
}
event->ack = &ack_mb;
r = rt_mq_send(app->mq, event, event_size);
if (r != RT_EOK)
{
rt_kprintf("send sync event failed\n");
goto __return;
}
r = rt_mb_recv(&ack_mb, (rt_uint32_t*)&ack_status, RT_WAITING_FOREVER);
if (r!= RT_EOK)
goto __return;
if (ack_status != RTGUI_STATUS_OK)
r = -RT_ERROR;
else
r = RT_EOK;
__return:
/* fini ack mailbox */
rt_mb_detach(&ack_mb);
return r;
}
rt_err_t rtgui_application_ack(rtgui_event_t* event, rt_int32_t status)
{
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event->ack != RT_NULL);
rt_mb_send(event->ack, status);
return RT_EOK;
}
rt_err_t rtgui_application_recv(rtgui_event_t* event, rt_size_t event_size)
{
struct rtgui_application* app;
rt_err_t r;
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
app = (struct rtgui_application*) (rt_thread_self()->user_data);
if (app == RT_NULL)
return -RT_ERROR;
r = rt_mq_recv(app->mq, event, event_size, RT_WAITING_FOREVER);
return r;
}
rt_err_t rtgui_application_recv_nosuspend(rtgui_event_t* event, rt_size_t event_size)
{
struct rtgui_application *app;
rt_err_t r;
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event != 0);
app = (struct rtgui_application*) (rt_thread_self()->user_data);
if (app == RT_NULL)
return -RT_ERROR;
r = rt_mq_recv(app->mq, event, event_size, 0);
return r;
}
rt_err_t rtgui_application_recv_filter(rt_uint32_t type, rtgui_event_t* event, rt_size_t event_size)
{
struct rtgui_application *app;
RT_ASSERT(event != RT_NULL);
RT_ASSERT(event_size != 0);
app = (struct rtgui_application*) (rt_thread_self()->user_data);
if (app == RT_NULL)
return -RT_ERROR;
while (rt_mq_recv(app->mq, event, event_size, RT_WAITING_FOREVER) == RT_EOK)
{
if (event->type == type)
{
return RT_EOK;
}
else
{
if (RTGUI_OBJECT(app)->event_handler != RT_NULL)
{
RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
}
}
}
return -RT_ERROR;
}
rt_inline rt_bool_t _rtgui_application_dest_handle(
struct rtgui_application *app,
struct rtgui_event *event)
{
struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
struct rtgui_object* dest_object = RTGUI_OBJECT(wevent->wid);
if (dest_object != RT_NULL)
{
if (dest_object->event_handler != RT_NULL)
return dest_object->event_handler(RTGUI_OBJECT(dest_object), event);
else
return RT_FALSE;
}
else
{
rt_kprintf("RTGUI ERROR:server sent a event(%d) without wid\n", event->type);
return RT_FALSE;
}
}
rt_bool_t rtgui_application_event_handler(struct rtgui_object* object, rtgui_event_t* event)
{
struct rtgui_application* app;
RT_ASSERT(object != RT_NULL);
RT_ASSERT(event != RT_NULL);
app = RTGUI_APPLICATION(object);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
case RTGUI_EVENT_CLIP_INFO:
case RTGUI_EVENT_WIN_ACTIVATE:
case RTGUI_EVENT_WIN_DEACTIVATE:
case RTGUI_EVENT_WIN_CLOSE:
case RTGUI_EVENT_WIN_MOVE:
case RTGUI_EVENT_KBD:
_rtgui_application_dest_handle(app, event);
break;
case RTGUI_EVENT_MOUSE_BUTTON:
case RTGUI_EVENT_MOUSE_MOTION:
{
struct rtgui_event_win* wevent = (struct rtgui_event_win*)event;
struct rtgui_object* dest_object = RTGUI_OBJECT(wevent->wid);
// FIXME: let application determine the dest_wiget but not in sever
// so we can combine this handler with above one
if (app->modal_object != RT_NULL &&
dest_object != app->modal_object)
{
// rt_kprintf("discard event %s that is not sent to modal object\n",
// event_string[event->type]);
}
else
{
_rtgui_application_dest_handle(app, event);
}
}
break;
case RTGUI_EVENT_TIMER:
{
struct rtgui_timer* timer;
struct rtgui_event_timer* etimer = (struct rtgui_event_timer*) event;
timer = etimer->timer;
if (timer->timeout != RT_NULL)
{
/* call timeout function */
timer->timeout(timer, timer->user_data);
}
}
break;
case RTGUI_EVENT_COMMAND:
{
struct rtgui_event_command *ecmd = (struct rtgui_event_command *)event;
if (ecmd->wid != RT_NULL)
return _rtgui_application_dest_handle(app, event);
}
default:
return rtgui_object_event_handler(object, event);
}
return RT_TRUE;
}
rt_inline void _rtgui_application_event_loop(struct rtgui_application *app)
{
rt_err_t result;
rt_uint16_t current_ref;
struct rtgui_event *event;
_rtgui_application_check(app);
/* point to event buffer */
event = (struct rtgui_event*)app->event_buffer;
current_ref = ++app->ref_count;
while (current_ref <= app->ref_count)
{
RT_ASSERT(current_ref == app->ref_count);
if (app->on_idle != RT_NULL)
{
result = rtgui_application_recv_nosuspend(event, sizeof(union rtgui_event_generic));
if (result == RT_EOK)
RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
else if (result == -RT_ETIMEOUT)
app->on_idle(RTGUI_OBJECT(app), RT_NULL);
}
else
{
result = rtgui_application_recv(event, sizeof(union rtgui_event_generic));
if (result == RT_EOK)
RTGUI_OBJECT(app)->event_handler(RTGUI_OBJECT(app), event);
}
}
}
rt_base_t rtgui_application_run(struct rtgui_application *app)
{
_rtgui_application_check(app);
app->state_flag &= ~RTGUI_APPLICATION_FLAG_EXITED;
_rtgui_application_event_loop(app);
if (app->ref_count == 0)
app->state_flag |= RTGUI_APPLICATION_FLAG_EXITED;
return app->exit_code;
}
void rtgui_application_exit(struct rtgui_application* app, rt_uint16_t code)
{
--app->ref_count;
app->exit_code = code;
}

View File

@ -16,14 +16,16 @@
#include <rtgui/event.h> #include <rtgui/event.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_object.h> #include <rtgui/rtgui_object.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/driver.h> #include <rtgui/driver.h>
#include "mouse.h" #include "mouse.h"
#include "topwin.h" #include "topwin.h"
static struct rt_thread *rtgui_server_tid; static struct rt_thread *rtgui_server_tid;
static struct rtgui_application *rtgui_server_application;
static struct rtgui_app *rtgui_server_application = RT_NULL;
static struct rtgui_app *rtgui_wm_application = RT_NULL;
void rtgui_server_handle_update(struct rtgui_event_update_end* event) void rtgui_server_handle_update(struct rtgui_event_update_end* event)
{ {
@ -85,7 +87,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
} }
/* send to client thread */ /* send to client thread */
rtgui_application_send(topwin->tid, &(ewin.parent), sizeof(ewin)); rtgui_send(topwin->tid, &(ewin.parent), sizeof(ewin));
return; return;
} }
@ -101,7 +103,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
if (rtgui_topwin_get_focus() != wnd) if (rtgui_topwin_get_focus() != wnd)
{ {
/* raise this window */ /* raise this window */
rtgui_topwin_activate_win(wnd); rtgui_topwin_activate_topwin(wnd);
} }
if (wnd->title != RT_NULL && if (wnd->title != RT_NULL &&
@ -112,7 +114,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
else else
{ {
/* send mouse event to thread */ /* send mouse event to thread */
rtgui_application_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_mouse)); rtgui_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_mouse));
} }
return ; return ;
} }
@ -144,7 +146,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
{ {
event->wid = last_monitor_topwin->wid; event->wid = last_monitor_topwin->wid;
/* send mouse motion event */ /* send mouse motion event */
rtgui_application_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); rtgui_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
} }
if (last_monitor_topwin != win) if (last_monitor_topwin != win)
@ -155,7 +157,7 @@ void rtgui_server_handle_mouse_motion(struct rtgui_event_mouse* event)
event->wid = last_monitor_topwin->wid; event->wid = last_monitor_topwin->wid;
/* send mouse motion event */ /* send mouse motion event */
rtgui_application_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); rtgui_send(last_monitor_topwin->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
} }
} }
@ -181,7 +183,7 @@ void rtgui_server_handle_kbd(struct rtgui_event_kbd* event)
event->wid = wnd->wid; event->wid = wnd->wid;
/* send keyboard event to thread */ /* send keyboard event to thread */
rtgui_application_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd)); rtgui_send(wnd->tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd));
return; return;
} }
@ -200,58 +202,113 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
/* dispatch event */ /* dispatch event */
switch (event->type) switch (event->type)
{ {
case RTGUI_EVENT_APP_CREATE:
case RTGUI_EVENT_APP_DESTROY:
if (rtgui_wm_application != RT_NULL)
{
/* forward event to wm application */
rtgui_send(rtgui_wm_application->tid, event, sizeof(struct rtgui_event_application));
}
else
{
/* always ack with OK */
rtgui_ack(event, RTGUI_STATUS_OK);
}
break;
/* mouse and keyboard event */
case RTGUI_EVENT_MOUSE_MOTION:
/* handle mouse motion event */
rtgui_server_handle_mouse_motion((struct rtgui_event_mouse*)event);
break;
case RTGUI_EVENT_MOUSE_BUTTON:
/* handle mouse button */
rtgui_server_handle_mouse_btn((struct rtgui_event_mouse*)event);
break;
case RTGUI_EVENT_KBD:
/* handle keyboard event */
rtgui_server_handle_kbd((struct rtgui_event_kbd*)event);
break;
/* window event */ /* window event */
case RTGUI_EVENT_WIN_CREATE: case RTGUI_EVENT_WIN_CREATE:
if (rtgui_topwin_add((struct rtgui_event_win_create*)event) == RT_EOK) if (rtgui_topwin_add((struct rtgui_event_win_create*)event) == RT_EOK)
rtgui_application_ack(event, RTGUI_STATUS_OK); rtgui_ack(event, RTGUI_STATUS_OK);
else else
rtgui_application_ack(event, RTGUI_STATUS_ERROR); rtgui_ack(event, RTGUI_STATUS_ERROR);
break; break;
case RTGUI_EVENT_WIN_SHOW:
if (rtgui_topwin_show((struct rtgui_event_win*)event) == RT_EOK)
rtgui_ack(event, RTGUI_STATUS_OK);
else
rtgui_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_HIDE:
if (rtgui_topwin_hide((struct rtgui_event_win*)event) == RT_EOK)
rtgui_ack(event, RTGUI_STATUS_OK);
else
rtgui_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_MOVE:
if (rtgui_topwin_move((struct rtgui_event_win_move*)event) == RT_EOK)
rtgui_ack(event, RTGUI_STATUS_OK);
else
rtgui_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_MODAL_ENTER:
if (rtgui_topwin_modal_enter((struct rtgui_event_win_modal_enter*)event) == RT_EOK)
rtgui_ack(event, RTGUI_STATUS_OK);
else
rtgui_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_ACTIVATE:
if (rtgui_topwin_activate((struct rtgui_event_win_activate*)event) == RT_EOK)
rtgui_ack(event, RTGUI_STATUS_OK);
else
rtgui_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_DESTROY: case RTGUI_EVENT_WIN_DESTROY:
if (last_monitor_topwin != RT_NULL && if (last_monitor_topwin != RT_NULL &&
last_monitor_topwin->wid == ((struct rtgui_event_win*)event)->wid) last_monitor_topwin->wid == ((struct rtgui_event_win*)event)->wid)
last_monitor_topwin = RT_NULL; last_monitor_topwin = RT_NULL;
if (rtgui_topwin_remove(((struct rtgui_event_win*)event)->wid) == RT_EOK) if (rtgui_topwin_remove(((struct rtgui_event_win*)event)->wid) == RT_EOK)
rtgui_application_ack(event, RTGUI_STATUS_OK); rtgui_ack(event, RTGUI_STATUS_OK);
else else
rtgui_application_ack(event, RTGUI_STATUS_ERROR); rtgui_ack(event, RTGUI_STATUS_ERROR);
break; break;
case RTGUI_EVENT_WIN_SHOW:
if (rtgui_topwin_show((struct rtgui_event_win*)event) == RT_EOK)
rtgui_application_ack(event, RTGUI_STATUS_OK);
else
rtgui_application_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_HIDE:
if (rtgui_topwin_hide((struct rtgui_event_win*)event) == RT_EOK)
rtgui_application_ack(event, RTGUI_STATUS_OK);
else
rtgui_application_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_MOVE:
if (rtgui_topwin_move((struct rtgui_event_win_move*)event) == RT_EOK)
rtgui_application_ack(event, RTGUI_STATUS_OK);
else
rtgui_application_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_MODAL_ENTER:
if (rtgui_topwin_modal_enter((struct rtgui_event_win_modal_enter*)event) == RT_EOK)
rtgui_application_ack(event, RTGUI_STATUS_OK);
else
rtgui_application_ack(event, RTGUI_STATUS_ERROR);
break;
case RTGUI_EVENT_WIN_RESIZE: case RTGUI_EVENT_WIN_RESIZE:
rtgui_topwin_resize(((struct rtgui_event_win_resize*)event)->wid, rtgui_topwin_resize(((struct rtgui_event_win_resize*)event)->wid,
&(((struct rtgui_event_win_resize*)event)->rect)); &(((struct rtgui_event_win_resize*)event)->rect));
break; break;
case RTGUI_EVENT_SET_WM:
if (rtgui_wm_application != RT_NULL)
{
rtgui_ack(event, RTGUI_STATUS_ERROR);
}
else
{
struct rtgui_event_set_wm *set_wm;
set_wm = (struct rtgui_event_set_wm*) event;
rtgui_wm_application = set_wm->app;
rtgui_ack(event, RTGUI_STATUS_OK);
}
break;
/* other event */ /* other event */
case RTGUI_EVENT_COMMAND:
break;
case RTGUI_EVENT_UPDATE_BEGIN: case RTGUI_EVENT_UPDATE_BEGIN:
#ifdef RTGUI_USING_MOUSE_CURSOR #ifdef RTGUI_USING_MOUSE_CURSOR
/* hide cursor */ /* hide cursor */
@ -272,25 +329,6 @@ static rt_bool_t rtgui_server_event_handler(struct rtgui_object *object,
/* handle mouse monitor */ /* handle mouse monitor */
rtgui_server_handle_monitor_add((struct rtgui_event_monitor*)event); rtgui_server_handle_monitor_add((struct rtgui_event_monitor*)event);
break; break;
/* mouse and keyboard event */
case RTGUI_EVENT_MOUSE_MOTION:
/* handle mouse motion event */
rtgui_server_handle_mouse_motion((struct rtgui_event_mouse*)event);
break;
case RTGUI_EVENT_MOUSE_BUTTON:
/* handle mouse button */
rtgui_server_handle_mouse_btn((struct rtgui_event_mouse*)event);
break;
case RTGUI_EVENT_KBD:
/* handle keyboard event */
rtgui_server_handle_kbd((struct rtgui_event_kbd*)event);
break;
case RTGUI_EVENT_COMMAND:
break;
} }
return RT_TRUE; return RT_TRUE;
@ -307,8 +345,8 @@ static void rtgui_server_entry(void* parameter)
SetThreadPriority(hCurrentThread, THREAD_PRIORITY_HIGHEST); SetThreadPriority(hCurrentThread, THREAD_PRIORITY_HIGHEST);
#endif #endif
/* register rtgui server thread */ /* create rtgui server application */
rtgui_server_application = rtgui_application_create(rtgui_server_tid, rtgui_server_application = rtgui_app_create(rtgui_server_tid,
"rtgui"); "rtgui");
if (rtgui_server_application == RT_NULL) if (rtgui_server_application == RT_NULL)
return; return;
@ -321,16 +359,16 @@ static void rtgui_server_entry(void* parameter)
rtgui_mouse_show_cursor(); rtgui_mouse_show_cursor();
#endif #endif
rtgui_application_run(rtgui_server_application); rtgui_app_run(rtgui_server_application);
rtgui_application_destroy(rtgui_server_application); rtgui_app_destroy(rtgui_server_application);
rtgui_server_application = RT_NULL; rtgui_server_application = RT_NULL;
} }
void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size) void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size)
{ {
if (rtgui_server_tid != RT_NULL) if (rtgui_server_tid != RT_NULL)
rtgui_application_send(rtgui_server_tid, event, size); rtgui_send(rtgui_server_tid, event, size);
else else
rt_kprintf("post when server is not running\n"); rt_kprintf("post when server is not running\n");
} }
@ -338,7 +376,7 @@ void rtgui_server_post_event(struct rtgui_event* event, rt_size_t size)
rt_err_t rtgui_server_post_event_sync(struct rtgui_event* event, rt_size_t size) rt_err_t rtgui_server_post_event_sync(struct rtgui_event* event, rt_size_t size)
{ {
if (rtgui_server_tid != RT_NULL) if (rtgui_server_tid != RT_NULL)
return rtgui_application_send_sync(rtgui_server_tid, event, size); return rtgui_send_sync(rtgui_server_tid, event, size);
else else
{ {
rt_kprintf("post when server is not running\n"); rt_kprintf("post when server is not running\n");

View File

@ -19,41 +19,36 @@
#include <rtgui/image.h> #include <rtgui/image.h>
#include <rtgui/rtgui_theme.h> #include <rtgui/rtgui_theme.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/widgets/window.h> #include <rtgui/widgets/window.h>
/* This list is divided into two parts. The first part is the shown list, in /* This list is divided into two parts. The first part is the shown list, in
* which all the windows have the WINTITLE_SHOWN flag set. Second part is the * which all the windows have the WINTITLE_SHOWN flag set. Second part is the
* hidden list, in which all the windows don't have WINTITLE_SHOWN flag. * hidden items, in which all the windows don't have WINTITLE_SHOWN flag.
* *
* The active window is the one that would receive kbd events. It should always * The active window is the one that would receive kbd events. It should always
* in the first tree. The order of this list is the order of the windows. * be in the first tree. The order of this list is the order of the windows.
* Thus, the first item is the top most window and the last item is the bottom * Top window can always clip the window beneath it when the two
* window. Top window can always clip the window beneath it when the two
* overlapping. Child window can always clip it's parent. Slibing windows can * overlapping. Child window can always clip it's parent. Slibing windows can
* clip each other with the same rule as this list. Thus, each child list is * clip each other with the same rule as this list. Each child list is the same
* the same as _rtgui_topwin_list. This forms the hierarchy tree structure of * as _rtgui_topwin_list. This forms the hierarchy tree structure of all
* all windows. * windows.
* *
* The hidden list have no specific order. * Thus, the left most leaf of the tree is the top most window and the right
* most root node is the bottom window. The hidden part have no specific
* order.
*/ */
static struct rtgui_dlist_node _rtgui_topwin_list; static struct rtgui_dlist_node _rtgui_topwin_list;
#define get_topwin_from_list(list_entry) \ #define get_topwin_from_list(list_entry) \
(rtgui_dlist_entry((list_entry), struct rtgui_topwin, list)) (rtgui_dlist_entry((list_entry), struct rtgui_topwin, list))
#ifdef RTGUI_USING_DESKTOP_WINDOW
static struct rtgui_topwin *the_desktop_topwin;
#define IS_ROOT_WIN(topwin) ((topwin)->parent == the_desktop_topwin)
#else
#define IS_ROOT_WIN(topwin) ((topwin)->parent == RT_NULL) #define IS_ROOT_WIN(topwin) ((topwin)->parent == RT_NULL)
#endif
static struct rt_semaphore _rtgui_topwin_lock; static struct rt_semaphore _rtgui_topwin_lock;
static void rtgui_topwin_update_clip(void); static void rtgui_topwin_update_clip(void);
static void rtgui_topwin_redraw(struct rtgui_rect* rect); static void rtgui_topwin_redraw(struct rtgui_rect* rect);
static void _rtgui_topwin_activate_next(void); static void _rtgui_topwin_activate_next(enum rtgui_topwin_flag);
void rtgui_topwin_init(void) void rtgui_topwin_init(void)
{ {
@ -113,11 +108,6 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event)
{ {
topwin->parent = RT_NULL; topwin->parent = RT_NULL;
rtgui_dlist_insert_before(&_rtgui_topwin_list, &topwin->list); rtgui_dlist_insert_before(&_rtgui_topwin_list, &topwin->list);
#ifdef RTGUI_USING_DESKTOP_WINDOW
RT_ASSERT(the_desktop_topwin == RT_NULL);
RT_ASSERT(event->parent.user & RTGUI_WIN_STYLE_DESKTOP);
the_desktop_topwin = topwin;
#endif
} }
else else
{ {
@ -138,6 +128,8 @@ rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event)
if (event->parent.user & RTGUI_WIN_STYLE_CLOSEBOX) topwin->flag |= WINTITLE_CLOSEBOX; if (event->parent.user & RTGUI_WIN_STYLE_CLOSEBOX) topwin->flag |= WINTITLE_CLOSEBOX;
if (!(event->parent.user & RTGUI_WIN_STYLE_NO_BORDER)) topwin->flag |= WINTITLE_BORDER; if (!(event->parent.user & RTGUI_WIN_STYLE_NO_BORDER)) topwin->flag |= WINTITLE_BORDER;
if (event->parent.user & RTGUI_WIN_STYLE_NO_FOCUS) topwin->flag |= WINTITLE_NOFOCUS; if (event->parent.user & RTGUI_WIN_STYLE_NO_FOCUS) topwin->flag |= WINTITLE_NOFOCUS;
if (event->parent.user & RTGUI_WIN_STYLE_ONTOP) topwin->flag |= WINTITLE_ONTOP;
if (event->parent.user & RTGUI_WIN_STYLE_ONBTM) topwin->flag |= WINTITLE_ONBTM;
if(!(topwin->flag & WINTITLE_NO) || (topwin->flag & WINTITLE_BORDER)) if(!(topwin->flag & WINTITLE_NO) || (topwin->flag & WINTITLE_BORDER))
{ {
@ -195,12 +187,31 @@ static struct rtgui_topwin* _rtgui_topwin_get_topmost_child_shown(struct rtgui_t
return topwin; return topwin;
} }
static struct rtgui_topwin* _rtgui_topwin_get_topmost_window_shown(void) static rt_bool_t _rtgui_topwin_in_layer(struct rtgui_topwin *topwin, enum rtgui_topwin_flag flag)
{ {
if (!(get_topwin_from_list(_rtgui_topwin_list.next)->flag & WINTITLE_SHOWN)) return (topwin->flag & (WINTITLE_ONTOP|WINTITLE_ONBTM))
return RT_NULL; == (flag & (WINTITLE_ONTOP|WINTITLE_ONBTM));
else }
return _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(_rtgui_topwin_list.next));
/* find the topmost window shown in the layer set by flag. The flag has many
* other infomations but we only use the ONTOP/ONBTM */
static struct rtgui_topwin* _rtgui_topwin_get_topmost_window_shown(enum rtgui_topwin_flag flag)
{
struct rtgui_dlist_node *node;
rtgui_dlist_foreach(node, &_rtgui_topwin_list, next)
{
struct rtgui_topwin *topwin = get_topwin_from_list(node);
/* reach the hidden region no window shown in current layer */
if (!(topwin->flag & WINTITLE_SHOWN))
return RT_NULL;
if (_rtgui_topwin_in_layer(topwin, flag))
return _rtgui_topwin_get_topmost_child_shown(topwin);
}
/* no window in current layer is shown */
return RT_NULL;
} }
/* a hidden parent will hide it's children. Top level window can be shown at /* a hidden parent will hide it's children. Top level window can be shown at
@ -286,24 +297,23 @@ rt_err_t rtgui_topwin_remove(struct rtgui_win* wid)
old_focus = rtgui_topwin_get_focus(); old_focus = rtgui_topwin_get_focus();
// TODO: if the window is hidden, there is no need to update the window
// region
_rtgui_topwin_union_region_tree(topwin, &region);
if (topwin->flag & WINTITLE_SHOWN)
rtgui_topwin_update_clip();
if (old_focus == topwin)
{
_rtgui_topwin_activate_next();
}
/* redraw the old rect */
rtgui_topwin_redraw(rtgui_region_extents(&region));
/* remove the root from _rtgui_topwin_list will remove the whole tree from /* remove the root from _rtgui_topwin_list will remove the whole tree from
* _rtgui_topwin_list. */ * _rtgui_topwin_list. */
rtgui_dlist_remove(&topwin->list); rtgui_dlist_remove(&topwin->list);
if (old_focus == topwin)
{
_rtgui_topwin_activate_next(topwin->flag);
}
if (topwin->flag & WINTITLE_SHOWN)
{
rtgui_topwin_update_clip();
/* redraw the old rect */
_rtgui_topwin_union_region_tree(topwin, &region);
rtgui_topwin_redraw(rtgui_region_extents(&region));
}
_rtgui_topwin_free_tree(topwin); _rtgui_topwin_free_tree(topwin);
return RT_EOK; return RT_EOK;
@ -327,7 +337,7 @@ static void _rtgui_topwin_only_activate(struct rtgui_topwin *topwin)
topwin->flag |= WINTITLE_ACTIVATE; topwin->flag |= WINTITLE_ACTIVATE;
event.wid = topwin->wid; event.wid = topwin->wid;
rtgui_application_send(topwin->tid, &(event.parent), sizeof(struct rtgui_event_win)); rtgui_send(topwin->tid, &(event.parent), sizeof(struct rtgui_event_win));
/* redraw title */ /* redraw title */
if (topwin->title != RT_NULL) if (topwin->title != RT_NULL)
@ -336,11 +346,13 @@ static void _rtgui_topwin_only_activate(struct rtgui_topwin *topwin)
} }
} }
static void _rtgui_topwin_activate_next(void) /* activate next window in the same layer as flag. The flag has many other
* infomations but we only use the ONTOP/ONBTM */
static void _rtgui_topwin_activate_next(enum rtgui_topwin_flag flag)
{ {
struct rtgui_topwin *topwin; struct rtgui_topwin *topwin;
topwin = _rtgui_topwin_get_topmost_window_shown(); topwin = _rtgui_topwin_get_topmost_window_shown(flag);
if (topwin == RT_NULL) if (topwin == RT_NULL)
return; return;
@ -358,7 +370,7 @@ static void _rtgui_topwin_deactivate(struct rtgui_topwin *topwin)
RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event); RTGUI_EVENT_WIN_DEACTIVATE_INIT(&event);
event.wid = topwin->wid; event.wid = topwin->wid;
rtgui_application_send(topwin->tid, rtgui_send(topwin->tid,
&event.parent, sizeof(struct rtgui_event_win)); &event.parent, sizeof(struct rtgui_event_win));
topwin->flag &= ~WINTITLE_ACTIVATE; topwin->flag &= ~WINTITLE_ACTIVATE;
@ -376,17 +388,6 @@ static void _rtgui_topwin_move_whole_tree2top(struct rtgui_topwin *topwin)
RT_ASSERT(topwin != RT_NULL); RT_ASSERT(topwin != RT_NULL);
#ifdef RTGUI_USING_DESKTOP_WINDOW
/* handle desktop window separately, avoid calling
* _rtgui_topwin_get_root_win */
if (topwin == the_desktop_topwin)
{
rtgui_dlist_remove(&the_desktop_topwin->list);
rtgui_dlist_insert_after(&_rtgui_topwin_list, &the_desktop_topwin->list);
return;
}
#endif
/* move the whole tree */ /* move the whole tree */
topparent = _rtgui_topwin_get_root_win(topwin); topparent = _rtgui_topwin_get_root_win(topwin);
RT_ASSERT(topparent != RT_NULL); RT_ASSERT(topparent != RT_NULL);
@ -394,20 +395,58 @@ static void _rtgui_topwin_move_whole_tree2top(struct rtgui_topwin *topwin)
/* remove node from hidden list */ /* remove node from hidden list */
rtgui_dlist_remove(&topparent->list); rtgui_dlist_remove(&topparent->list);
/* add node to show list */ /* add node to show list */
#ifdef RTGUI_USING_DESKTOP_WINDOW if (topwin->flag & WINTITLE_ONTOP)
rtgui_dlist_insert_after(&the_desktop_topwin->child_list, &(topparent->list)); {
#else rtgui_dlist_insert_after(&_rtgui_topwin_list, &(topparent->list));
rtgui_dlist_insert_after(&_rtgui_topwin_list, &(topparent->list)); }
#endif else if (topwin->flag & WINTITLE_ONBTM)
{
/* botton layer window, before the fisrt bottom window or hidden window. */
struct rtgui_topwin *ntopwin = get_topwin_from_list(&_rtgui_topwin_list);
struct rtgui_dlist_node *node;
rtgui_dlist_foreach(node, &_rtgui_topwin_list, next)
{
ntopwin = get_topwin_from_list(node);
if ((ntopwin->flag & WINTITLE_ONBTM)
|| !(ntopwin->flag & WINTITLE_SHOWN))
break;
}
/* all other windows are shown top/normal layer windows. Insert it as
* the last window. */
if (node == &_rtgui_topwin_list)
rtgui_dlist_insert_before(&_rtgui_topwin_list, &(topparent->list));
else
rtgui_dlist_insert_before(&ntopwin->list, &(topparent->list));
}
else
{
/* normal layer window, before the fisrt shown normal layer window. */
struct rtgui_topwin *ntopwin = get_topwin_from_list(&_rtgui_topwin_list);
struct rtgui_dlist_node *node;
rtgui_dlist_foreach(node, &_rtgui_topwin_list, next)
{
ntopwin = get_topwin_from_list(node);
if (!((ntopwin->flag & WINTITLE_ONTOP)
&& (ntopwin->flag & WINTITLE_SHOWN)))
break;
}
/* all other windows are shown top layer windows. Insert it as
* the last window. */
if (node == &_rtgui_topwin_list)
rtgui_dlist_insert_before(&_rtgui_topwin_list, &(topparent->list));
else
rtgui_dlist_insert_before(&ntopwin->list, &(topparent->list));
}
} }
static void _rtgui_topwin_raise_topwin_in_tree(struct rtgui_topwin *topwin) static void _rtgui_topwin_raise_in_sibling(struct rtgui_topwin *topwin)
{ {
struct rtgui_dlist_node *win_level; struct rtgui_dlist_node *win_level;
RT_ASSERT(topwin != RT_NULL); RT_ASSERT(topwin != RT_NULL);
_rtgui_topwin_move_whole_tree2top(topwin);
if (topwin->parent == RT_NULL) if (topwin->parent == RT_NULL)
win_level = &_rtgui_topwin_list; win_level = &_rtgui_topwin_list;
else else
@ -416,33 +455,64 @@ static void _rtgui_topwin_raise_topwin_in_tree(struct rtgui_topwin *topwin)
rtgui_dlist_insert_after(win_level, &topwin->list); rtgui_dlist_insert_after(win_level, &topwin->list);
} }
/* it will do 2 things. One is moving the whole tree(the root of the tree) to
* the front and the other is moving topwin to the front of it's siblings. */
static void _rtgui_topwin_raise_tree_from_root(struct rtgui_topwin *topwin)
{
RT_ASSERT(topwin != RT_NULL);
_rtgui_topwin_move_whole_tree2top(topwin);
/* root win is aleady moved by _rtgui_topwin_move_whole_tree2top */
if (!IS_ROOT_WIN(topwin))
_rtgui_topwin_raise_in_sibling(topwin);
}
/* activate a win means: /* activate a win means:
* - deactivate the old focus win if any * - deactivate the old focus win if any
* - raise the window to the front of it's siblings * - raise the window to the front of it's siblings
* - activate a win * - activate a win
*/ */
void rtgui_topwin_activate_win(struct rtgui_topwin* topwin) rt_err_t rtgui_topwin_activate(struct rtgui_event_win_activate* event)
{
struct rtgui_topwin *topwin;
RT_ASSERT(event);
topwin = rtgui_topwin_search_in_list(event->wid, &_rtgui_topwin_list);
if (topwin == RT_NULL)
return -RT_ERROR;
return rtgui_topwin_activate_topwin(topwin);
}
rt_err_t rtgui_topwin_activate_topwin(struct rtgui_topwin* topwin)
{ {
struct rtgui_topwin *old_focus_topwin; struct rtgui_topwin *old_focus_topwin;
RT_ASSERT(topwin != RT_NULL); RT_ASSERT(topwin != RT_NULL);
if (!(topwin->flag & WINTITLE_SHOWN))
return -RT_ERROR;
if (topwin->flag & WINTITLE_NOFOCUS) if (topwin->flag & WINTITLE_NOFOCUS)
{ {
/* just raise it, not affect others. */ /* just raise it, not affect others. */
_rtgui_topwin_raise_topwin_in_tree(topwin); _rtgui_topwin_raise_tree_from_root(topwin);
/* update clip info */ /* update clip info */
rtgui_topwin_update_clip(); rtgui_topwin_update_clip();
return; return RT_EOK;
} }
if (topwin->flag & WINTITLE_ACTIVATE)
return RT_EOK;
old_focus_topwin = rtgui_topwin_get_focus(); old_focus_topwin = rtgui_topwin_get_focus();
/* if topwin has the focus, it shoule have WINTITLE_ACTIVATE set and
* returned above. */
RT_ASSERT(old_focus_topwin != topwin);
if (old_focus_topwin == topwin) _rtgui_topwin_raise_tree_from_root(topwin);
return;
_rtgui_topwin_raise_topwin_in_tree(topwin);
/* update clip info */ /* update clip info */
rtgui_topwin_update_clip(); rtgui_topwin_update_clip();
@ -454,6 +524,8 @@ void rtgui_topwin_activate_win(struct rtgui_topwin* topwin)
} }
_rtgui_topwin_only_activate(topwin); _rtgui_topwin_only_activate(topwin);
return RT_EOK;
} }
/* map func to the topwin tree in preorder. /* map func to the topwin tree in preorder.
@ -486,6 +558,10 @@ rt_inline void _rtgui_topwin_mark_hidden(struct rtgui_topwin *topwin)
rt_inline void _rtgui_topwin_mark_shown(struct rtgui_topwin *topwin) rt_inline void _rtgui_topwin_mark_shown(struct rtgui_topwin *topwin)
{ {
if (!(topwin->flag & WINTITLE_SHOWN)
&& RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(topwin->wid)))
return;
topwin->flag |= WINTITLE_SHOWN; topwin->flag |= WINTITLE_SHOWN;
if (topwin->title != RT_NULL) if (topwin->title != RT_NULL)
{ {
@ -504,10 +580,12 @@ static void _rtgui_topwin_draw_tree(struct rtgui_topwin *topwin, struct rtgui_ev
} }
epaint->wid = topwin->wid; epaint->wid = topwin->wid;
rtgui_application_send(topwin->tid, &(epaint->parent), sizeof(struct rtgui_event_paint)); rtgui_send(topwin->tid, &(epaint->parent), sizeof(struct rtgui_event_paint));
rtgui_dlist_foreach(node, &topwin->child_list, prev) rtgui_dlist_foreach(node, &topwin->child_list, prev)
{ {
if (!(get_topwin_from_list(node)->flag & WINTITLE_SHOWN))
return;
_rtgui_topwin_draw_tree(get_topwin_from_list(node), epaint); _rtgui_topwin_draw_tree(get_topwin_from_list(node), epaint);
} }
} }
@ -519,7 +597,7 @@ static void _rtgui_topwin_show_tree(struct rtgui_topwin *topwin, struct rtgui_ev
RT_ASSERT(topwin != RT_NULL); RT_ASSERT(topwin != RT_NULL);
RT_ASSERT(epaint != RT_NULL); RT_ASSERT(epaint != RT_NULL);
_rtgui_topwin_raise_topwin_in_tree(topwin); _rtgui_topwin_raise_tree_from_root(topwin);
/* we have to mark the _all_ tree before update_clip because update_clip /* we have to mark the _all_ tree before update_clip because update_clip
* will stop as hidden windows */ * will stop as hidden windows */
_rtgui_topwin_preorder_map(topwin, _rtgui_topwin_mark_shown); _rtgui_topwin_preorder_map(topwin, _rtgui_topwin_mark_shown);
@ -532,14 +610,6 @@ static void _rtgui_topwin_show_tree(struct rtgui_topwin *topwin, struct rtgui_ev
_rtgui_topwin_draw_tree(topwin, epaint); _rtgui_topwin_draw_tree(topwin, epaint);
} }
/** show a window
*
* If any parent window in the hierarchy tree is hidden, this window won't be
* shown. If this window could be shown, all the child windows will be shown as
* well. The topmost child will be active.
*
* Top level window(parent == RT_NULL) can always be shown.
*/
rt_err_t rtgui_topwin_show(struct rtgui_event_win* event) rt_err_t rtgui_topwin_show(struct rtgui_event_win* event)
{ {
struct rtgui_topwin *topwin, *old_focus; struct rtgui_topwin *topwin, *old_focus;
@ -548,25 +618,30 @@ rt_err_t rtgui_topwin_show(struct rtgui_event_win* event)
RTGUI_EVENT_PAINT_INIT(&epaint); RTGUI_EVENT_PAINT_INIT(&epaint);
/* find in hide list */
topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list); topwin = rtgui_topwin_search_in_list(wid, &_rtgui_topwin_list);
if (topwin == RT_NULL || /* no such a window recorded */
!_rtgui_topwin_could_show(topwin)) if (topwin == RT_NULL)
return -RT_ERROR; return -RT_ERROR;
/* if the parent is hidden, just mark it as shown. It will be shown when
* the parent is shown. */
if (!_rtgui_topwin_could_show(topwin))
{
topwin->flag |= WINTITLE_SHOWN;
_rtgui_topwin_raise_in_sibling(topwin);
return -RT_ERROR;
}
old_focus = rtgui_topwin_get_focus(); old_focus = rtgui_topwin_get_focus();
_rtgui_topwin_show_tree(topwin, &epaint); _rtgui_topwin_show_tree(topwin, &epaint);
/* we don't want double clipping(bare rtgui_topwin_activate_win will clip), /* we don't want double clipping(bare rtgui_topwin_activate_win will clip),
* so we have to do deactivate/activate manually. */ * so we have to do deactivate/activate manually. */
if (old_focus == RT_NULL) if (old_focus && old_focus != topwin)
_rtgui_topwin_only_activate(topwin);
else if (old_focus != topwin)
{
_rtgui_topwin_deactivate(old_focus); _rtgui_topwin_deactivate(old_focus);
_rtgui_topwin_only_activate(topwin); _rtgui_topwin_only_activate(topwin);
}
return RT_EOK; return RT_EOK;
} }
@ -633,7 +708,7 @@ rt_err_t rtgui_topwin_hide(struct rtgui_event_win* event)
if (old_focus_topwin == topwin) if (old_focus_topwin == topwin)
{ {
_rtgui_topwin_activate_next(); _rtgui_topwin_activate_next(topwin->flag);
} }
return RT_EOK; return RT_EOK;
@ -697,7 +772,7 @@ rt_err_t rtgui_topwin_move(struct rtgui_event_win_move* event)
struct rtgui_event_paint epaint; struct rtgui_event_paint epaint;
RTGUI_EVENT_PAINT_INIT(&epaint); RTGUI_EVENT_PAINT_INIT(&epaint);
epaint.wid = topwin->wid; epaint.wid = topwin->wid;
rtgui_application_send(topwin->tid, &(epaint.parent), sizeof(epaint)); rtgui_send(topwin->tid, &(epaint.parent), sizeof(epaint));
} }
return RT_EOK; return RT_EOK;
@ -772,24 +847,7 @@ static struct rtgui_topwin* _rtgui_topwin_get_focus_from_list(struct rtgui_dlist
struct rtgui_topwin* rtgui_topwin_get_focus(void) struct rtgui_topwin* rtgui_topwin_get_focus(void)
{ {
#if 1
// debug code
struct rtgui_topwin *topwin = _rtgui_topwin_get_focus_from_list(&_rtgui_topwin_list);
if (topwin != RT_NULL)
#ifdef RTGUI_USING_DESKTOP_WINDOW
RT_ASSERT(topwin == the_desktop_topwin ||\
get_topwin_from_list(the_desktop_topwin->child_list.next) ==
_rtgui_topwin_get_root_win(topwin));
#else
RT_ASSERT(get_topwin_from_list(_rtgui_topwin_list.next) ==
_rtgui_topwin_get_root_win(topwin));
#endif
return topwin;
#else
return _rtgui_topwin_get_focus_from_list(&_rtgui_topwin_list); return _rtgui_topwin_get_focus_from_list(&_rtgui_topwin_list);
#endif
} }
static struct rtgui_topwin* _rtgui_topwin_get_wnd_from_tree(struct rtgui_dlist_node *list, static struct rtgui_topwin* _rtgui_topwin_get_wnd_from_tree(struct rtgui_dlist_node *list,
@ -885,7 +943,12 @@ static void rtgui_topwin_update_clip(void)
rtgui_graphic_driver_get_default()->height); rtgui_graphic_driver_get_default()->height);
/* from top to bottom. */ /* from top to bottom. */
top = _rtgui_topwin_get_topmost_window_shown(); top = _rtgui_topwin_get_topmost_window_shown(WINTITLE_ONTOP);
/* 0 is normal layer */
if (top == RT_NULL)
top = _rtgui_topwin_get_topmost_window_shown(0);
if (top == RT_NULL)
top = _rtgui_topwin_get_topmost_window_shown(WINTITLE_ONBTM);
while (top != RT_NULL) while (top != RT_NULL)
{ {
@ -906,7 +969,7 @@ static void rtgui_topwin_update_clip(void)
/* send clip event to destination window */ /* send clip event to destination window */
eclip.wid = top->wid; eclip.wid = top->wid;
rtgui_application_send(top->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info)); rtgui_send(top->tid, &(eclip.parent), sizeof(struct rtgui_event_clip_info));
/* move to next sibling tree */ /* move to next sibling tree */
if (top->parent == RT_NULL) if (top->parent == RT_NULL)
@ -915,6 +978,7 @@ static void rtgui_topwin_update_clip(void)
top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next)); top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next));
else else
break; break;
/* move to next slibing topwin */
else if (top->list.next != &top->parent->child_list && else if (top->list.next != &top->parent->child_list &&
get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN) get_topwin_from_list(top->list.next)->flag & WINTITLE_SHOWN)
top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next)); top = _rtgui_topwin_get_topmost_child_shown(get_topwin_from_list(top->list.next));
@ -951,7 +1015,7 @@ static void _rtgui_topwin_redraw_tree(struct rtgui_dlist_node *list,
if (rtgui_rect_is_intersect(rect, &(topwin->extent)) == RT_EOK) if (rtgui_rect_is_intersect(rect, &(topwin->extent)) == RT_EOK)
{ {
epaint->wid = topwin->wid; epaint->wid = topwin->wid;
rtgui_application_send(topwin->tid, &(epaint->parent), sizeof(*epaint)); rtgui_send(topwin->tid, &(epaint->parent), sizeof(*epaint));
/* draw title */ /* draw title */
if (topwin->title != RT_NULL) if (topwin->title != RT_NULL)
@ -1019,7 +1083,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mou
if (rtgui_rect_contains_point(&win->extent, event->x, event->y) == RT_EOK) if (rtgui_rect_contains_point(&win->extent, event->x, event->y) == RT_EOK)
{ {
/* send mouse event to thread */ /* send mouse event to thread */
rtgui_application_send(win->tid, &(event->parent), sizeof(struct rtgui_event_mouse)); rtgui_send(win->tid, &(event->parent), sizeof(struct rtgui_event_mouse));
return; return;
} }
@ -1058,7 +1122,7 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mou
/* send close event to window */ /* send close event to window */
RTGUI_EVENT_WIN_CLOSE_INIT(&event); RTGUI_EVENT_WIN_CLOSE_INIT(&event);
event.wid = win->wid; event.wid = win->wid;
rtgui_application_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win)); rtgui_send(win->tid, &(event.parent), sizeof(struct rtgui_event_win));
} }
} }
} }
@ -1120,19 +1184,18 @@ void rtgui_topwin_dump_tree(void)
{ {
struct rtgui_dlist_node *node; struct rtgui_dlist_node *node;
#ifdef RTGUI_USING_DESKTOP_WINDOW
_rtgui_topwin_dump(the_desktop_topwin);
rt_kprintf("\n");
rtgui_dlist_foreach(node, &the_desktop_topwin->child_list, next)
{
_rtgui_topwin_dump_tree(get_topwin_from_list(node));
rt_kprintf("\n");
}
#else
rtgui_dlist_foreach(node, &_rtgui_topwin_list, next) rtgui_dlist_foreach(node, &_rtgui_topwin_list, next)
{ {
_rtgui_topwin_dump_tree(get_topwin_from_list(node)); _rtgui_topwin_dump_tree(get_topwin_from_list(node));
rt_kprintf("\n"); rt_kprintf("\n");
} }
#endif
} }
#ifdef RT_USING_FINSH
#include <finsh.h>
void dump_tree()
{
rtgui_topwin_dump_tree();
}
FINSH_FUNCTION_EXPORT(dump_tree, dump rtgui topwin tree)
#endif

View File

@ -23,8 +23,8 @@
/* add or remove a top win */ /* add or remove a top win */
rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event); rt_err_t rtgui_topwin_add(struct rtgui_event_win_create* event);
rt_err_t rtgui_topwin_remove(struct rtgui_win* wid); rt_err_t rtgui_topwin_remove(struct rtgui_win* wid);
rt_err_t rtgui_topwin_activate(struct rtgui_event_win_activate* event);
void rtgui_topwin_activate_win(struct rtgui_topwin* win); rt_err_t rtgui_topwin_activate_topwin(struct rtgui_topwin* win);
/* show a window */ /* show a window */
rt_err_t rtgui_topwin_show(struct rtgui_event_win* event); rt_err_t rtgui_topwin_show(struct rtgui_event_win* event);

View File

@ -1,101 +0,0 @@
/*
* File : about_view.c
* This file is part of RTGUI in RT-Thread RTOS
* COPYRIGHT (C) 2010, 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
* 2010-01-06 Bernard first version
*/
#include <rtgui/rtgui_theme.h>
#include <rtgui/widgets/about_view.h>
static void _rtgui_about_view_constructor(struct rtgui_about_view *view)
{
/* default rect */
struct rtgui_rect rect = {0, 0, 200, 200};
/* set default widget rect and set event handler */
rtgui_object_set_event_handler(RTGUI_OBJECT(view),rtgui_about_view_event_handler);
rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
RTGUI_WIDGET(view)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
view->logo = RT_NULL;
view->description = RT_NULL;
RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(view)) = RTGUI_ALIGN_CENTER_VERTICAL;
}
DEFINE_CLASS_TYPE(aboutview, "aboutview",
RTGUI_CONTAINER_TYPE,
_rtgui_about_view_constructor,
RT_NULL,
sizeof(struct rtgui_about_view));
void rtgui_about_view_ondraw(struct rtgui_about_view* view)
{
struct rtgui_rect rect;
struct rtgui_dc* dc;
dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(view));
if (dc == RT_NULL) return;
rtgui_widget_get_rect(RTGUI_WIDGET(view), &rect);
rtgui_dc_fill_rect(dc, &rect);
if (view->logo != RT_NULL)
rtgui_image_blit(view->logo, dc, &rect);
rect.y1 += view->logo->h + 5;
if (view->description != RT_NULL)
rtgui_dc_draw_text(dc, view->description, &rect);
rect.y1 += rtgui_dc_get_gc(dc)->font->height;
rtgui_dc_draw_hline(dc, rect.x1 + 3, rect.x2 - 3, rect.y1);
RTGUI_DC_FC(dc) = white;
rtgui_dc_draw_hline(dc, rect.x1 + 4, rect.x2 - 2, rect.y1 + 1);
rtgui_dc_end_drawing(dc);
}
rt_bool_t rtgui_about_view_event_handler(struct rtgui_object* widget, struct rtgui_event* event)
{
struct rtgui_about_view* view = RT_NULL;
view = RTGUI_ABOUT_VIEW(widget);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
rtgui_about_view_ondraw(view);
return RT_FALSE;
}
/* use view event handler */
return rtgui_container_event_handler(widget, event);
}
rtgui_about_view_t* rtgui_about_view_create(rtgui_image_t *logo, const char* description)
{
struct rtgui_about_view* view = RT_NULL;
view = (struct rtgui_about_view*) rtgui_widget_create(RTGUI_ABOUT_VIEW_TYPE);
if (view != RT_NULL)
{
view->logo = logo;
view->description = description;
}
return view;
}
void rtgui_about_view_destroy(rtgui_about_view_t* view)
{
/* destroy view */
rtgui_widget_destroy(RTGUI_WIDGET(view));
}

View File

@ -14,73 +14,37 @@
#include <rtgui/dc.h> #include <rtgui/dc.h>
#include <rtgui/widgets/box.h> #include <rtgui/widgets/box.h>
#ifndef RTGUI_USING_SMALL_SIZE
static void _rtgui_box_constructor(rtgui_box_t *box) static void _rtgui_box_constructor(rtgui_box_t *box)
{ {
/* init widget and set event handler */ /* init widget and set event handler */
rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler); rtgui_object_set_event_handler(RTGUI_OBJECT(box), RT_NULL);
RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_TRANSPARENT;
rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_box_event_handler);
/* set proper of control */ /* set proper of control */
box->orient = RTGUI_HORIZONTAL; box->orient = RTGUI_HORIZONTAL;
box->border_size = RTGUI_BORDER_DEFAULT_WIDTH; box->border_size = RTGUI_BORDER_DEFAULT_WIDTH;
box->container = RT_NULL;
} }
DEFINE_CLASS_TYPE(box, "box", DEFINE_CLASS_TYPE(box, "box",
RTGUI_CONTAINER_TYPE, RTGUI_OBJECT_TYPE,
_rtgui_box_constructor, _rtgui_box_constructor,
RT_NULL, RT_NULL,
sizeof(struct rtgui_box)); sizeof(struct rtgui_box));
rt_bool_t rtgui_box_event_handler(struct rtgui_object *widget, rtgui_event_t *event) struct rtgui_box* rtgui_box_create(int orientation, int border_size)
{
struct rtgui_box* box = (struct rtgui_box*)widget;
RT_ASSERT(box != RT_NULL);
switch (event->type)
{
case RTGUI_EVENT_RESIZE:
/* re-layout */
rtgui_box_layout(box);
break;
default:
return rtgui_container_event_handler(RTGUI_OBJECT(box), event);
}
return RT_FALSE;
}
struct rtgui_box* rtgui_box_create(int orientation, rtgui_rect_t* rect)
{ {
struct rtgui_box* box; struct rtgui_box* box;
box = (struct rtgui_box*) rtgui_widget_create (RTGUI_BOX_TYPE); box = (struct rtgui_box*) rtgui_object_create (RTGUI_BOX_TYPE);
if (box != RT_NULL) if (box != RT_NULL)
{ {
/* set proper of control */
rtgui_widget_set_rect(RTGUI_WIDGET(box), rect);
box->orient = orientation; box->orient = orientation;
box->border_size = border_size;
} }
return box; return box;
} }
void rtgui_box_append(struct rtgui_box* box, rtgui_widget_t* widget)
{
/* put to box's children list */
rtgui_container_add_child(RTGUI_CONTAINER(box), widget);
}
void rtgui_box_delete(struct rtgui_box* box, rtgui_widget_t* widget)
{
/* remove from box's children list */
rtgui_container_remove_child(RTGUI_CONTAINER(box), widget);
}
static void rtgui_box_layout_vertical(rtgui_box_t* box) static void rtgui_box_layout_vertical(rtgui_box_t* box)
{ {
rtgui_list_t *node; rtgui_list_t *node;
@ -89,16 +53,18 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box)
rt_int32_t next_x, next_y; rt_int32_t next_x, next_y;
rt_int32_t total_height, space_height; rt_int32_t total_height, space_height;
struct rtgui_event_resize size_event; struct rtgui_event_resize size_event;
struct rtgui_widget *container_widget;
/* prepare the resize event */ /* prepare the resize event */
RTGUI_EVENT_RESIZE_INIT(&size_event); RTGUI_EVENT_RESIZE_INIT(&size_event);
container_widget = RTGUI_WIDGET(box->container);
/* find spaces */ /* find spaces */
space_count = 0; space_count = 0;
total_height = 0; total_height = 0;
space_height = 0; space_height = 0;
rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) rtgui_list_foreach(node, &(box->container->children))
{ {
rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++;
@ -108,16 +74,16 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box)
/* calculate the height for each spaces */ /* calculate the height for each spaces */
if (space_count != 0) if (space_count != 0)
{ {
space_height = (rtgui_rect_height(RTGUI_WIDGET(box)->extent) - total_height - (box->border_size << 1)) / space_count; space_height = (rtgui_rect_height(container_widget->extent) - total_height - (box->border_size << 1)) / space_count;
} }
/* init (x, y) and box width */ /* init (x, y) and box width */
next_x = RTGUI_WIDGET(box)->extent.x1 + box->border_size; next_x = container_widget->extent.x1 + box->border_size;
next_y = RTGUI_WIDGET(box)->extent.y1 + box->border_size; next_y = container_widget->extent.y1 + box->border_size;
box_width = rtgui_rect_width(RTGUI_WIDGET(box)->extent) - (box->border_size << 1); box_width = rtgui_rect_width(container_widget->extent) - (box->border_size << 1);
/* layout each widget */ /* layout each widget */
rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) rtgui_list_foreach(node, &(box->container->children))
{ {
rtgui_rect_t *rect; rtgui_rect_t *rect;
rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
@ -170,7 +136,7 @@ static void rtgui_box_layout_vertical(rtgui_box_t* box)
&size_event.parent); &size_event.parent);
/* point to next height */ /* point to next height */
next_y = rect->y2; next_y = rect->y2 + box->border_size;
} }
} }
@ -182,16 +148,18 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box)
rt_int32_t next_x, next_y; rt_int32_t next_x, next_y;
rt_int32_t total_width, space_width; rt_int32_t total_width, space_width;
struct rtgui_event_resize size_event; struct rtgui_event_resize size_event;
struct rtgui_widget *container_widget;
/* prepare the resize event */ /* prepare the resize event */
RTGUI_EVENT_RESIZE_INIT(&size_event); RTGUI_EVENT_RESIZE_INIT(&size_event);
container_widget = RTGUI_WIDGET(box->container);
/* find spaces */ /* find spaces */
space_count = 0; space_count = 0;
total_width = 0; total_width = 0;
space_width = 0; space_width = 0;
rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) rtgui_list_foreach(node, &(box->container->children))
{ {
rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++; if (widget->align & RTGUI_ALIGN_STRETCH) space_count ++;
@ -201,16 +169,16 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box)
if (space_count != 0) if (space_count != 0)
{ {
/* calculate the height for each spaces */ /* calculate the height for each spaces */
space_width = (rtgui_rect_width(RTGUI_WIDGET(box)->extent) - total_width) / space_count; space_width = (rtgui_rect_width(container_widget->extent) - total_width) / space_count;
} }
/* init (x, y) and box height */ /* init (x, y) and box height */
next_x = RTGUI_WIDGET(box)->extent.x1 + box->border_size; next_x = container_widget->extent.x1 + box->border_size;
next_y = RTGUI_WIDGET(box)->extent.y1 + box->border_size; next_y = container_widget->extent.y1 + box->border_size;
box_height = rtgui_rect_height(RTGUI_WIDGET(box)->extent) - (box->border_size << 1); box_height = rtgui_rect_height(container_widget->extent) - (box->border_size << 1);
/* layout each widget */ /* layout each widget */
rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children)) rtgui_list_foreach(node, &(box->container->children))
{ {
rtgui_rect_t *rect; rtgui_rect_t *rect;
rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling); rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
@ -263,7 +231,7 @@ static void rtgui_box_layout_horizontal(rtgui_box_t* box)
&size_event.parent); &size_event.parent);
/* point to next width */ /* point to next width */
next_x = rect->x2; next_x = rect->x2 + box->border_size;
} }
} }
@ -271,6 +239,8 @@ void rtgui_box_layout(rtgui_box_t* box)
{ {
RT_ASSERT(box != RT_NULL); RT_ASSERT(box != RT_NULL);
if (box->container == RT_NULL) return;
if (box->orient & RTGUI_VERTICAL) if (box->orient & RTGUI_VERTICAL)
{ {
rtgui_box_layout_vertical(box); rtgui_box_layout_vertical(box);
@ -281,64 +251,9 @@ void rtgui_box_layout(rtgui_box_t* box)
} }
/* update box and its children clip */ /* update box and its children clip */
if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box))) if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(box->container)))
{ {
rtgui_widget_update_clip(RTGUI_WIDGET(box)); rtgui_widget_update_clip(RTGUI_WIDGET(box->container));
} }
} }
rt_uint32_t rtgui_box_get_width(rtgui_box_t* box)
{
rtgui_list_t *node;
rt_uint32_t width;
width = 0;
rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children))
{
rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
rt_uint32_t widget_width;
widget_width = rtgui_rect_width(widget->extent);
if (box->orient & RTGUI_VERTICAL)
{
/* get the max width */
if (width < widget_width) width = widget_width;
}
else
{
/* get the total width */
width += widget_width;
}
}
return width;
}
rt_uint32_t rtgui_box_get_height(rtgui_box_t* box)
{
rtgui_list_t *node;
rt_uint32_t height;
height = 0;
rtgui_list_foreach(node, &(RTGUI_CONTAINER(box)->children))
{
rtgui_widget_t* widget = rtgui_list_entry(node, struct rtgui_widget, sibling);
rt_uint32_t widget_height;
widget_height = rtgui_rect_height(widget->extent);
if (box->orient & RTGUI_HORIZONTAL)
{
/* get the max height */
if (height < widget_height) height = widget_height;
}
else
{
/* get the total height */
height += widget_height;
}
}
return height;
}
#endif

View File

@ -62,7 +62,7 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_e
struct rtgui_widget *widget; struct rtgui_widget *widget;
struct rtgui_button *btn; struct rtgui_button *btn;
RT_ASSERT(widget != RT_NULL); RT_ASSERT(object != RT_NULL);
RT_ASSERT(event != RT_NULL); RT_ASSERT(event != RT_NULL);
widget = RTGUI_WIDGET(object); widget = RTGUI_WIDGET(object);
@ -189,6 +189,8 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_object* object, struct rtgui_e
return RT_TRUE; return RT_TRUE;
} }
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -92,6 +92,8 @@ rt_bool_t rtgui_checkbox_event_handler(struct rtgui_object* object, struct rtgui
return RT_TRUE; return RT_TRUE;
} }
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -38,7 +38,6 @@ rt_bool_t rtgui_combobox_pdwin_onitem(struct rtgui_object* object, struct rtgui_
rtgui_listbox_t* list; rtgui_listbox_t* list;
RT_ASSERT(object != RT_NULL); RT_ASSERT(object != RT_NULL);
RT_ASSERT(event != RT_NULL);
widget = RTGUI_WIDGET(object); widget = RTGUI_WIDGET(object);
list = RTGUI_LISTBOX(widget); list = RTGUI_LISTBOX(widget);
@ -228,6 +227,8 @@ rt_bool_t rtgui_combobox_event_handler(struct rtgui_object* object, struct rtgui
} }
} }
break; break;
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -14,7 +14,7 @@
*/ */
#include <rtgui/dc.h> #include <rtgui/dc.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/widgets/container.h> #include <rtgui/widgets/container.h>
#include <rtgui/widgets/window.h> #include <rtgui/widgets/window.h>
@ -25,26 +25,17 @@ static void _rtgui_container_constructor(rtgui_container_t *container)
rtgui_container_event_handler); rtgui_container_event_handler);
rtgui_list_init(&(container->children)); rtgui_list_init(&(container->children));
container->layout_box = RT_NULL;
/* container is used to 'contain'(show) widgets and dispatch events to RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
* them, not interact with user. So no need to grab focus. If we did it,
* some widget inherited from container(e.g. notebook) will grab the focus
* annoyingly.
*
* For example, a focusable notebook N has a widget W. When the user press
* W, N will gain the focus and W will lose it at first. Then N will set
* focus to W because it is W that eventually interact with people. N will
* yield focus and W will gain the focus again. This loop will make W
* repaint twice every time user press it.
*
* Just eliminate it.
*/
RTGUI_WIDGET(container)->flag &= ~RTGUI_WIDGET_FLAG_FOCUSABLE;
} }
static void _rtgui_container_destructor(rtgui_container_t *container) static void _rtgui_container_destructor(rtgui_container_t *container)
{ {
rtgui_container_destroy_children(container); rtgui_container_destroy_children(container);
if (container->layout_box != RT_NULL)
rtgui_object_destroy(RTGUI_OBJECT(container->layout_box));
} }
static void _rtgui_container_update_toplevel(rtgui_container_t* container) static void _rtgui_container_update_toplevel(rtgui_container_t* container)
@ -152,15 +143,6 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgu
break; break;
case RTGUI_EVENT_KBD: case RTGUI_EVENT_KBD:
/* let parent to handle keyboard event */
if (widget->parent != RT_NULL &&
widget->parent != RTGUI_WIDGET(widget->toplevel) &&
RTGUI_OBJECT(widget->parent)->event_handler)
{
return RTGUI_OBJECT(widget->parent)->event_handler(
RTGUI_OBJECT(widget->parent),
event);
}
break; break;
case RTGUI_EVENT_MOUSE_BUTTON: case RTGUI_EVENT_MOUSE_BUTTON:
@ -169,6 +151,14 @@ rt_bool_t rtgui_container_event_handler(struct rtgui_object* object, struct rtgu
return rtgui_container_dispatch_mouse_event(container, return rtgui_container_dispatch_mouse_event(container,
(struct rtgui_event_mouse*)event); (struct rtgui_event_mouse*)event);
case RTGUI_EVENT_SHOW:
rtgui_widget_onshow(RTGUI_OBJECT(container), event);
rtgui_container_dispatch_event(container, event);
break;
case RTGUI_EVENT_HIDE:
rtgui_widget_onhide(RTGUI_OBJECT(container), event);
rtgui_container_dispatch_event(container, event);
break;
case RTGUI_EVENT_COMMAND: case RTGUI_EVENT_COMMAND:
case RTGUI_EVENT_RESIZE: case RTGUI_EVENT_RESIZE:
rtgui_container_dispatch_event(container, event); rtgui_container_dispatch_event(container, event);
@ -193,7 +183,6 @@ rtgui_container_t* rtgui_container_create(void)
void rtgui_container_destroy(rtgui_container_t* container) void rtgui_container_destroy(rtgui_container_t* container)
{ {
rtgui_container_hide(container);
rtgui_widget_destroy(RTGUI_WIDGET(container)); rtgui_widget_destroy(RTGUI_WIDGET(container));
} }
@ -296,26 +285,20 @@ rtgui_widget_t* rtgui_container_get_first_child(rtgui_container_t* container)
return child; return child;
} }
#ifndef RTGUI_USING_SMALL_SIZE
void rtgui_container_set_box(rtgui_container_t* container, struct rtgui_box* box) void rtgui_container_set_box(rtgui_container_t* container, struct rtgui_box* box)
{ {
if (container == RT_NULL || box == RT_NULL) if (container == RT_NULL || box == RT_NULL)
return; return;
rtgui_container_add_child(RTGUI_CONTAINER(container), RTGUI_WIDGET(box)); container->layout_box = box;
rtgui_widget_set_rect(RTGUI_WIDGET(box), &(RTGUI_WIDGET(container)->extent)); box->container = container;
} }
#endif
void rtgui_container_hide(rtgui_container_t* container) void rtgui_container_layout(struct rtgui_container* container)
{ {
if (container == RT_NULL) if (container == RT_NULL || container->layout_box == RT_NULL)
return; return;
if (RTGUI_WIDGET(container)->parent == RT_NULL) rtgui_box_layout(container->layout_box);
{
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(container));
return;
}
} }

View File

@ -15,7 +15,7 @@
#include <rtgui/rtgui_object.h> #include <rtgui/rtgui_object.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_theme.h> #include <rtgui/rtgui_theme.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/list.h> #include <rtgui/list.h>
#include <rtgui/image.h> #include <rtgui/image.h>
@ -235,14 +235,14 @@ static struct rtgui_listbox_item items[] =
}; };
static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view); static void rtgui_filelist_view_clear(rtgui_filelist_view_t* view);
static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rtgui_event* event) static rt_bool_t rtgui_filelist_view_on_folder_item(rtgui_object_t* object, struct rtgui_event* event)
{ {
rtgui_win_t *menu; rtgui_win_t *menu;
rtgui_listbox_t *listbox; rtgui_listbox_t *listbox;
rtgui_filelist_view_t *view; rtgui_filelist_view_t *view;
listbox = RTGUI_LISTBOX(widget); listbox = RTGUI_LISTBOX(object);
menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget)); menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object)));
view = RTGUI_FILELIST_VIEW(menu->user_data); view = RTGUI_FILELIST_VIEW(menu->user_data);
/* hide window */ /* hide window */
@ -273,12 +273,14 @@ static void rtgui_filelist_view_on_folder_item(rtgui_widget_t* widget, struct rt
rtgui_win_destroy(menu); rtgui_win_destroy(menu);
break; break;
} }
return RT_TRUE;
} }
static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_widget_t* widget, struct rtgui_event* event) static rt_bool_t rtgui_filelist_view_on_menu_deactivate(rtgui_object_t* object, struct rtgui_event* event)
{ {
rtgui_win_t *menu; rtgui_win_t *menu;
menu = RTGUI_WIN(rtgui_widget_get_toplevel(widget)); menu = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object)));
/* destroy menu window */ /* destroy menu window */
rtgui_win_destroy(menu); rtgui_win_destroy(menu);
@ -295,7 +297,7 @@ static void rtgui_filelist_view_menu_pop(rtgui_widget_t *parent)
rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen); rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &screen);
rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL); rtgui_rect_moveto_align(&screen, &rect, RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL);
menu = rtgui_win_create(rtgui_widget_get_toplevel(parent), menu = rtgui_win_create(RTGUI_WIN(rtgui_widget_get_toplevel(parent)),
"Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT); "Folder Menu", &rect, RTGUI_WIN_STYLE_DEFAULT);
if (menu != RT_NULL) if (menu != RT_NULL)
{ {
@ -533,10 +535,12 @@ static void rtgui_filelist_view_onenturn(struct rtgui_filelist_view* view)
} }
} }
rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{ {
struct rtgui_widget *widget;
struct rtgui_filelist_view* view = RT_NULL; struct rtgui_filelist_view* view = RT_NULL;
widget = RTGUI_WIDGET(object);
view = RTGUI_FILELIST_VIEW(widget); view = RTGUI_FILELIST_VIEW(widget);
switch (event->type) switch (event->type)
{ {
@ -650,7 +654,7 @@ rt_bool_t rtgui_filelist_view_event_handler(struct rtgui_widget* widget, struct
} }
/* use view event handler */ /* use view event handler */
return rtgui_container_event_handler(RTGUI_OBJECT(widget), event); return rtgui_container_event_handler(object, event);
} }
rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory, rtgui_filelist_view_t* rtgui_filelist_view_create(const char* directory,

View File

@ -66,6 +66,8 @@ rt_bool_t rtgui_iconbox_event_handler(struct rtgui_object* object, struct rtgui_
} }
break; break;
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -49,6 +49,8 @@ rt_bool_t rtgui_label_event_handler(struct rtgui_object *object, struct rtgui_ev
case RTGUI_EVENT_PAINT: case RTGUI_EVENT_PAINT:
rtgui_theme_draw_label(label); rtgui_theme_draw_label(label);
break; break;
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -267,17 +267,18 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_
{ {
rt_int16_t old_item; rt_int16_t old_item;
if (box->current_item == -1) if (box->current_item == -1)
{ {
/* set a initial item */ /* set a initial item */
if ((box->items_count > 0) && if ((box->items_count > 0) &&
(ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN)) (ekbd->key == RTGUIK_UP || ekbd->key == RTGUIK_DOWN))
{ {
box->current_item = 0; box->current_item = 0;
rtgui_listbox_update_current(box, -1); rtgui_listbox_update_current(box, -1);
break; return RT_TRUE;
} }
else return RT_FALSE; else
return RT_FALSE;
} }
old_item = box->current_item; old_item = box->current_item;
@ -287,32 +288,30 @@ rt_bool_t rtgui_listbox_event_handler(struct rtgui_object* object, struct rtgui_
if (box->current_item - box->page_items >= 0) if (box->current_item - box->page_items >= 0)
box->current_item -= box->page_items; box->current_item -= box->page_items;
rtgui_listbox_update_current(box, old_item); rtgui_listbox_update_current(box, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_UP: case RTGUIK_UP:
if (box->current_item > 0) if (box->current_item > 0)
box->current_item --; box->current_item --;
rtgui_listbox_update_current(box, old_item); rtgui_listbox_update_current(box, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_RIGHT: case RTGUIK_RIGHT:
if (box->current_item + box->page_items < box->items_count - 1) if (box->current_item + box->page_items < box->items_count - 1)
box->current_item += box->page_items; box->current_item += box->page_items;
rtgui_listbox_update_current(box, old_item); rtgui_listbox_update_current(box, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_DOWN: case RTGUIK_DOWN:
if (box->current_item < box->items_count - 1) if (box->current_item < box->items_count - 1)
box->current_item ++; box->current_item ++;
rtgui_listbox_update_current(box, old_item); rtgui_listbox_update_current(box, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_RETURN: case RTGUIK_RETURN:
if (box->on_item != RT_NULL) if (box->on_item != RT_NULL)
{
box->on_item(RTGUI_OBJECT(box), RT_NULL); box->on_item(RTGUI_OBJECT(box), RT_NULL);
} return RT_TRUE;
return RT_FALSE;
default: default:
break; break;

View File

@ -316,13 +316,13 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui
if (ctrl->current_item - ctrl->page_items >= 0) if (ctrl->current_item - ctrl->page_items >= 0)
ctrl->current_item -= ctrl->page_items; ctrl->current_item -= ctrl->page_items;
rtgui_listctrl_update_current(ctrl, old_item); rtgui_listctrl_update_current(ctrl, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_UP: case RTGUIK_UP:
if (ctrl->current_item > 0) if (ctrl->current_item > 0)
ctrl->current_item --; ctrl->current_item --;
rtgui_listctrl_update_current(ctrl, old_item); rtgui_listctrl_update_current(ctrl, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_RIGHT: case RTGUIK_RIGHT:
if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1) if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1)
@ -333,18 +333,18 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_object* object, struct rtgui
ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items; ctrl->current_item = ((ctrl->current_item / ctrl->page_items) + 1) * ctrl->page_items;
} }
rtgui_listctrl_update_current(ctrl, old_item); rtgui_listctrl_update_current(ctrl, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_DOWN: case RTGUIK_DOWN:
if (ctrl->current_item < ctrl->items_count - 1) if (ctrl->current_item < ctrl->items_count - 1)
ctrl->current_item ++; ctrl->current_item ++;
rtgui_listctrl_update_current(ctrl, old_item); rtgui_listctrl_update_current(ctrl, old_item);
return RT_FALSE; return RT_TRUE;
case RTGUIK_RETURN: case RTGUIK_RETURN:
if (ctrl->on_item != RT_NULL) if (ctrl->on_item != RT_NULL)
{ {
ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL); return ctrl->on_item(RTGUI_OBJECT(ctrl), RT_NULL);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -40,10 +40,12 @@ static void _rtgui_menu_destructor(rtgui_menu_t* menu)
static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_event* event) static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_event* event)
{ {
struct rtgui_menu* menu; struct rtgui_menu* menu;
RTGUI_WIDGET_EVENT_HANDLER_PREPARE
/* event will be NULL, don't check it. */
RT_ASSERT(object);
/* get menu */ /* get menu */
menu = RTGUI_MENU(rtgui_widget_get_toplevel(widget)); menu = RTGUI_MENU(rtgui_widget_get_toplevel(RTGUI_WIDGET(object)));
if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU) if (menu->items[menu->items_list->current_item].type == RTGUI_ITEM_SUBMENU)
{ {
const rtgui_menu_item_t* items; const rtgui_menu_item_t* items;
@ -84,7 +86,7 @@ static rt_bool_t _rtgui_menu_onitem(struct rtgui_object* object, struct rtgui_ev
{ {
/* invoke action */ /* invoke action */
if (menu->items[menu->items_list->current_item].on_menuaction != RT_NULL) 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); menu->items[menu->items_list->current_item].on_menuaction(RTGUI_OBJECT(menu), RT_NULL);
/* hide sub-menu */ /* hide sub-menu */
if (menu->sub_menu != RT_NULL) if (menu->sub_menu != RT_NULL)

View File

@ -301,12 +301,16 @@ void rtgui_notebook_set_current_by_index(struct rtgui_notebook* notebook, rt_uin
if ((index < notebook->count) && (notebook->current != index)) if ((index < notebook->count) && (notebook->current != index))
{ {
struct rtgui_widget *widget;
if (notebook->current != RTGUI_NOT_FOUND) if (notebook->current != RTGUI_NOT_FOUND)
rtgui_widget_hide(notebook->childs[notebook->current].widget); rtgui_widget_hide(notebook->childs[notebook->current].widget);
notebook->current = index; notebook->current = index;
rtgui_widget_show(notebook->childs[notebook->current].widget); widget = notebook->childs[notebook->current].widget;
rtgui_widget_update(notebook->childs[notebook->current].widget); rtgui_widget_show(widget);
rtgui_widget_update(widget);
rtgui_widget_focus(widget);
} }
} }
@ -319,6 +323,16 @@ struct rtgui_widget* rtgui_notebook_get_widget_at(struct rtgui_notebook* noteboo
return RT_NULL; return RT_NULL;
} }
static rt_bool_t _rtgui_notebook_current_widget_handle(struct rtgui_notebook *notebook,
struct rtgui_event *event)
{
struct rtgui_widget *widget = rtgui_notebook_get_current(notebook);
if (widget && widget != RTGUI_WIDGET(notebook))
return RTGUI_OBJECT(widget)->event_handler(RTGUI_OBJECT(widget), event);
else
return RT_FALSE;
}
rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui_event* event) rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{ {
struct rtgui_notebook* notebook; struct rtgui_notebook* notebook;
@ -336,17 +350,18 @@ rt_bool_t rtgui_notebook_event_handler(struct rtgui_object* object, struct rtgui
case RTGUI_EVENT_MOUSE_BUTTON: case RTGUI_EVENT_MOUSE_BUTTON:
_rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event); _rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event);
break; break;
case RTGUI_EVENT_SHOW:
/* show myself */
rtgui_widget_onshow(object, event);
/* show the tab widget */
return _rtgui_notebook_current_widget_handle(notebook, event);
case RTGUI_EVENT_HIDE:
/* hide myself */
rtgui_widget_onhide(object, event);
/* hide the tab widget */
return _rtgui_notebook_current_widget_handle(notebook, event);
case RTGUI_EVENT_KBD: case RTGUI_EVENT_KBD:
if (notebook->current != RTGUI_NOT_FOUND) return _rtgui_notebook_current_widget_handle(notebook, event);
{
if (RTGUI_OBJECT(notebook->childs[notebook->current].widget
)->event_handler != RT_NULL)
return RTGUI_OBJECT(notebook->childs[notebook->current].widget
)->event_handler(
RTGUI_OBJECT(notebook->childs[notebook->current].widget),
event);
}
break;
default: default:
/* use parent event handler */ /* use parent event handler */
return rtgui_widget_event_handler(object, event); return rtgui_widget_event_handler(object, event);

View File

@ -0,0 +1,89 @@
/*
* File : panel.c
* This file is part of RT-Thread RTOS
* COPYRIGHT (C) 2006 - 2012, 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
* 2012-07-07 Bernard implement panel as a widget
*/
#include <rtgui/dc.h>
#include <rtgui/widgets/panel.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_theme.h>
static void _rtgui_panel_constructor(rtgui_panel_t *panel)
{
/* init widget and set event handler */
rtgui_object_set_event_handler(RTGUI_OBJECT(panel), rtgui_panel_event_handler);
/* set field */
panel->border_style = RTGUI_BORDER_NONE;
}
DEFINE_CLASS_TYPE(panel, "panel",
RTGUI_CONTAINER_TYPE,
_rtgui_panel_constructor,
RT_NULL,
sizeof(struct rtgui_panel));
rt_bool_t rtgui_panel_event_handler(struct rtgui_object *object, struct rtgui_event* event)
{
struct rtgui_panel* panel;
panel = RTGUI_PANEL(object);
switch (event->type)
{
case RTGUI_EVENT_PAINT:
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
rtgui_widget_get_rect(RTGUI_WIDGET(object), &rect);
dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(object));
if (dc == RT_NULL) return RT_FALSE;
rtgui_dc_fill_rect(dc, &rect);
// rtgui_rect_inflate(&rect, RTGUI_WIDGET(panel)->);
rtgui_dc_draw_border(dc, &rect, panel->border_style);
/* paint on each child */
rtgui_container_dispatch_event(RTGUI_CONTAINER(panel), event);
rtgui_dc_end_drawing(dc);
}
break;
default:
return rtgui_container_event_handler(object, event);
}
return RT_FALSE;
}
rtgui_panel_t* rtgui_panel_create(int border_style)
{
struct rtgui_panel* panel;
panel = (struct rtgui_panel*) rtgui_widget_create(RTGUI_PANEL_TYPE);
if (panel != RT_NULL)
{
rtgui_rect_t rect = {0, 0, 100, 100};
rtgui_widget_set_rect(RTGUI_WIDGET(panel), &rect);
panel->border_style = border_style;
}
return panel;
}
void rtgui_panel_destroy(rtgui_panel_t* panel)
{
rtgui_object_destroy(RTGUI_OBJECT(panel));
}

View File

@ -38,6 +38,8 @@ rt_bool_t rtgui_progressbar_event_handler(struct rtgui_object* object,
case RTGUI_EVENT_PAINT: case RTGUI_EVENT_PAINT:
rtgui_theme_draw_progressbar(bar); rtgui_theme_draw_progressbar(bar);
break; break;
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -101,7 +101,7 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui
#ifndef RTGUI_USING_SMALL_SIZE #ifndef RTGUI_USING_SMALL_SIZE
if (widget->on_key != RT_NULL) if (widget->on_key != RT_NULL)
widget->on_key(RTGUI_OBJECT(widget), event); return widget->on_key(RTGUI_OBJECT(widget), event);
else else
#endif #endif
{ {
@ -116,12 +116,18 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui
if (e->key == RTGUIK_UP) if (e->key == RTGUIK_UP)
{ {
if (radiobox->item_selection > 0) if (radiobox->item_selection > 0)
{
rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1); rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
return RT_TRUE;
}
} }
else if (e->key == RTGUIK_DOWN) else if (e->key == RTGUIK_DOWN)
{ {
if (radiobox->item_selection < radiobox->item_count - 1) if (radiobox->item_selection < radiobox->item_count - 1)
{
rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1); rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
return RT_TRUE;
}
} }
} }
else else
@ -129,12 +135,18 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui
if (e->key == RTGUIK_LEFT) if (e->key == RTGUIK_LEFT)
{ {
if (radiobox->item_selection > 0) if (radiobox->item_selection > 0)
{
rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1); rtgui_radiobox_set_selection(radiobox, radiobox->item_selection - 1);
return RT_TRUE;
}
} }
else if (e->key == RTGUIK_RIGHT) else if (e->key == RTGUIK_RIGHT)
{ {
if (radiobox->item_selection < radiobox->item_count - 1) if (radiobox->item_selection < radiobox->item_count - 1)
{
rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1); rtgui_radiobox_set_selection(radiobox, radiobox->item_selection + 1);
return RT_TRUE;
}
} }
} }
} }
@ -150,6 +162,8 @@ rt_bool_t rtgui_radiobox_event_handler(struct rtgui_object* object, struct rtgui
rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event); rtgui_radiobox_onmouse(radiobox, (struct rtgui_event_mouse*)event);
} }
break; break;
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -302,7 +302,7 @@ rt_bool_t rtgui_scrollbar_event_handler(struct rtgui_object *object,
break; break;
default: default:
break; return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -168,13 +168,10 @@ rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_e
#ifndef RTGUI_USING_SMALL_SIZE #ifndef RTGUI_USING_SMALL_SIZE
if (widget->on_key != RT_NULL) if (widget->on_key != RT_NULL)
widget->on_key(RTGUI_OBJECT(widget), event); return widget->on_key(RTGUI_OBJECT(widget), event);
else else
#endif #endif
{
return rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event); return rtgui_slider_onkey(slider, (struct rtgui_event_kbd *)event);
}
break;
case RTGUI_EVENT_MOUSE_BUTTON: case RTGUI_EVENT_MOUSE_BUTTON:
if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE; if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
@ -188,6 +185,9 @@ rt_bool_t rtgui_slider_event_handler(struct rtgui_object *object, struct rtgui_e
rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event); rtgui_slider_onmouse(slider, (struct rtgui_event_mouse*)event);
} }
break; break;
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -36,6 +36,8 @@ rt_bool_t rtgui_staticline_event_handler(struct rtgui_object* object, struct rtg
#endif #endif
rtgui_theme_draw_staticline(staticline); rtgui_theme_draw_staticline(staticline);
break; break;
default:
return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -11,106 +11,197 @@
* Date Author Notes * Date Author Notes
* 2009-10-16 Bernard first version * 2009-10-16 Bernard first version
* 2011-01-224 Bernard fix backspace issue. * 2011-01-224 Bernard fix backspace issue.
* 2012-06-09 asml refactor
* 2012-06-17 Grissiom misc cleanup and merge
*/ */
#include <rtgui/dc.h> #include <string.h>
#include <rtgui/rtgui_theme.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/textbox.h> #include <rtgui/widgets/textbox.h>
#include <rtgui/widgets/combobox.h>
#include <rtgui/rtgui_system.h>
#ifndef _WIN32
#include <ctype.h> #include <ctype.h>
#endif
#define RTGUI_TEXTBOX_LINE_MAX 64 static void rtgui_textbox_draw_caret(rtgui_textbox_t *box, rt_uint16_t position);
#define RTGUI_TEXTBOX_MARGIN 3 static rt_bool_t rtgui_textbox_onkey(struct rtgui_object* widget, rtgui_event_t* event);
static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* widget, rtgui_event_t* event);
static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event); static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* widget, rtgui_event_t* event);
static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event);
static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* object, struct rtgui_event* event);
static void _rtgui_textbox_caret_timeout(struct rtgui_timer* 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;
/* re-darw textbox */
rtgui_theme_draw_textbox(box);
return ;
}
static void _rtgui_textbox_constructor(rtgui_textbox_t *box) static void _rtgui_textbox_constructor(rtgui_textbox_t *box)
{ {
rtgui_rect_t rect = {0, 0, RTGUI_TEXTBOX_DEFAULT_WIDTH, RTGUI_TEXTBOX_DEFAULT_HEIGHT}; rtgui_rect_t rect;
rtgui_widget_set_rect(RTGUI_WIDGET(box), &rect);
RTGUI_WIDGET_FLAG(RTGUI_WIDGET(box)) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
RTGUI_WIDGET(box)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_textbox_event_handler); rtgui_object_set_event_handler(RTGUI_OBJECT(box), rtgui_textbox_event_handler);
rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus); rtgui_widget_set_onfocus(RTGUI_WIDGET(box), rtgui_textbox_onfocus);
rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus); rtgui_widget_set_onunfocus(RTGUI_WIDGET(box), rtgui_textbox_onunfocus);
#ifndef RTGUI_USING_SMALL_SIZE
rtgui_widget_set_onkey(RTGUI_WIDGET(box),rtgui_textbox_onkey);
#endif
RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = black;
RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
/* set default text align */ /* set default text align */
RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL; RTGUI_WIDGET_TEXTALIGN(RTGUI_WIDGET(box)) = RTGUI_ALIGN_CENTER_VERTICAL;
/* set proper of control */ /* set proper of control */
box->caret_timer = rtgui_timer_create(RT_TICK_PER_SECOND, RT_TIMER_FLAG_PERIODIC, box->caret_timer = RT_NULL;
_rtgui_textbox_caret_timeout, box); box->caret = RT_NULL;
box->line = box->line_begin = box->position = 0; box->line = box->line_begin = box->position = 0;
box->flag = RTGUI_TEXTBOX_SINGLE; box->flag = RTGUI_TEXTBOX_SINGLE;
/* allocate default line buffer */ /* allocate default line buffer */
box->text = RT_NULL; box->text = RT_NULL;
rtgui_font_get_metrics(RTGUI_WIDGET(box)->gc.font, "h", &rect); rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &rect);
box->font_width = rtgui_rect_width(rect); box->font_width = rtgui_rect_width(rect);
box->on_enter = RT_NULL;
box->dis_length = 0;
} }
static void _rtgui_textbox_deconstructor(rtgui_textbox_t *box) static void _rtgui_textbox_deconstructor(rtgui_textbox_t *textbox)
{ {
if (box->text != RT_NULL) if(textbox->text != RT_NULL)
{ {
rt_free(box->text); rtgui_free(textbox->text);
box->text = RT_NULL; textbox->text = RT_NULL;
}
if(textbox->caret_timer != RT_NULL)
{
rtgui_timer_destory(textbox->caret_timer);
textbox->caret_timer = RT_NULL;
}
if(textbox->caret != RT_NULL)
{
rtgui_free(textbox->caret);
textbox->caret = RT_NULL;
} }
rtgui_timer_destory(box->caret_timer);
box->caret_timer = RT_NULL;
} }
DEFINE_CLASS_TYPE(textbox, "textbox", DEFINE_CLASS_TYPE(textbox, "textbox",
RTGUI_WIDGET_TYPE, RTGUI_WIDGET_TYPE,
_rtgui_textbox_constructor, _rtgui_textbox_constructor,
_rtgui_textbox_deconstructor, _rtgui_textbox_deconstructor,
sizeof(struct rtgui_textbox)); sizeof(struct rtgui_textbox));
static void rtgui_textbox_onmouse(struct rtgui_textbox* box, struct rtgui_event_mouse* event) static void rtgui_textbox_get_caret_rect(rtgui_textbox_t *box, rtgui_rect_t *rect, rt_uint16_t position)
{
int font_h,box_h;
rtgui_rect_t item_rect;
RT_ASSERT(box != RT_NULL);
rtgui_widget_get_rect(RTGUI_WIDGET(box), rect);
rtgui_font_get_metrics(RTGUI_WIDGET_FONT(RTGUI_WIDGET(box)), "H", &item_rect);
font_h = rtgui_rect_height(item_rect);
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;
}
static void rtgui_textbox_init_caret(rtgui_textbox_t *box, rt_uint16_t position)
{
int x, y;
rtgui_color_t color;
rtgui_rect_t rect;
int ofs = 0;
RT_ASSERT(box != RT_NULL);
if (!RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(box)))
return;
rtgui_textbox_get_caret_rect(box, &box->caret_rect, position);
rect = box->caret_rect;
rtgui_widget_rect_to_device(RTGUI_WIDGET(box), &rect);
if (box->caret == RT_NULL)
box->caret = rtgui_malloc(rtgui_rect_width(rect)*rtgui_rect_height(rect)*sizeof(rtgui_color_t));
for (x = rect.x1; x < rect.x2; x++)
{
for(y = rect.y1; y < rect.y2; y++)
{
rtgui_graphic_driver_get_default()->ops->get_pixel(&color, x, y);
*(box->caret + ofs) = color;
ofs++;
}
}
}
/* draw caret */
static 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 ofs = 0;
struct rtgui_dc *dc;
RT_ASSERT(box != RT_NULL);
if (box->caret == RT_NULL)
return;
dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(box));
if (dc == RT_NULL)
return;
rect = box->caret_rect;
for(x = rect.x1; x < rect.x2; x++)
{
for(y = rect.y1; y < rect.y2; y++)
{
color = *(box->caret + ofs);
ofs++;
if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
{
color = ~color;
}
rtgui_dc_draw_color_point(dc, x, y, color);
}
}
rtgui_dc_end_drawing(dc);
}
static void rtgui_textbox_timeout(rtgui_timer_t* timer, void* parameter)
{
rtgui_textbox_t* box;
box = RTGUI_TEXTBOX(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);
}
static void rtgui_textbox_onmouse(rtgui_textbox_t* box, struct rtgui_event_mouse* event)
{ {
rt_size_t length; rt_size_t length;
rt_uint16_t posbak = box->position;
RT_ASSERT(box != RT_NULL); RT_ASSERT(box != RT_NULL);
RT_ASSERT(event != RT_NULL); RT_ASSERT(event != RT_NULL);
length = rt_strlen((const char*)box->text); length = rt_strlen(box->text);
if (event->button & RTGUI_MOUSE_BUTTON_LEFT && if(event->button & RTGUI_MOUSE_BUTTON_LEFT && event->button & RTGUI_MOUSE_BUTTON_DOWN)
event->button & RTGUI_MOUSE_BUTTON_DOWN)
{ {
rt_int32_t x; rt_int32_t x;
/* single line text */
/* set caret position */ /* set caret position */
x = event->x - RTGUI_WIDGET(box)->extent.x1; x = event->x - RTGUI_WIDGET(box)->extent.x1;
if (x < 0) if(x < 0)
{ {
box->position = 0; box->position = 0;
} }
else if (x > length * box->font_width) else if(x > length * box->font_width)
{ {
box->position = length; box->position = length;
} }
@ -119,30 +210,54 @@ static void rtgui_textbox_onmouse(struct rtgui_textbox* box, struct rtgui_event_
box->position = x / box->font_width; box->position = x / box->font_width;
} }
/* set caret to show */ if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
box->flag |= RTGUI_TEXTBOX_CARET_SHOW; {
if(box->caret_timer != RT_NULL)
rtgui_timer_stop(box->caret_timer);
/* set widget focus */ box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
rtgui_widget_focus(RTGUI_WIDGET(box)); rtgui_textbox_draw_caret(box, posbak);
/* re-draw text box */
rtgui_theme_draw_textbox(box); if(box->caret_timer != RT_NULL)
rtgui_timer_start(box->caret_timer);
}
rtgui_textbox_init_caret(box, box->position);
box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
rtgui_textbox_draw_caret(box,box->position);
} }
} }
static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kbd* event) 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_size_t length;
rt_uint16_t posbak = box->position;
RT_ASSERT(box != RT_NULL); RT_ASSERT(box != RT_NULL);
RT_ASSERT(event != RT_NULL); RT_ASSERT(ekbd != RT_NULL);
if (event->type != RTGUI_KEYUP) /* handle the key at down time and nothing to do with up */
return ; if (RTGUI_KBD_IS_UP(ekbd))
return RT_TRUE;
length = rt_strlen((const char*)box->text); if (box->dis_length == 0)
if (event->key == RTGUIK_DELETE)
{ {
if (box->position == length - 1) 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->position == length - 1)
{ {
box->text[box->position] = '\0'; box->text[box->position] = '\0';
} }
@ -151,197 +266,278 @@ static void rtgui_textbox_onkey(struct rtgui_textbox* box, struct rtgui_event_kb
char *c; char *c;
/* remove character */ /* remove character */
for (c = &box->text[box->position]; c[1] != '\0'; c++) for(c = &box->text[box->position]; c[1] != '\0'; c++)
*c = c[1]; *c = c[1];
*c = '\0'; *c = '\0';
} }
} }
else if (event->key == RTGUIK_BACKSPACE) else if(ekbd->key == RTGUIK_BACKSPACE)
{ {/* delete front character */
if ((box->position == length - 1) && length != 1)
if(box->position == length - 1)
{ {
box->text[box->position] = '\0'; box->text[box->position] = '\0';
box->position --; box->position --;
} }
else if (box->position != 0) else if(box->position != 0)
{ {
/* remove current character */ /* remove current character */
char *c; if(box->position != 0)
{
char *c;
/* remove character */ /* remove character */
for (c = &box->text[box->position - 1]; c[1] != '\0'; c++) for(c = &box->text[box->position - 1]; c[1] != '\0'; c++)
*c = c[1]; *c = c[1];
*c = '\0'; *c = '\0';
}
box->position --; box->position --;
} }
} }
else if (event->key == RTGUIK_LEFT) else if(ekbd->key == RTGUIK_LEFT)
{ {/* move to prev */
if (box->position > 0) box->position --; if(box->position > 0)
{
box->position --;
}
} }
else if (event->key == RTGUIK_RIGHT) else if(ekbd->key == RTGUIK_RIGHT)
{ {/* move to next */
if (box->position < length) box->position ++; if(box->position < length)
{
box->position ++;
}
} }
else if (event->key == RTGUIK_HOME) else if(ekbd->key == RTGUIK_HOME)
{ {/* move cursor to start */
box->position = 0; box->position = 0;
} }
else if (event->key == RTGUIK_END) else if(ekbd->key == RTGUIK_END)
{ {/* move cursor to end */
box->position = length; box->position = length;
} }
else if (event->key == RTGUIK_RETURN) else if(ekbd->key == RTGUIK_RETURN)
{ {
if (box->on_enter != RT_NULL) if(box->on_enter != RT_NULL)
{ {
box->on_enter(RTGUI_WIDGET(box), 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 else
{ {
if (isprint(event->key) || isdigit(event->key)) if(isprint(ekbd->key))
{ {/* it's may print character */
/* no buffer on this line */ /* no buffer on this line */
if (length + 1 > box->line_length) return; 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 (box->position < length - 1) 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; char* c;
for (c = &box->text[length]; c != &box->text[box->position]; c--) for(c = &box->text[length]; c != &box->text[box->position]; c--)
*c = *(c-1); *c = *(c-1);
box->text[length + 1] = '\0'; box->text[length+1] = '\0';
} }
box->text[box->position] = event->key; box->text[box->position] = ekbd->key;
box->position ++; box->position ++;
} }
} }
/* set caret to show */ _exit:
box->flag |= RTGUI_TEXTBOX_CARET_SHOW; if(box->flag & RTGUI_TEXTBOX_CARET_SHOW)
/* re-draw text box */
rtgui_theme_draw_textbox(box);
}
static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* object, struct rtgui_event* event)
{
struct rtgui_textbox* box;
RTGUI_WIDGET_EVENT_HANDLER_PREPARE
box = RTGUI_TEXTBOX(object);
/* 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(struct rtgui_object* object, struct rtgui_event* event)
{
struct rtgui_textbox* box;
RTGUI_WIDGET_EVENT_HANDLER_PREPARE
box = RTGUI_TEXTBOX(object);
/* stop caret timer */
rtgui_timer_stop(box->caret_timer);
/* set caret to hide */
box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
return RT_TRUE;
}
rt_bool_t rtgui_textbox_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{
struct rtgui_textbox* box;
RTGUI_WIDGET_EVENT_HANDLER_PREPARE
box = RTGUI_TEXTBOX(object);
switch (event->type)
{ {
case RTGUI_EVENT_PAINT: if(box->caret_timer != RT_NULL)
#ifndef RTGUI_USING_SMALL_SIZE rtgui_timer_stop(box->caret_timer);
if (widget->on_draw != RT_NULL)
widget->on_draw(RTGUI_OBJECT(widget), event);
else
#endif
rtgui_theme_draw_textbox(box);
break;
case RTGUI_EVENT_MOUSE_BUTTON: box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE; rtgui_textbox_draw_caret(box, posbak);/* refresh it */
if(box->caret_timer != RT_NULL)
#ifndef RTGUI_USING_SMALL_SIZE rtgui_timer_start(box->caret_timer);
if (widget->on_mouseclick != RT_NULL)
widget->on_mouseclick(RTGUI_OBJECT(widget), event);
else
#endif
rtgui_textbox_onmouse(box, (struct rtgui_event_mouse*)event);
return RT_TRUE;
case RTGUI_EVENT_KBD:
if (!RTGUI_WIDGET_IS_ENABLE(widget) || RTGUI_WIDGET_IS_HIDE(widget)) return RT_FALSE;
#ifndef RTGUI_USING_SMALL_SIZE
if (widget->on_key != RT_NULL)
widget->on_key(RTGUI_OBJECT(widget), event);
else
#endif
rtgui_textbox_onkey(box, (struct rtgui_event_kbd*)event);
return RT_TRUE;
} }
return RT_FALSE; /* 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;
} }
struct rtgui_textbox* rtgui_textbox_create(const char* text, rt_uint8_t flag) static rt_bool_t rtgui_textbox_onfocus(struct rtgui_object* widget, rtgui_event_t* event)
{ {
struct rtgui_textbox* box; rtgui_textbox_t* box = RTGUI_TEXTBOX(widget);
box = (struct rtgui_textbox*) rtgui_widget_create (RTGUI_TEXTBOX_TYPE); /* if there is already a timer, don't create another one. */
if (box != RT_NULL) if (box->caret_timer == RT_NULL)
{
box->caret_timer = rtgui_timer_create(100, RT_TIMER_FLAG_PERIODIC,rtgui_textbox_timeout, box);
/* set caret to show */
box->flag |= RTGUI_TEXTBOX_CARET_SHOW;
/* start caret timer */
if(box->caret_timer != RT_NULL)
rtgui_timer_start(box->caret_timer);
}
return RT_TRUE;
}
static rt_bool_t rtgui_textbox_onunfocus(struct rtgui_object* widget, rtgui_event_t* event)
{
rtgui_textbox_t* box = RTGUI_TEXTBOX(widget);
/* stop caret timer */
if(box->caret_timer != RT_NULL)
{
rtgui_timer_stop(box->caret_timer);
rtgui_timer_destory(box->caret_timer);
box->caret_timer = RT_NULL;
}
/* set caret to hide */
box->flag &= ~RTGUI_TEXTBOX_CARET_SHOW;
rtgui_textbox_draw_caret(box,box->position);
if(box->on_enter != RT_NULL)
box->on_enter(box,event);
return RT_TRUE;
}
rtgui_textbox_t* rtgui_textbox_create(const char* text, rt_uint32_t flag)
{
rtgui_textbox_t* box;
box = (struct rtgui_textbox*)rtgui_widget_create(RTGUI_TEXTBOX_TYPE);
if(box != RT_NULL)
{ {
rtgui_rect_t rect = {0, 0, RTGUI_TEXTBOX_DEFAULT_WIDTH, RTGUI_TEXTBOX_DEFAULT_HEIGHT};
/* allocate default line buffer */ /* allocate default line buffer */
rtgui_textbox_set_value(box, text); rtgui_textbox_set_value(box, text);
box->flag = flag; box->flag = flag;
rtgui_font_get_metrics(RTGUI_WIDGET(box)->gc.font, "h", &rect);
} }
return box; return box;
} }
void rtgui_textbox_destroy(struct rtgui_textbox* box) void rtgui_textbox_destroy(rtgui_textbox_t* box)
{ {
rtgui_widget_destroy(RTGUI_WIDGET(box)); rtgui_widget_destroy(RTGUI_WIDGET(box));
} }
void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text) void rtgui_textbox_ondraw(rtgui_textbox_t* box)
{ {
if (box->text != RT_NULL) /* draw button */
rtgui_rect_t rect;
struct rtgui_dc* dc;
rtgui_color_t fc;
RT_ASSERT(box != RT_NULL);
/* 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);
fc = RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box));
rtgui_rect_inflate(&rect, -1);
/* fill widget rect with white color */
RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(box)) = white;
rtgui_dc_fill_rect(dc,&rect);
rtgui_rect_inflate(&rect, 1);
/* draw border */
RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = RTGUI_RGB(123, 158, 189);
rtgui_dc_draw_rect(dc, &rect);
/* draw text */
RTGUI_WIDGET_FOREGROUND(RTGUI_WIDGET(box)) = fc;
if(box->text != RT_NULL)
{ {
if (box->line_length > rt_strlen(text) + 1) rect.x1 += RTGUI_WIDGET_DEFAULT_MARGIN;
/* draw single text */
if(box->flag & RTGUI_TEXTBOX_MASK)
{ {
rt_memcpy(box->text, text, rt_strlen(text) + 1); /* draw '*' */
/* set current position */ rt_size_t len = rt_strlen(box->text);
box->position = 0; if(len > 0)
return; {
char *text_mask = rtgui_malloc(len + 1);
rt_memset(text_mask, '*', len + 1);
text_mask[len] = 0;
rtgui_dc_draw_text(dc, text_mask, &rect);
rtgui_free(text_mask);
}
} }
else else
{ {
/* free the old text */ rtgui_dc_draw_text(dc, box->text, &rect);
rtgui_free(box->text);
box->text = RT_NULL;
} }
} }
box->line_length = RTGUI_TEXTBOX_LINE_MAX > rt_strlen(text) + 1 ? rtgui_dc_end_drawing(dc);
RTGUI_TEXTBOX_LINE_MAX : rt_strlen(text) + 1; }
/* set textbox text */
void rtgui_textbox_set_value(rtgui_textbox_t* box, const char* text)
{
if(box->text != RT_NULL)
{/* yet exist something */
/* free the old text */
rtgui_free(box->text);
box->text = RT_NULL;
}
/* no something */
box->line_length = ((rt_strlen(text)+1)/RTGUI_TEXTBOX_LINE_MAX+1)*RTGUI_TEXTBOX_LINE_MAX;
/* allocate line buffer */ /* allocate line buffer */
box->text = rtgui_malloc(box->line_length); box->text = rtgui_malloc(box->line_length);
@ -351,25 +547,26 @@ void rtgui_textbox_set_value(struct rtgui_textbox* box, const char* text)
rt_memcpy(box->text, text, rt_strlen(text) + 1); rt_memcpy(box->text, text, rt_strlen(text) + 1);
/* set current position */ /* set current position */
box->position = 0; box->position = rt_strlen(text);
} }
const char* rtgui_textbox_get_value(struct rtgui_textbox* box) const char* rtgui_textbox_get_value(rtgui_textbox_t* box)
{ {
return (const char*)box->text; return (const char*)box->text;
} }
void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length) void rtgui_textbox_set_line_length(rtgui_textbox_t* box, rt_size_t length)
{ {
rt_uint8_t* new_line; rt_uint8_t* new_line;
RT_ASSERT(box != RT_NULL); RT_ASSERT(box != RT_NULL);
/* invalid length */ /* invalid length */
if (length <= 0) return; if(length <= 0)
return;
new_line = rtgui_malloc(length); new_line = rtgui_malloc(length);
if (length < box->line_length) if(length < box->line_length)
{ {
rt_memcpy(new_line, box->text, length - 1); rt_memcpy(new_line, box->text, length - 1);
new_line[length] = '\0'; new_line[length] = '\0';
@ -383,3 +580,51 @@ void rtgui_textbox_set_line_length(struct rtgui_textbox* box, rt_size_t length)
box->line_length = length; box->line_length = length;
} }
/* get textbox text area */
void rtgui_textbox_get_edit_rect(rtgui_textbox_t *box,rtgui_rect_t *rect)
{
rtgui_widget_get_rect(RTGUI_WIDGET(box), rect);
rtgui_rect_inflate(rect,-1);
}
rt_bool_t rtgui_textbox_event_handler(struct rtgui_object *object, rtgui_event_t* event)
{
rtgui_widget_t *widget = RTGUI_WIDGET(object);
rtgui_textbox_t* box = RTGUI_TEXTBOX(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_textbox_ondraw(box);
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_textbox_onmouse(box, (struct rtgui_event_mouse*)event);
return RT_TRUE;
case RTGUI_EVENT_KBD:
#ifndef RTGUI_USING_SMALL_SIZE
if(widget->on_key != RT_NULL)
widget->on_key(RTGUI_OBJECT(widget), event);
else
#endif
rtgui_textbox_onkey(RTGUI_OBJECT(box), (struct rtgui_event*)event);
return RT_TRUE;
default:
return rtgui_widget_event_handler(RTGUI_OBJECT(widget),event);
}
return RT_FALSE;
}

View File

@ -307,6 +307,8 @@ rt_bool_t rtgui_textview_event_handler(struct rtgui_object* object, struct rtgui
} }
break; break;
} }
default:
return rtgui_widget_event_handler(RTGUI_OBJECT(widget),event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -14,7 +14,7 @@
*/ */
#include <rtgui/dc_client.h> #include <rtgui/dc_client.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/widgets/widget.h> #include <rtgui/widgets/widget.h>
#include <rtgui/widgets/window.h> #include <rtgui/widgets/window.h>
#include <rtgui/widgets/container.h> #include <rtgui/widgets/container.h>
@ -36,9 +36,7 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
widget->gc.font = rtgui_font_default(); widget->gc.font = rtgui_font_default();
widget->gc.textstyle = RTGUI_TEXTSTYLE_NORMAL; widget->gc.textstyle = RTGUI_TEXTSTYLE_NORMAL;
widget->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; widget->gc.textalign = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
#ifndef RTGUI_USING_SMALL_SIZE
widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP; widget->align = RTGUI_ALIGN_LEFT | RTGUI_ALIGN_TOP;
#endif
/* set parent and toplevel root */ /* set parent and toplevel root */
widget->parent = RT_NULL; widget->parent = RT_NULL;
@ -88,7 +86,7 @@ static void _rtgui_widget_destructor(rtgui_widget_t *widget)
rtgui_region_fini(&(widget->clip)); rtgui_region_fini(&(widget->clip));
} }
DEFINE_CLASS_TYPE(widget, "widget", DEFINE_CLASS_TYPE(widget, "widget",
RTGUI_OBJECT_TYPE, RTGUI_OBJECT_TYPE,
_rtgui_widget_constructor, _rtgui_widget_constructor,
_rtgui_widget_destructor, _rtgui_widget_destructor,
@ -114,11 +112,9 @@ void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect)
widget->extent = *rect; widget->extent = *rect;
#ifndef RTGUI_USING_SMALL_SIZE
/* reset mini width and height */ /* reset mini width and height */
widget->mini_width = rtgui_rect_width(widget->extent); widget->mini_width = rtgui_rect_width(widget->extent);
widget->mini_height = rtgui_rect_height(widget->extent); widget->mini_height = rtgui_rect_height(widget->extent);
#endif
/* it's not empty, fini it */ /* it's not empty, fini it */
if (rtgui_region_not_empty(&(widget->clip))) if (rtgui_region_not_empty(&(widget->clip)))
@ -166,7 +162,6 @@ void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect)
*rect = widget->extent; *rect = widget->extent;
} }
#ifndef RTGUI_USING_SMALL_SIZE
void rtgui_widget_set_miniwidth(rtgui_widget_t* widget, int width) void rtgui_widget_set_miniwidth(rtgui_widget_t* widget, int width)
{ {
RT_ASSERT(widget != RT_NULL); RT_ASSERT(widget != RT_NULL);
@ -180,7 +175,6 @@ void rtgui_widget_set_miniheight(rtgui_widget_t* widget, int height)
widget->mini_height = height; widget->mini_height = height;
} }
#endif
/* /*
* This function moves widget and its children to a logic point * This function moves widget and its children to a logic point
@ -410,16 +404,16 @@ struct rtgui_win* rtgui_widget_get_toplevel(rtgui_widget_t* widget)
rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event) rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t* event)
{ {
#ifndef RTGUI_USING_SMALL_SIZE
struct rtgui_widget *widget;
RT_ASSERT(object != RT_NULL); RT_ASSERT(object != RT_NULL);
RT_ASSERT(event != RT_NULL); RT_ASSERT(event != RT_NULL);
widget = RTGUI_WIDGET(object);
switch (event->type) switch (event->type)
{ {
case RTGUI_EVENT_SHOW:
return rtgui_widget_onshow(object, event);
case RTGUI_EVENT_HIDE:
return rtgui_widget_onhide(object, event);
#ifndef RTGUI_USING_SMALL_SIZE
case RTGUI_EVENT_PAINT: case RTGUI_EVENT_PAINT:
if (widget->on_draw != RT_NULL) if (widget->on_draw != RT_NULL)
return widget->on_draw(RTGUI_OBJECT(widget), event); return widget->on_draw(RTGUI_OBJECT(widget), event);
@ -444,8 +438,8 @@ rt_bool_t rtgui_widget_event_handler(struct rtgui_object* object, rtgui_event_t*
if (widget->on_size != RT_NULL) if (widget->on_size != RT_NULL)
return widget->on_size(RTGUI_OBJECT(widget), event); return widget->on_size(RTGUI_OBJECT(widget), event);
break; break;
}
#endif #endif
}
return RT_FALSE; return RT_FALSE;
} }
@ -512,12 +506,26 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
} }
} }
void rtgui_widget_show(rtgui_widget_t* widget) void rtgui_widget_show(struct rtgui_widget *widget)
{ {
/* there is no parent or the parent is hide, no show at all */ struct rtgui_event_show eshow;
if (widget->parent == RT_NULL || RT_ASSERT(widget != RT_NULL);
RTGUI_WIDGET_IS_HIDE(widget->parent))
return; if (!RTGUI_WIDGET_IS_HIDE(widget))
return;
RTGUI_EVENT_SHOW_INIT(&eshow);
if (RTGUI_OBJECT(widget)->event_handler != RT_NULL)
{
RTGUI_OBJECT(widget)->event_handler(
RTGUI_OBJECT(widget),
&eshow);
}
}
rt_bool_t rtgui_widget_onshow(struct rtgui_object *object, struct rtgui_event *event)
{
struct rtgui_widget *widget = RTGUI_WIDGET(object);
/* update the clip info of widget */ /* update the clip info of widget */
RTGUI_WIDGET_UNHIDE(widget); RTGUI_WIDGET_UNHIDE(widget);
@ -525,10 +533,14 @@ void rtgui_widget_show(rtgui_widget_t* widget)
if (widget->on_show != RT_NULL) if (widget->on_show != RT_NULL)
widget->on_show(RTGUI_OBJECT(widget), RT_NULL); widget->on_show(RTGUI_OBJECT(widget), RT_NULL);
return RT_FALSE;
} }
void rtgui_widget_hide(rtgui_widget_t* widget) rt_bool_t rtgui_widget_onhide(struct rtgui_object *object, struct rtgui_event *event)
{ {
struct rtgui_widget *widget = RTGUI_WIDGET(object);
/* hide this widget */ /* hide this widget */
RTGUI_WIDGET_HIDE(widget); RTGUI_WIDGET_HIDE(widget);
@ -549,12 +561,31 @@ void rtgui_widget_hide(rtgui_widget_t* widget)
if (widget->on_hide != RT_NULL) if (widget->on_hide != RT_NULL)
widget->on_hide(RTGUI_OBJECT(widget), RT_NULL); widget->on_hide(RTGUI_OBJECT(widget), RT_NULL);
return RT_FALSE;
}
void rtgui_widget_hide(struct rtgui_widget *widget)
{
struct rtgui_event_hide ehide;
RT_ASSERT(widget != RT_NULL);
if (RTGUI_WIDGET_IS_HIDE(widget))
return;
RTGUI_EVENT_HIDE_INIT(&ehide);
if (RTGUI_OBJECT(widget)->event_handler != RT_NULL)
{
RTGUI_OBJECT(widget)->event_handler(
RTGUI_OBJECT(widget),
&ehide);
}
} }
rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget) rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget)
{ {
rtgui_widget_t* parent; rtgui_widget_t* parent;
/* get parent widget */ /* get parent widget */
parent = widget->parent; parent = widget->parent;
while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT)) while (parent->parent != RT_NULL && (RTGUI_WIDGET_FLAG(parent) & RTGUI_WIDGET_FLAG_TRANSPARENT))
@ -591,6 +622,9 @@ void rtgui_widget_update(rtgui_widget_t* widget)
RT_ASSERT(widget != RT_NULL); RT_ASSERT(widget != RT_NULL);
if (RTGUI_WIDGET_IS_HIDE(widget))
return;
if (RTGUI_OBJECT(widget)->event_handler != RT_NULL) if (RTGUI_OBJECT(widget)->event_handler != RT_NULL)
{ {
RTGUI_OBJECT(widget)->event_handler( RTGUI_OBJECT(widget)->event_handler(

View File

@ -16,7 +16,7 @@
#include <rtgui/image.h> #include <rtgui/image.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_server.h> #include <rtgui/rtgui_server.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/widgets/window.h> #include <rtgui/widgets/window.h>
#include <rtgui/widgets/button.h> #include <rtgui/widgets/button.h>
@ -108,10 +108,6 @@ DEFINE_CLASS_TYPE(win, "win",
_rtgui_win_destructor, _rtgui_win_destructor,
sizeof(struct rtgui_win)); sizeof(struct rtgui_win));
#ifdef RTGUI_USING_DESKTOP_WINDOW
static struct rtgui_win *the_desktop_window;
#endif
rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window, rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window,
const char* title, const char* title,
rtgui_rect_t *rect, rtgui_rect_t *rect,
@ -125,23 +121,7 @@ rtgui_win_t* rtgui_win_create(struct rtgui_win* parent_window,
return RT_NULL; return RT_NULL;
/* set parent toplevel */ /* set parent toplevel */
#ifdef RTGUI_USING_DESKTOP_WINDOW
if (style & RTGUI_WIN_STYLE_DESKTOP)
{
RT_ASSERT(the_desktop_window == RT_NULL);
win->parent_window = RT_NULL;
the_desktop_window = win;
}
else if (parent_window == RT_NULL)
{
RT_ASSERT(the_desktop_window != RT_NULL);
win->parent_window = the_desktop_window;
}
else
win->parent_window = parent_window;
#else
win->parent_window = parent_window; win->parent_window = parent_window;
#endif
/* set title, rect and style */ /* set title, rect and style */
if (title != RT_NULL) if (title != RT_NULL)
@ -163,25 +143,13 @@ __on_err:
return RT_NULL; return RT_NULL;
} }
void rtgui_win_destroy(struct rtgui_win* win)
{
if (win->flag & RTGUI_WIN_FLAG_MODAL)
{
/* set the RTGUI_WIN_STYLE_DESTROY_ON_CLOSE flag so the window will be
* destroyed after the event_loop */
win->style |= RTGUI_WIN_STYLE_DESTROY_ON_CLOSE;
rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
}
else
rtgui_widget_destroy(RTGUI_WIDGET(win));
}
static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win, static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win,
struct rtgui_event *event) struct rtgui_event *event,
rt_bool_t force_close)
{ {
if (win->on_close != RT_NULL) if (win->on_close != RT_NULL)
{ {
if (win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE) if ((win->on_close(RTGUI_OBJECT(win), event) == RT_FALSE) && !force_close)
return RT_FALSE; return RT_FALSE;
} }
@ -201,6 +169,42 @@ static rt_bool_t _rtgui_win_deal_close(struct rtgui_win *win,
return RT_TRUE; return RT_TRUE;
} }
void rtgui_win_destroy(struct rtgui_win* win)
{
/* close the window first if it's not. */
if (!(win->flag & RTGUI_WIN_FLAG_CLOSED))
{
struct rtgui_event_win_close eclose;
RTGUI_EVENT_WIN_CLOSE_INIT(&eclose);
eclose.wid = win;
if (win->style & RTGUI_WIN_STYLE_DESTROY_ON_CLOSE)
{
_rtgui_win_deal_close(win,
(struct rtgui_event*)&eclose,
RT_TRUE);
return;
}
else
_rtgui_win_deal_close(win,
(struct rtgui_event*)&eclose,
RT_TRUE);
}
if (win->flag & RTGUI_WIN_FLAG_MODAL)
{
/* set the RTGUI_WIN_STYLE_DESTROY_ON_CLOSE flag so the window will be
* destroyed after the event_loop */
win->style |= RTGUI_WIN_STYLE_DESTROY_ON_CLOSE;
rtgui_win_end_modal(win, RTGUI_MODAL_CANCEL);
}
else
{
rtgui_widget_destroy(RTGUI_WIDGET(win));
}
}
/* send a close event to myself to get a consistent behavior */ /* send a close event to myself to get a consistent behavior */
rt_bool_t rtgui_win_close(struct rtgui_win* win) rt_bool_t rtgui_win_close(struct rtgui_win* win)
{ {
@ -209,14 +213,17 @@ rt_bool_t rtgui_win_close(struct rtgui_win* win)
RTGUI_EVENT_WIN_CLOSE_INIT(&eclose); RTGUI_EVENT_WIN_CLOSE_INIT(&eclose);
eclose.wid = win; eclose.wid = win;
return _rtgui_win_deal_close(win, return _rtgui_win_deal_close(win,
(struct rtgui_event*)&eclose); (struct rtgui_event*)&eclose,
RT_FALSE);
} }
rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal) rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
{ {
struct rtgui_event_win_show eshow;
rt_base_t exit_code = -1; rt_base_t exit_code = -1;
struct rtgui_app *app;
struct rtgui_event_win_show eshow;
app = rtgui_app_self();
RTGUI_EVENT_WIN_SHOW_INIT(&eshow); RTGUI_EVENT_WIN_SHOW_INIT(&eshow);
eshow.wid = win; eshow.wid = win;
@ -230,29 +237,33 @@ rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
return exit_code; return exit_code;
} }
/* set window unhidden before notify the server */
rtgui_widget_show(RTGUI_WIDGET(win));
if (rtgui_server_post_event_sync(RTGUI_EVENT(&eshow), if (rtgui_server_post_event_sync(RTGUI_EVENT(&eshow),
sizeof(struct rtgui_event_win_show) sizeof(struct rtgui_event_win_show)) != RT_EOK)
) != RT_EOK)
{ {
rt_kprintf("show win failed\n"); /* It could not be shown if a parent window is hidden. */
rtgui_widget_hide(RTGUI_WIDGET(win));
return exit_code; return exit_code;
} }
/* set window unhidden */
RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win));
if (win->focused_widget == RT_NULL) if (win->focused_widget == RT_NULL)
rtgui_widget_focus(RTGUI_WIDGET(win)); rtgui_widget_focus(RTGUI_WIDGET(win));
/* set main window */
if (app->main_object == RT_NULL)
rtgui_app_set_main_win(win);
if (is_modal == RT_TRUE) if (is_modal == RT_TRUE)
{ {
struct rtgui_application *app; struct rtgui_app *app;
struct rtgui_event_win_modal_enter emodal; struct rtgui_event_win_modal_enter emodal;
RTGUI_EVENT_WIN_MODAL_ENTER_INIT(&emodal); RTGUI_EVENT_WIN_MODAL_ENTER_INIT(&emodal);
emodal.wid = win; emodal.wid = win;
app = rtgui_application_self(); app = rtgui_app_self();
RT_ASSERT(app != RT_NULL); RT_ASSERT(app != RT_NULL);
win->flag |= RTGUI_WIN_FLAG_MODAL; win->flag |= RTGUI_WIN_FLAG_MODAL;
@ -263,7 +274,7 @@ rt_base_t rtgui_win_show(struct rtgui_win* win, rt_bool_t is_modal)
app->modal_object = RTGUI_OBJECT(win); app->modal_object = RTGUI_OBJECT(win);
exit_code = rtgui_application_run(app); exit_code = rtgui_app_run(app);
app->modal_object = RT_NULL; app->modal_object = RT_NULL;
win->flag &= ~RTGUI_WIN_FLAG_MODAL; win->flag &= ~RTGUI_WIN_FLAG_MODAL;
@ -282,7 +293,7 @@ void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code)
if (win == RT_NULL || !(win->flag & RTGUI_WIN_FLAG_MODAL)) if (win == RT_NULL || !(win->flag & RTGUI_WIN_FLAG_MODAL))
return; return;
rtgui_application_exit(rtgui_application_self(), modal_code); rtgui_app_exit(rtgui_app_self(), modal_code);
/* remove modal mode */ /* remove modal mode */
win->flag &= ~RTGUI_WIN_FLAG_MODAL; win->flag &= ~RTGUI_WIN_FLAG_MODAL;
@ -291,9 +302,6 @@ void rtgui_win_end_modal(struct rtgui_win* win, rtgui_modal_code_t modal_code)
void rtgui_win_hiden(struct rtgui_win* win) void rtgui_win_hiden(struct rtgui_win* win)
{ {
RT_ASSERT(win != RT_NULL); RT_ASSERT(win != RT_NULL);
#ifdef RTGUI_USING_DESKTOP_WINDOW
RT_ASSERT(win != the_desktop_window);
#endif
if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) && if (!RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(win)) &&
win->flag & RTGUI_WIN_FLAG_CONNECTED) win->flag & RTGUI_WIN_FLAG_CONNECTED)
@ -310,12 +318,21 @@ void rtgui_win_hiden(struct rtgui_win* win)
return; return;
} }
/* set window hide and deactivated */ rtgui_widget_hide(RTGUI_WIDGET(win));
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win));
win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE; win->flag &= ~RTGUI_WIN_FLAG_ACTIVATE;
} }
} }
rt_err_t rtgui_win_activate(struct rtgui_win *win)
{
struct rtgui_event_win_activate eact;
RTGUI_EVENT_WIN_ACTIVATE_INIT(&eact);
eact.wid = win;
return rtgui_server_post_event_sync(RTGUI_EVENT(&eact),
sizeof(eact));
}
rt_bool_t rtgui_win_is_activated(struct rtgui_win* win) rt_bool_t rtgui_win_is_activated(struct rtgui_win* win)
{ {
RT_ASSERT(win != RT_NULL); RT_ASSERT(win != RT_NULL);
@ -341,7 +358,7 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y)
if (win->flag & RTGUI_WIN_FLAG_CONNECTED) if (win->flag & RTGUI_WIN_FLAG_CONNECTED)
{ {
/* set win hide firstly */ /* set win hide firstly */
RTGUI_WIDGET_HIDE(RTGUI_WIDGET(win)); rtgui_widget_hide(RTGUI_WIDGET(win));
emove.wid = win; emove.wid = win;
emove.x = x; emove.x = x;
@ -354,7 +371,7 @@ void rtgui_win_move(struct rtgui_win* win, int x, int y)
} }
/* set window visible */ /* set window visible */
RTGUI_WIDGET_UNHIDE(RTGUI_WIDGET(win)); rtgui_widget_show(RTGUI_WIDGET(win));
return; return;
} }
@ -405,7 +422,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_even
break; break;
case RTGUI_EVENT_WIN_CLOSE: case RTGUI_EVENT_WIN_CLOSE:
_rtgui_win_deal_close(win, event); _rtgui_win_deal_close(win, event, RT_FALSE);
/* don't broadcast WIN_CLOSE event to others */ /* don't broadcast WIN_CLOSE event to others */
return RT_TRUE; return RT_TRUE;
@ -522,20 +539,21 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_object* object, struct rtgui_even
/* we should dispatch key event firstly */ /* we should dispatch key event firstly */
if (!(win->flag & RTGUI_WIN_FLAG_HANDLE_KEY)) if (!(win->flag & RTGUI_WIN_FLAG_HANDLE_KEY))
{ {
struct rtgui_widget *widget;
rt_bool_t res = RT_FALSE; rt_bool_t res = RT_FALSE;
/* we should dispatch the key event just once. Once entered the /* we should dispatch the key event just once. Once entered the
* dispatch mode, we should swtich to key handling mode. */ * dispatch mode, we should swtich to key handling mode. */
win->flag |= RTGUI_WIN_FLAG_HANDLE_KEY; win->flag |= RTGUI_WIN_FLAG_HANDLE_KEY;
/* dispatch the key event */ /* dispatch the key event */
if (win->focused_widget != RT_NULL && for (widget = win->focused_widget;
RTGUI_OBJECT(win->focused_widget)->event_handler != RT_NULL) widget && !res;
res = RTGUI_OBJECT(win->focused_widget)->event_handler( widget = widget->parent)
RTGUI_OBJECT(win->focused_widget), event); {
if (RTGUI_OBJECT(widget)->event_handler != RT_NULL)
/* if the focused widget doesn't handle it, I will handle it. */ res = RTGUI_OBJECT(widget)->event_handler(
if (res != RT_TRUE && win->on_key != RT_NULL) RTGUI_OBJECT(widget), event);
res = win->on_key(RTGUI_OBJECT(win), event); }
win->flag &= ~RTGUI_WIN_FLAG_HANDLE_KEY; win->flag &= ~RTGUI_WIN_FLAG_HANDLE_KEY;
return res; return res;

View File

@ -36,6 +36,7 @@ demo_view_combobox.c
demo_view_slider.c demo_view_slider.c
demo_view_notebook.c demo_view_notebook.c
demo_view_mywidget.c demo_view_mywidget.c
demo_view_box.c
mywidget.c mywidget.c
""") """)

View File

@ -1,6 +1,6 @@
#include <rtgui/rtgui.h> #include <rtgui/rtgui.h>
#include <rtgui/rtgui_system.h> #include <rtgui/rtgui_system.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/widgets/window.h> #include <rtgui/widgets/window.h>
#include <rtgui/widgets/notebook.h> #include <rtgui/widgets/notebook.h>
@ -11,7 +11,7 @@ static rt_bool_t demo_handle_key(struct rtgui_object* object, struct rtgui_event
{ {
struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event; struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
if (ekbd->type == RTGUI_KEYDOWN) if (ekbd->type == RTGUI_KEYUP)
{ {
if (ekbd->key == RTGUIK_RIGHT) if (ekbd->key == RTGUIK_RIGHT)
{ {
@ -30,10 +30,10 @@ static rt_bool_t demo_handle_key(struct rtgui_object* object, struct rtgui_event
struct rtgui_win *main_win; struct rtgui_win *main_win;
static void application_entry(void* parameter) static void application_entry(void* parameter)
{ {
struct rtgui_application *app; struct rtgui_app *app;
struct rtgui_rect rect; struct rtgui_rect rect;
app = rtgui_application_create(rt_thread_self(), "gui_demo"); app = rtgui_app_create(rt_thread_self(), "gui_demo");
if (app == RT_NULL) if (app == RT_NULL)
return; return;
@ -41,11 +41,10 @@ static void application_entry(void* parameter)
rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect); rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), &rect);
main_win = rtgui_win_create(RT_NULL, "demo_win", &rect, main_win = rtgui_win_create(RT_NULL, "demo_win", &rect,
/*RTGUI_WIN_STYLE_DESKTOP_DEFAULT);*/ RTGUI_WIN_STYLE_NO_BORDER | RTGUI_WIN_STYLE_NO_TITLE);
RTGUI_WIN_STYLE_NO_BORDER | RTGUI_WIN_STYLE_NO_TITLE);
if (main_win == RT_NULL) if (main_win == RT_NULL)
{ {
rtgui_application_destroy(app); rtgui_app_destroy(app);
return; return;
} }
@ -56,12 +55,14 @@ static void application_entry(void* parameter)
if (the_notebook == RT_NULL) if (the_notebook == RT_NULL)
{ {
rtgui_win_destroy(main_win); rtgui_win_destroy(main_win);
rtgui_application_destroy(app); rtgui_app_destroy(app);
return; return;
} }
rtgui_container_add_child(RTGUI_CONTAINER(main_win), RTGUI_WIDGET(the_notebook)); rtgui_container_add_child(RTGUI_CONTAINER(main_win), RTGUI_WIDGET(the_notebook));
demo_view_box();
/* 初始化各个例子的视图 */ /* 初始化各个例子的视图 */
demo_view_benchmark(); demo_view_benchmark();
@ -112,12 +113,12 @@ static void application_entry(void* parameter)
rtgui_win_show(main_win, RT_FALSE); rtgui_win_show(main_win, RT_FALSE);
/* 执行工作台事件循环 */ /* 执行工作台事件循环 */
rtgui_application_run(app); rtgui_app_run(app);
rtgui_application_destroy(app); rtgui_app_destroy(app);
} }
void application_init(void) void application_init()
{ {
static rt_bool_t inited = RT_FALSE; static rt_bool_t inited = RT_FALSE;
@ -138,7 +139,7 @@ void application_init(void)
#ifdef RT_USING_FINSH #ifdef RT_USING_FINSH
#include <finsh.h> #include <finsh.h>
void application(void) void application()
{ {
application_init(); application_init();
} }

View File

@ -45,11 +45,7 @@ static void listitem_action(rtgui_widget_t* widget, void* parameter)
} }
/* 返回功能的动作函数 */ /* 返回功能的动作函数 */
#if RT_VERSION == 4
static void return_action(rtgui_widget_t* widget, void* parameter) static void return_action(rtgui_widget_t* widget, void* parameter)
#else
static void return_action(void* parameter)
#endif
{ {
/* 退出模态显示 */ /* 退出模态显示 */
rtgui_container_end_modal(RTGUI_CONTAINER(_view), RTGUI_MODAL_OK); rtgui_container_end_modal(RTGUI_CONTAINER(_view), RTGUI_MODAL_OK);

View File

@ -1,10 +1,11 @@
#include <rtgui/rtgui.h> #include <rtgui/rtgui.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/widgets/container.h> #include <rtgui/widgets/container.h>
#include <rtgui/widgets/notebook.h> #include <rtgui/widgets/notebook.h>
#include <rtgui/widgets/button.h> #include <rtgui/widgets/button.h>
#include <rtgui/widgets/staticline.h> #include <rtgui/widgets/staticline.h>
#include <rtgui/widgets/box.h>
extern struct rtgui_notebook *the_notebook; extern struct rtgui_notebook *the_notebook;
@ -130,7 +131,6 @@ void demo_view_get_logic_rect(rtgui_container_t* container, rtgui_rect_t *rect)
/* 当是标准版本时这个函数用于返回自动布局引擎box控件 */ /* 当是标准版本时这个函数用于返回自动布局引擎box控件 */
#ifndef RTGUI_USING_SMALL_SIZE #ifndef RTGUI_USING_SMALL_SIZE
#include <rtgui/widgets/box.h>
struct rtgui_box* demo_view_create_box(struct rtgui_container *container, int orient) struct rtgui_box* demo_view_create_box(struct rtgui_container *container, int orient)
{ {
rtgui_rect_t rect; rtgui_rect_t rect;
@ -142,7 +142,7 @@ struct rtgui_box* demo_view_create_box(struct rtgui_container *container, int or
rect.y2 -= 25; rect.y2 -= 25;
/* 创建一个自动布局引擎 */ /* 创建一个自动布局引擎 */
box = rtgui_box_create(orient, &rect); box = rtgui_box_create(orient, 5);
/* 添加box控件到视图中 */ /* 添加box控件到视图中 */
rtgui_container_add_child(container, RTGUI_WIDGET(box)); rtgui_container_add_child(container, RTGUI_WIDGET(box));

View File

@ -15,7 +15,7 @@
#define __DEMO_VIEW_H__ #define __DEMO_VIEW_H__
#include <rtgui/rtgui.h> #include <rtgui/rtgui.h>
#include <rtgui/rtgui_application.h> #include <rtgui/rtgui_app.h>
#include <rtgui/widgets/container.h> #include <rtgui/widgets/container.h>
/* 如果是标准版本可以启用box自动布局引擎 */ /* 如果是标准版本可以启用box自动布局引擎 */

View File

@ -74,18 +74,21 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev
{ {
struct rtgui_event_kbd *kbd = (struct rtgui_event_kbd*)event; 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 (RTGUI_KBD_IS_UP(kbd))
{ {
if (running) if (running)
{ {
/* stop */ /* stop */
rtgui_application_set_onidle(RT_NULL); rtgui_app_set_onidle(RT_NULL);
_draw_default(object, event); _draw_default(object, event);
} }
else else
{ {
/* run */ /* run */
rtgui_application_set_onidle(_onidle); rtgui_app_set_onidle(_onidle);
} }
running = !running; running = !running;
@ -101,11 +104,19 @@ rt_bool_t benchmark_event_handler(struct rtgui_object *object, rtgui_event_t *ev
return RT_FALSE; return RT_FALSE;
} }
static rt_bool_t _benchmark_onshow(struct rtgui_object *obj, struct rtgui_event* ev)
{
rtgui_widget_focus(RTGUI_WIDGET(obj));
return RT_TRUE;
}
rtgui_container_t *demo_view_benchmark(void) rtgui_container_t *demo_view_benchmark(void)
{ {
srand(100); srand(100);
container = demo_view("»æͼ²âÊÔ"); container = demo_view("»æͼ²âÊÔ");
RTGUI_WIDGET(container)->flag |= RTGUI_WIDGET_FLAG_FOCUSABLE;
rtgui_object_set_event_handler(RTGUI_OBJECT(container), benchmark_event_handler); rtgui_object_set_event_handler(RTGUI_OBJECT(container), benchmark_event_handler);
rtgui_widget_set_onshow(RTGUI_WIDGET(container), _benchmark_onshow);
return container; return container;
} }

View File

@ -1,15 +1,44 @@
#include "demo_view.h" #include "demo_view.h"
#ifndef RTGUI_USING_SMALL_SIZE
#include <rtgui/widgets/box.h> #include <rtgui/widgets/box.h>
#include <rtgui/widgets/panel.h>
#include <rtgui/widgets/label.h>
#include <rtgui/widgets/button.h>
rtgui_container_t* demo_view_box(rtgui_workbench_t* workbench) rtgui_container_t* demo_view_box(void)
{ {
rtgui_rect_t rect; rtgui_rect_t rect;
rtgui_container_t* view; rtgui_container_t* view;
struct rtgui_panel *panel;
struct rtgui_box *box;
view = demo_view(workbench, "Box View"); struct rtgui_label *label;
struct rtgui_button *button;
view = demo_view("Box View");
demo_view_get_rect(view, &rect); demo_view_get_rect(view, &rect);
panel = rtgui_panel_create(RTGUI_BORDER_NONE);
rtgui_widget_set_rect(RTGUI_WIDGET(panel), &rect);
rtgui_container_add_child(RTGUI_CONTAINER(view), RTGUI_WIDGET(panel));
box = rtgui_box_create(RTGUI_VERTICAL, 5);
rtgui_container_set_box(RTGUI_CONTAINER(panel), box);
label = rtgui_label_create("label 1");
rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(label));
label = rtgui_label_create("label 2");
rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(label));
button = rtgui_button_create("button 1");
rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(button));
button = rtgui_button_create("button 2");
rtgui_container_add_child(RTGUI_CONTAINER(panel), RTGUI_WIDGET(button));
rtgui_widget_set_miniheight(RTGUI_WIDGET(button), 25);
RTGUI_WIDGET_ALIGN(button) = RTGUI_ALIGN_EXPAND;
rtgui_container_layout(RTGUI_CONTAINER(panel));
return view; return view;
} }
#endif

View File

@ -26,7 +26,7 @@ static void open_btn_onbutton(rtgui_widget_t* widget, struct rtgui_event* event)
filelist = rtgui_filelist_view_create("/", "*.*", &rect); filelist = rtgui_filelist_view_create("/", "*.*", &rect);
#endif #endif
/* 模态显示一个文件列表视图,以提供给用户选择图像文件 */ /* 模态显示一个文件列表视图,以提供给用户选择图像文件 */
if (rtgui_container_show(RTGUI_CONTAINER(filelist), RT_TRUE) == RTGUI_MODAL_OK) if (rtgui_widget_show(RTGUI_WIDGET(filelist), RT_TRUE) == RTGUI_MODAL_OK)
{ {
char path[32], image_type[8]; char path[32], image_type[8];

View File

@ -141,14 +141,16 @@ static struct rtgui_listbox_item items[] =
{"list #3", RT_NULL}, {"list #3", RT_NULL},
}; };
static void on_items(rtgui_widget_t* widget, struct rtgui_event* event) static rt_bool_t on_items(struct rtgui_object* object, struct rtgui_event* event)
{ {
rtgui_listbox_t* box; rtgui_listbox_t* box;
/* get listbox */ /* get listbox */
box = RTGUI_LISTBOX(widget); box = RTGUI_LISTBOX(object);
/* 打印当前的项 */ /* 打印当前的项 */
rt_kprintf("current item: %d\n", box->current_item); rt_kprintf("current item: %d\n", box->current_item);
return RT_TRUE;
} }
/* 创建用于演示label控件的视图 */ /* 创建用于演示label控件的视图 */

View File

@ -204,14 +204,16 @@ void _rtgui_listctrl_item_draw(struct rtgui_listctrl *list,
} }
} }
static void on_items(rtgui_widget_t* widget, struct rtgui_event* event) static rt_bool_t on_items(struct rtgui_object* object, struct rtgui_event* event)
{ {
rtgui_listctrl_t* ctrl; rtgui_listctrl_t* ctrl;
/* get listctrl */ /* get listctrl */
ctrl = RTGUI_LISTCTRL(widget); ctrl = RTGUI_LISTCTRL(object);
/* 打印当前的项 */ /* 打印当前的项 */
rt_kprintf("current item: %d\n", ctrl->current_item); rt_kprintf("current item: %d\n", ctrl->current_item);
return RT_TRUE;
} }
/* 创建用于演示label控件的视图 */ /* 创建用于演示label控件的视图 */

View File

@ -7,7 +7,7 @@
#include <rtgui/widgets/menu.h> #include <rtgui/widgets/menu.h>
#include <rtgui/widgets/button.h> #include <rtgui/widgets/button.h>
static rt_bool_t _onmenuitem(struct rtgui_widget *widget, struct rtgui_event* event) static rt_bool_t _onmenuitem(struct rtgui_object *object, struct rtgui_event* event)
{ {
rt_kprintf("menu action!!\n"); rt_kprintf("menu action!!\n");
return RT_TRUE; return RT_TRUE;
@ -31,15 +31,17 @@ static const rtgui_menu_item_t items[] =
}; };
static rtgui_menu_t* menu; static rtgui_menu_t* menu;
static _onmenu(struct rtgui_widget* widget, struct rtgui_event* event) static rt_bool_t _onmenu(struct rtgui_object* object, struct rtgui_event* event)
{ {
rtgui_rect_t rect; rtgui_rect_t rect;
rtgui_widget_get_rect(widget, &rect); rtgui_widget_get_rect(RTGUI_WIDGET(object), &rect);
rtgui_widget_rect_to_device(widget, &rect); rtgui_widget_rect_to_device(RTGUI_WIDGET(object), &rect);
if (menu != RT_NULL) if (menu != RT_NULL)
rtgui_menu_pop(menu, rect.x1, rect.y2 + 5); rtgui_menu_pop(menu, rect.x1, rect.y2 + 5);
return RT_TRUE;
} }
/* 创建用于演示menu控件的视图 */ /* 创建用于演示menu控件的视图 */

View File

@ -57,14 +57,16 @@ static void create_normal_win(void)
} }
/* 触发正常窗口显示 */ /* 触发正常窗口显示 */
static void demo_normal_window_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) static void demo_normal_window_onbutton(struct rtgui_object* object, rtgui_event_t* event)
{ {
rt_sprintf(normal_window_label_text, rt_sprintf(normal_window_label_text,
"第 %d 次显示", normal_window_show_count); "第 %d 次显示", normal_window_show_count);
rtgui_label_set_text(normal_window_label, rtgui_label_set_text(normal_window_label,
normal_window_label_text); normal_window_label_text);
/* 非模态显示窗口 */ if (RTGUI_WIDGET_IS_HIDE(RTGUI_WIDGET(normal_window)))
rtgui_win_show(normal_window, RT_FALSE); rtgui_win_show(normal_window, RT_FALSE);
else
rtgui_win_activate(normal_window);
} }
/* 获取一个递增的窗口标题 */ /* 获取一个递增的窗口标题 */
@ -91,10 +93,6 @@ void diag_close(struct rtgui_timer* timer, void* parameter)
{ {
/* 超时,关闭对话框 */ /* 超时,关闭对话框 */
rtgui_win_destroy(msgbox); rtgui_win_destroy(msgbox);
/* 停止并删除定时器 */
rtgui_timer_stop(timer);
rtgui_timer_destory(timer);
} }
} }
@ -117,7 +115,7 @@ static rt_uint16_t delta_x = 20;
static rt_uint16_t delta_y = 40; static rt_uint16_t delta_y = 40;
/* 触发自动窗口显示 */ /* 触发自动窗口显示 */
static void demo_autowin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) static void demo_autowin_onbutton(struct rtgui_object* object, rtgui_event_t* event)
{ {
struct rtgui_rect rect ={50, 50, 200, 200}; struct rtgui_rect rect ={50, 50, 200, 200};
@ -147,7 +145,7 @@ static void demo_autowin_onbutton(struct rtgui_widget* widget, rtgui_event_t* ev
} }
/* 触发模态窗口显示 */ /* 触发模态窗口显示 */
static void demo_modalwin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) static void demo_modalwin_onbutton(struct rtgui_object* object, rtgui_event_t* event)
{ {
rtgui_win_t *win; rtgui_win_t *win;
rtgui_label_t *label; rtgui_label_t *label;
@ -177,19 +175,19 @@ static void demo_modalwin_onbutton(struct rtgui_widget* widget, rtgui_event_t* e
rtgui_win_destroy(win); rtgui_win_destroy(win);
} }
static void demo_close_ntitle_window(struct rtgui_widget* widget, rtgui_event_t* event) static void demo_close_ntitle_window(struct rtgui_object* object, rtgui_event_t* event)
{ {
rtgui_win_t* win; rtgui_win_t* win;
/* 获得最顶层控件 */ /* 获得最顶层控件 */
win = RTGUI_WIN(rtgui_widget_get_toplevel(widget)); win = RTGUI_WIN(rtgui_widget_get_toplevel(RTGUI_WIDGET(object)));
/* 销毁窗口 */ /* 销毁窗口 */
rtgui_win_destroy(win); rtgui_win_destroy(win);
} }
/* 触发无标题窗口显示 */ /* 触发无标题窗口显示 */
static void demo_ntitlewin_onbutton(struct rtgui_widget* widget, rtgui_event_t* event) static void demo_ntitlewin_onbutton(struct rtgui_object* object, rtgui_event_t* event)
{ {
rtgui_win_t *win; rtgui_win_t *win;
rtgui_label_t *label; rtgui_label_t *label;

View File

@ -71,10 +71,10 @@ static void rtgui_mywidget_onmouse(struct rtgui_mywidget* me, struct rtgui_event
} }
/* mywidget控件的事件处理函<E79086><E587BD>?*/ /* mywidget控件的事件处理函<E79086><E587BD>?*/
rt_bool_t rtgui_mywidget_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) rt_bool_t rtgui_mywidget_event_handler(struct rtgui_object* object, struct rtgui_event* event)
{ {
/* 调用事件处理函数时widget指针指向控件本身所以先获得相应控件对象的指<E79A84><E68C87>?*/ /* 调用事件处理函数时widget指针指向控件本身所以先获得相应控件对象的指<E79A84><E68C87>?*/
struct rtgui_mywidget* me = RTGUI_MYWIDGET(widget); struct rtgui_mywidget* me = RTGUI_MYWIDGET(object);
switch (event->type) switch (event->type)
{ {
@ -90,7 +90,7 @@ rt_bool_t rtgui_mywidget_event_handler(struct rtgui_widget* widget, struct rtgui
/* 其他事件调用父类的事件处理函<E79086><E587BD>?*/ /* 其他事件调用父类的事件处理函<E79086><E587BD>?*/
default: default:
return rtgui_widget_event_handler(RTGUI_OBJECT(widget), event); return rtgui_widget_event_handler(object, event);
} }
return RT_FALSE; return RT_FALSE;

View File

@ -45,6 +45,6 @@ void rtgui_mywidget_destroy(struct rtgui_mywidget* me);
* 对ä¸ä¸ªæŽ§ä»èŒè¨ï¼Œå¦æžœæ´¾çŸèªå®ƒçšå­<EFBFBD>控ä»å¾ˆå<EFBFBD>¯èƒ½ä¼šè°ƒç¨çˆæŽ§ä»çšäºä»å¤ç<EFBFBD>å½æ°ï¼Œ * 对ä¸ä¸ªæŽ§ä»èŒè¨ï¼Œå¦æžœæ´¾çŸèªå®ƒçšå­<EFBFBD>控ä»å¾ˆå<EFBFBD>¯èƒ½ä¼šè°ƒç¨çˆæŽ§ä»çšäºä»å¤ç<EFBFBD>å½æ°ï¼Œ
* æ以è¿éŒéç¨å¬å¼å£°æ˜Žçšæ¹å¼<EFBFBD>ã? * æ以è¿éŒéç¨å¬å¼å£°æ˜Žçšæ¹å¼<EFBFBD>ã?
*/ */
rt_bool_t rtgui_mywidget_event_handler(struct rtgui_widget* widget, struct rtgui_event* event); rt_bool_t rtgui_mywidget_event_handler(struct rtgui_object* object, struct rtgui_event* event);
#endif #endif