From 97cc2b9e4cdc80b883827f6f6326c93c7caf87ca Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Tue, 28 Dec 2010 00:06:05 +0000 Subject: [PATCH] update notebook control; fix rtgui_widget_hide issue. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1226 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/rtgui/common/filerw.c | 918 +++++++++--------- .../rtgui/include/rtgui/widgets/notebook.h | 12 +- .../rtgui/include/rtgui/widgets/widget.h | 2 + components/rtgui/server/topwin.c | 2 + components/rtgui/widgets/listctrl.c | 101 +- components/rtgui/widgets/notebook.c | 131 ++- components/rtgui/widgets/widget.c | 43 +- 7 files changed, 730 insertions(+), 479 deletions(-) diff --git a/components/rtgui/common/filerw.c b/components/rtgui/common/filerw.c index 3ad9e83054..3d50bbb36f 100644 --- a/components/rtgui/common/filerw.c +++ b/components/rtgui/common/filerw.c @@ -1,463 +1,463 @@ -/* - * File : filerw.c - * This file is part of RT-Thread RTOS - * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rt-thread.org/license/LICENSE - * - * Change Logs: - * Date Author Notes - * 2009-10-16 Bernard first version - */ - -#include -#include - -#ifdef RTGUI_USING_DFS_FILERW -#include - -/* standard file read/write */ -struct rtgui_filerw_stdio -{ - /* inherit from rtgui_filerw */ - struct rtgui_filerw parent; - - int fd; - rt_bool_t eof; -}; - -static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END}; - - if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END) - { - return -1; - } - - return lseek(stdio_filerw->fd, offset, stdio_whence[whence]); -} - -static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum) -{ - int result; - - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - /* end of file */ - if (stdio_filerw->eof == RT_TRUE) return -1; - - result = read(stdio_filerw->fd, ptr, size * maxnum); - if (result == 0) stdio_filerw->eof = RT_TRUE; - - return result; -} - -static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - return write(stdio_filerw->fd, (char*)ptr, size * num); -} - -static int stdio_tell(struct rtgui_filerw* context) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - return lseek(stdio_filerw->fd, 0, SEEK_CUR); -} - -static int stdio_eof(struct rtgui_filerw* context) -{ - int result; - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - if (stdio_filerw->eof == RT_TRUE) result = 1; - else result = -1; - - return result; -} - -static int stdio_close(struct rtgui_filerw *context) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - if (stdio_filerw) - { - close(stdio_filerw->fd); - rtgui_free(stdio_filerw); - - return 0; - } - - return -1; -} -#elif defined(RTGUI_USING_STDIO_FILERW) -#include - -/* standard file read/write */ -struct rtgui_filerw_stdio -{ - /* inherit from rtgui_filerw */ - struct rtgui_filerw parent; - - FILE* fp; -}; - -static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END}; - - if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END) - { - return -1; - } - - if (fseek(stdio_filerw->fp, offset, stdio_whence[whence]) == 0) - { - return ftell(stdio_filerw->fp); - } - - return -1; -} - -static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum) -{ - size_t nread; - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - nread = fread(ptr, size, maxnum, stdio_filerw->fp); - if (nread == 0 && ferror(stdio_filerw->fp)) - { - return -1; - } - - return nread; -} - -static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num) -{ - size_t nwrote; - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - nwrote = fwrite(ptr, size, num, stdio_filerw->fp); - - if ( nwrote == 0 && ferror(stdio_filerw->fp) ) - { - return -1; - } - - return nwrote; -} - -static int stdio_tell(struct rtgui_filerw* context) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - return ftell(stdio_filerw->fp); -} - -static int stdio_eof(struct rtgui_filerw* context) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - return feof(stdio_filerw->fp); -} - -static int stdio_close(struct rtgui_filerw *context) -{ - struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; - - if (stdio_filerw) - { - fclose(stdio_filerw->fp); - rtgui_free(stdio_filerw); - - return 0; - } - - return -1; -} -#endif - -/* memory file read/write */ -struct rtgui_filerw_mem -{ - /* inherit from rtgui_filerw */ - struct rtgui_filerw parent; - - const rt_uint8_t *mem_base, *mem_position, *mem_end; -}; - -static int mem_seek(struct rtgui_filerw *context, rt_off_t offset, int whence) -{ - const rt_uint8_t* newpos; - struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; - - RT_ASSERT(mem != RT_NULL); - - switch (whence) { - case RTGUI_FILE_SEEK_SET: - newpos = mem->mem_base + offset; - break; - - case RTGUI_FILE_SEEK_CUR: - newpos = mem->mem_position + offset; - break; - - case RTGUI_FILE_SEEK_END: - newpos = mem->mem_end + offset; - break; - - default: - return -1; - } - - if ( newpos < mem->mem_base ) - newpos = mem->mem_base; - - if ( newpos > mem->mem_end ) - newpos = mem->mem_end; - - mem->mem_position = newpos; - return mem->mem_position- mem->mem_base; -} - -static int mem_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum) -{ - int total_bytes; - int mem_available; - struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; - - total_bytes = (maxnum * size); - if ( (maxnum <= 0) || (size <= 0) || ((total_bytes / maxnum) != size) ) - { - return -1; - } - - mem_available = mem->mem_end - mem->mem_position; - if (total_bytes > mem_available) - total_bytes = mem_available; - - rt_memcpy(ptr, mem->mem_position, total_bytes); - mem->mem_position += total_bytes; - - return (total_bytes / size); -} - -static int mem_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num) +/* + * File : filerw.c + * This file is part of RT-Thread RTOS + * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rt-thread.org/license/LICENSE + * + * Change Logs: + * Date Author Notes + * 2009-10-16 Bernard first version + */ + +#include +#include + +#ifdef RTGUI_USING_DFS_FILERW +#include + +/* standard file read/write */ +struct rtgui_filerw_stdio { -#if 0 - struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; - - if ((mem->mem_position + (num * size)) > mem->mem_end) - { - num = (mem->mem_end - mem->mem_position)/size; - } - - rt_memcpy(mem->mem_position, ptr, num*size); - mem->mem_position += num*size; - + /* inherit from rtgui_filerw */ + struct rtgui_filerw parent; + + int fd; + rt_bool_t eof; +}; + +static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END}; + + if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END) + { + return -1; + } + + return lseek(stdio_filerw->fd, offset, stdio_whence[whence]); +} + +static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum) +{ + int result; + + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + /* end of file */ + if (stdio_filerw->eof == RT_TRUE) return -1; + + result = read(stdio_filerw->fd, ptr, size * maxnum); + if (result == 0) stdio_filerw->eof = RT_TRUE; + + return result; +} + +static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + return write(stdio_filerw->fd, (char*)ptr, size * num); +} + +static int stdio_tell(struct rtgui_filerw* context) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + return lseek(stdio_filerw->fd, 0, SEEK_CUR); +} + +static int stdio_eof(struct rtgui_filerw* context) +{ + int result; + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + if (stdio_filerw->eof == RT_TRUE) result = 1; + else result = -1; + + return result; +} + +static int stdio_close(struct rtgui_filerw *context) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + if (stdio_filerw) + { + close(stdio_filerw->fd); + rtgui_free(stdio_filerw); + + return 0; + } + + return -1; +} +#elif defined(RTGUI_USING_STDIO_FILERW) +#include + +/* standard file read/write */ +struct rtgui_filerw_stdio +{ + /* inherit from rtgui_filerw */ + struct rtgui_filerw parent; + + FILE* fp; +}; + +static int stdio_seek(struct rtgui_filerw *context, rt_off_t offset, int whence) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + int stdio_whence[3] = {SEEK_SET, SEEK_CUR, SEEK_END}; + + if (whence < RTGUI_FILE_SEEK_SET || whence > RTGUI_FILE_SEEK_END) + { + return -1; + } + + if (fseek(stdio_filerw->fp, offset, stdio_whence[whence]) == 0) + { + return ftell(stdio_filerw->fp); + } + + return -1; +} + +static int stdio_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum) +{ + size_t nread; + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + nread = fread(ptr, size, maxnum, stdio_filerw->fp); + if (nread == 0 && ferror(stdio_filerw->fp)) + { + return -1; + } + + return nread; +} + +static int stdio_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num) +{ + size_t nwrote; + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + nwrote = fwrite(ptr, size, num, stdio_filerw->fp); + + if ( nwrote == 0 && ferror(stdio_filerw->fp) ) + { + return -1; + } + + return nwrote; +} + +static int stdio_tell(struct rtgui_filerw* context) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + return ftell(stdio_filerw->fp); +} + +static int stdio_eof(struct rtgui_filerw* context) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + return feof(stdio_filerw->fp); +} + +static int stdio_close(struct rtgui_filerw *context) +{ + struct rtgui_filerw_stdio* stdio_filerw = (struct rtgui_filerw_stdio *)context; + + if (stdio_filerw) + { + fclose(stdio_filerw->fp); + rtgui_free(stdio_filerw); + + return 0; + } + + return -1; +} +#endif + +/* memory file read/write */ +struct rtgui_filerw_mem +{ + /* inherit from rtgui_filerw */ + struct rtgui_filerw parent; + + const rt_uint8_t *mem_base, *mem_position, *mem_end; +}; + +static int mem_seek(struct rtgui_filerw *context, rt_off_t offset, int whence) +{ + const rt_uint8_t* newpos; + struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; + + RT_ASSERT(mem != RT_NULL); + + switch (whence) { + case RTGUI_FILE_SEEK_SET: + newpos = mem->mem_base + offset; + break; + + case RTGUI_FILE_SEEK_CUR: + newpos = mem->mem_position + offset; + break; + + case RTGUI_FILE_SEEK_END: + newpos = mem->mem_end + offset; + break; + + default: + return -1; + } + + if ( newpos < mem->mem_base ) + newpos = mem->mem_base; + + if ( newpos > mem->mem_end ) + newpos = mem->mem_end; + + mem->mem_position = newpos; + return mem->mem_position- mem->mem_base; +} + +static int mem_read(struct rtgui_filerw *context, void *ptr, rt_size_t size, rt_size_t maxnum) +{ + int total_bytes; + int mem_available; + struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; + + total_bytes = (maxnum * size); + if ( (maxnum <= 0) || (size <= 0) || ((total_bytes / maxnum) != size) ) + { + return -1; + } + + mem_available = mem->mem_end - mem->mem_position; + if (total_bytes > mem_available) + total_bytes = mem_available; + + rt_memcpy(ptr, mem->mem_position, total_bytes); + mem->mem_position += total_bytes; + + return (total_bytes / size); +} + +static int mem_write(struct rtgui_filerw *context, const void *ptr, rt_size_t size, rt_size_t num) +{ +#if 0 + struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; + + if ((mem->mem_position + (num * size)) > mem->mem_end) + { + num = (mem->mem_end - mem->mem_position)/size; + } + + rt_memcpy(mem->mem_position, ptr, num*size); + mem->mem_position += num*size; + return num; #else return 0; /* not support memory write */ -#endif -} - -static int mem_tell(struct rtgui_filerw* context) -{ - struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; - - return mem->mem_position - mem->mem_base; -} - -static int mem_eof(struct rtgui_filerw* context) -{ - struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; - - return mem->mem_position >= mem->mem_end; -} - -static int mem_close(struct rtgui_filerw *context) -{ - struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; - - if (mem != RT_NULL) - { - rtgui_free(mem); - return 0; - } - - return -1; -} - -const rt_uint8_t* rtgui_filerw_mem_getdata(struct rtgui_filerw* context) -{ - struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; - - /* check whether it's a memory filerw */ - if (mem->parent.read != mem_read) return RT_NULL; - - return mem->mem_base; -} - -/* file read/write public interface */ -#ifdef RTGUI_USING_DFS_FILERW -static int parse_mode(const char *mode) -{ - int f=0; - - for (;;) - { - switch (*mode) - { - case 0: return f; - case 'b': break; - case 'r': f=O_RDONLY; break; - case 'w': f=O_WRONLY|O_CREAT|O_TRUNC; break; - case 'a': f=O_WRONLY|O_CREAT|O_APPEND; break; - case '+': f=(f&(~O_WRONLY))|O_RDWR; break; - } - - ++mode; - } -} - -struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode) -{ - int fd; - struct rtgui_filerw_stdio *rw; - - RT_ASSERT(filename != RT_NULL); - - rw = RT_NULL; - fd = open(filename, parse_mode(mode), 0); - - if ( fd >= 0 ) - { - rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio)); - if (rw != RT_NULL) - { - rw->parent.seek = stdio_seek; - rw->parent.read = stdio_read; - rw->parent.write = stdio_write; - rw->parent.tell = stdio_tell; - rw->parent.close = stdio_close; - rw->parent.eof = stdio_eof; - - rw->fd = fd; - rw->eof = RT_FALSE; - } - } - - return &(rw->parent); -} -#elif defined(RTGUI_USING_STDIO_FILERW) -struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode) -{ - FILE *fp; - struct rtgui_filerw_stdio *rw; - - RT_ASSERT(filename != RT_NULL); - - rw = RT_NULL; - fp = fopen(filename, mode); - - if ( fp != NULL ) - { - rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio)); - if (rw != RT_NULL) - { - rw->parent.seek = stdio_seek; - rw->parent.read = stdio_read; - rw->parent.write = stdio_write; - rw->parent.tell = stdio_tell; - rw->parent.close = stdio_close; - rw->parent.eof = stdio_eof; - - rw->fp = fp; - } - } - - return &(rw->parent); -} -#endif - -struct rtgui_filerw* rtgui_filerw_create_mem(const rt_uint8_t* mem, rt_size_t size) -{ - struct rtgui_filerw_mem* rw; - RT_ASSERT(mem != RT_NULL); - - rw = (struct rtgui_filerw_mem*) rtgui_malloc(sizeof(struct rtgui_filerw_mem)); - if (rw != RT_NULL) - { - rw->parent.seek = mem_seek; - rw->parent.read = mem_read; - rw->parent.write = mem_write; - rw->parent.tell = mem_tell; - rw->parent.eof = mem_eof; - rw->parent.close = mem_close; - - rw->mem_base = mem; - rw->mem_position = mem; - rw->mem_end = mem + size; - } - - return &(rw->parent); -} - -int rtgui_filerw_seek(struct rtgui_filerw* context, rt_off_t offset, int whence) -{ - RT_ASSERT(context != RT_NULL); - - return context->seek(context, offset, whence); -} - -int rtgui_filerw_read(struct rtgui_filerw* context, void* buffer, rt_size_t size, rt_size_t count) -{ - RT_ASSERT(context != RT_NULL); - - return context->read(context, buffer, size, count); -} - -int rtgui_filerw_write(struct rtgui_filerw* context, const void* buffer, rt_size_t size, rt_size_t count) -{ - RT_ASSERT(context != RT_NULL); - - return context->write(context, buffer, size, count); -} - -int rtgui_filerw_eof (struct rtgui_filerw* context) -{ - RT_ASSERT(context != RT_NULL); - - return context->eof(context); -} - -int rtgui_filerw_tell(struct rtgui_filerw* context) -{ - RT_ASSERT(context != RT_NULL); - - return context->tell(context); -} - -int rtgui_filerw_close(struct rtgui_filerw* context) -{ - int result; - - RT_ASSERT(context != RT_NULL); - - /* close context */ - result = context->close(context); - if (result != 0) - { - /* close file failed */ - return -1; - } - - return 0; -} +#endif +} + +static int mem_tell(struct rtgui_filerw* context) +{ + struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; + + return mem->mem_position - mem->mem_base; +} + +static int mem_eof(struct rtgui_filerw* context) +{ + struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; + + return mem->mem_position >= mem->mem_end; +} + +static int mem_close(struct rtgui_filerw *context) +{ + struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; + + if (mem != RT_NULL) + { + rtgui_free(mem); + return 0; + } + + return -1; +} + +const rt_uint8_t* rtgui_filerw_mem_getdata(struct rtgui_filerw* context) +{ + struct rtgui_filerw_mem* mem = (struct rtgui_filerw_mem*)context; + + /* check whether it's a memory filerw */ + if (mem->parent.read != mem_read) return RT_NULL; + + return mem->mem_base; +} + +/* file read/write public interface */ +#ifdef RTGUI_USING_DFS_FILERW +static int parse_mode(const char *mode) +{ + int f=0; + + for (;;) + { + switch (*mode) + { + case 0: return f; + case 'b': break; + case 'r': f=O_RDONLY; break; + case 'w': f=O_WRONLY|O_CREAT|O_TRUNC; break; + case 'a': f=O_WRONLY|O_CREAT|O_APPEND; break; + case '+': f=(f&(~O_WRONLY))|O_RDWR; break; + } + + ++mode; + } +} + +struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode) +{ + int fd; + struct rtgui_filerw_stdio *rw; + + RT_ASSERT(filename != RT_NULL); + + rw = RT_NULL; + fd = open(filename, parse_mode(mode), 0); + + if ( fd >= 0 ) + { + rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio)); + if (rw != RT_NULL) + { + rw->parent.seek = stdio_seek; + rw->parent.read = stdio_read; + rw->parent.write = stdio_write; + rw->parent.tell = stdio_tell; + rw->parent.close = stdio_close; + rw->parent.eof = stdio_eof; + + rw->fd = fd; + rw->eof = RT_FALSE; + } + } + + return &(rw->parent); +} +#elif defined(RTGUI_USING_STDIO_FILERW) +struct rtgui_filerw* rtgui_filerw_create_file(const char* filename, const char* mode) +{ + FILE *fp; + struct rtgui_filerw_stdio *rw; + + RT_ASSERT(filename != RT_NULL); + + rw = RT_NULL; + fp = fopen(filename, mode); + + if ( fp != NULL ) + { + rw = (struct rtgui_filerw_stdio*) rtgui_malloc(sizeof(struct rtgui_filerw_stdio)); + if (rw != RT_NULL) + { + rw->parent.seek = stdio_seek; + rw->parent.read = stdio_read; + rw->parent.write = stdio_write; + rw->parent.tell = stdio_tell; + rw->parent.close = stdio_close; + rw->parent.eof = stdio_eof; + + rw->fp = fp; + } + } + + return &(rw->parent); +} +#endif + +struct rtgui_filerw* rtgui_filerw_create_mem(const rt_uint8_t* mem, rt_size_t size) +{ + struct rtgui_filerw_mem* rw; + RT_ASSERT(mem != RT_NULL); + + rw = (struct rtgui_filerw_mem*) rtgui_malloc(sizeof(struct rtgui_filerw_mem)); + if (rw != RT_NULL) + { + rw->parent.seek = mem_seek; + rw->parent.read = mem_read; + rw->parent.write = mem_write; + rw->parent.tell = mem_tell; + rw->parent.eof = mem_eof; + rw->parent.close = mem_close; + + rw->mem_base = mem; + rw->mem_position = mem; + rw->mem_end = mem + size; + } + + return &(rw->parent); +} + +int rtgui_filerw_seek(struct rtgui_filerw* context, rt_off_t offset, int whence) +{ + RT_ASSERT(context != RT_NULL); + + return context->seek(context, offset, whence); +} + +int rtgui_filerw_read(struct rtgui_filerw* context, void* buffer, rt_size_t size, rt_size_t count) +{ + RT_ASSERT(context != RT_NULL); + + return context->read(context, buffer, size, count); +} + +int rtgui_filerw_write(struct rtgui_filerw* context, const void* buffer, rt_size_t size, rt_size_t count) +{ + RT_ASSERT(context != RT_NULL); + + return context->write(context, buffer, size, count); +} + +int rtgui_filerw_eof (struct rtgui_filerw* context) +{ + RT_ASSERT(context != RT_NULL); + + return context->eof(context); +} + +int rtgui_filerw_tell(struct rtgui_filerw* context) +{ + RT_ASSERT(context != RT_NULL); + + return context->tell(context); +} + +int rtgui_filerw_close(struct rtgui_filerw* context) +{ + int result; + + RT_ASSERT(context != RT_NULL); + + /* close context */ + result = context->close(context); + if (result != 0) + { + /* close file failed */ + return -1; + } + + return 0; +} diff --git a/components/rtgui/include/rtgui/widgets/notebook.h b/components/rtgui/include/rtgui/widgets/notebook.h index 477150c014..ea203599a9 100644 --- a/components/rtgui/include/rtgui/widgets/notebook.h +++ b/components/rtgui/include/rtgui/widgets/notebook.h @@ -2,7 +2,7 @@ #define __RTGUI_NOTEBOOK_H__ #include -#include +#include /** Gets the type of a notebook */ #define RTGUI_NOTEBOOK_TYPE (rtgui_notebook_type_get()) @@ -11,6 +11,10 @@ /** Checks if the object is a notebook control */ #define RTGUI_IS_NOTEBOOK(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_NOTEBOOK_TYPE)) +#define RTGUI_NOTEBOOK_TOP 0x00 +#define RTGUI_NOTEBOOK_BOTTOM 0x01 +#define RTGUI_NOTEBOOK_NOTAB 0x02 + struct rtgui_notebook_tab { char* title; @@ -20,7 +24,9 @@ typedef struct rtgui_notebook_tab rtgui_notebook_tab_t; struct rtgui_notebook { - struct rtgui_widget parent; + struct rtgui_container parent; + + rt_uint8_t flag; /* widget private data */ rtgui_notebook_tab_t* childs; @@ -31,7 +37,7 @@ typedef struct rtgui_notebook rtgui_notebook_t; rtgui_type_t *rtgui_notebook_type_get(void); -rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect); +rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style); void rtgui_notebook_destroy(rtgui_notebook_t* notebook); void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_widget_t* child); diff --git a/components/rtgui/include/rtgui/widgets/widget.h b/components/rtgui/include/rtgui/widgets/widget.h index dc58cac76d..93bc333237 100644 --- a/components/rtgui/include/rtgui/widgets/widget.h +++ b/components/rtgui/include/rtgui/widgets/widget.h @@ -157,6 +157,8 @@ void rtgui_widget_set_miniwidth(rtgui_widget_t* widget, int width); void rtgui_widget_set_miniheight(rtgui_widget_t* widget, int height); #endif +void rtgui_widget_set_parent(rtgui_widget_t* widget, rtgui_widget_t* parent); + /* get the physical position of a logic point on widget */ void rtgui_widget_point_to_device(rtgui_widget_t * widget, rtgui_point_t * point); /* get the physical position of a logic rect on widget */ diff --git a/components/rtgui/server/topwin.c b/components/rtgui/server/topwin.c index 171e9396a8..b1c9749d18 100644 --- a/components/rtgui/server/topwin.c +++ b/components/rtgui/server/topwin.c @@ -281,6 +281,7 @@ void rtgui_topwin_raise(struct rtgui_win* wid, rt_thread_t sender) struct rtgui_list_node* node; struct rtgui_event_clip_info eclip; RTGUI_EVENT_CLIP_INFO_INIT(&eclip); + eclip.wid = RT_NULL; /* the window is already placed in front */ if (&(topwin->list) == _rtgui_topwin_show_list.next) @@ -879,6 +880,7 @@ static void rtgui_topwin_redraw(struct rtgui_rect* rect) struct rtgui_list_node* node; struct rtgui_event_paint epaint; RTGUI_EVENT_PAINT_INIT(&epaint); + epaint.wid = RT_NULL; rtgui_list_foreach(node, &_rtgui_topwin_show_list) { diff --git a/components/rtgui/widgets/listctrl.c b/components/rtgui/widgets/listctrl.c index 360b2ad892..10087dc8d1 100644 --- a/components/rtgui/widgets/listctrl.c +++ b/components/rtgui/widgets/listctrl.c @@ -15,6 +15,8 @@ #include #include +static void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_item); + static void _rtgui_listctrl_constructor(struct rtgui_listctrl *ctrl) { /* set default widget rect and set event handler */ @@ -45,7 +47,78 @@ rtgui_type_t *rtgui_listctrl_type_get(void) return listctrl_type; } -void rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl) +static void _rtgui_listctrl_get_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect) +{ + rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect); + if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height()) + { + rect->x2 = rect->x2 - 8; + } +} + +static void _rtgui_listctrl_get_scrollbar_rect(struct rtgui_listctrl* ctrl, rtgui_rect_t* rect) +{ + rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), rect); + if (ctrl->items_count > rtgui_rect_height(*rect)/rtgui_theme_get_selected_height()) + { + rect->x1 = rect->x2 - 8; + } + else + { + /* no scrollbar */ + rt_memset(rect, 0, sizeof(rtgui_rect_t)); + } +} + +static void _rtgui_listctrl_scrollbar_ondraw(struct rtgui_listctrl* ctrl, struct rtgui_dc* dc) +{ + rtgui_rect_t rect; + rt_uint32_t height, y1; + + /* get scrollbar rect */ + _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect); + rtgui_dc_fill_rect(dc, &rect); + + height = rtgui_rect_height(rect); + + height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items); + y1 = (ctrl->current_item / ctrl->page_items) * height; + + rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height; + rtgui_theme_draw_selected(dc, &rect); +} + +static void _rtgui_listctrl_scrollbar_onmouse(struct rtgui_listctrl* ctrl, struct rtgui_event_mouse* mouse) +{ + rtgui_rect_t rect; + rt_uint32_t height, y1; + rt_uint16_t old_item; + + /* get scrollbar rect */ + _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect); + height = rtgui_rect_height(rect); + height = height / ((ctrl->items_count + (ctrl->page_items - 1))/ctrl->page_items); + y1 = (ctrl->current_item / ctrl->page_items) * height; + + rect.y1 = rect.y1 + y1; rect.y2 = rect.y1 + height; + rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect); + + old_item = ctrl->current_item; + if (mouse->y < rect.y1) + { + if (ctrl->current_item - ctrl->page_items >= 0) + ctrl->current_item -= ctrl->page_items; + rtgui_listctrl_update_current(ctrl, old_item); + } + else if (mouse->y > rect.y2) + { + if (ctrl->current_item + ctrl->page_items < ctrl->items_count - 1) + ctrl->current_item += ctrl->page_items; + rtgui_listctrl_update_current(ctrl, old_item); + } +} + +static void _rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl) { struct rtgui_rect rect, item_rect; struct rtgui_dc* dc; @@ -54,13 +127,10 @@ void rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl) dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl)); if (dc == RT_NULL) return; - rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect); + _rtgui_listctrl_get_rect(ctrl, &rect); rtgui_dc_fill_rect(dc, &rect); rect.x2 -= 1; rect.y2 -= 1; - /* draw focused border */ - // if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(ctrl))) - // rtgui_dc_draw_focus_rect(dc, &rect); /* get item base rect */ item_rect = rect; @@ -88,6 +158,9 @@ void rtgui_listctrl_ondraw(struct rtgui_listctrl* ctrl) item_rect.y1 += (rtgui_theme_get_selected_height() + 2); item_rect.y2 += (rtgui_theme_get_selected_height() + 2); } + + /* draw scrollbar */ + _rtgui_listctrl_scrollbar_ondraw(ctrl, dc); rtgui_dc_end_drawing(dc); } @@ -106,7 +179,7 @@ void rtgui_listctrl_update_current(struct rtgui_listctrl* ctrl, rt_uint16_t old_ dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(ctrl)); if (dc == RT_NULL) return; - rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect); + _rtgui_listctrl_get_rect(ctrl, &rect); rect.x2 -= 1; rect.y2 -= 1; item_rect = rect; @@ -145,7 +218,7 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui switch (event->type) { case RTGUI_EVENT_PAINT: - rtgui_listctrl_ondraw(ctrl); + _rtgui_listctrl_ondraw(ctrl); return RT_FALSE; case RTGUI_EVENT_RESIZE: @@ -166,10 +239,19 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui emouse = (struct rtgui_event_mouse*)event; + /* get scrollbar rect */ + _rtgui_listctrl_get_scrollbar_rect(ctrl, &rect); + rtgui_widget_rect_to_device(RTGUI_WIDGET(ctrl), &rect); + if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) + { + _rtgui_listctrl_scrollbar_onmouse(ctrl, emouse); + return RT_TRUE; + } + /* calculate selected item */ /* get physical extent information */ - rtgui_widget_get_rect(widget, &rect); + _rtgui_listctrl_get_rect(ctrl, &rect); rtgui_widget_rect_to_device(widget, &rect); if ((rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) && (ctrl->items_count > 0)) @@ -190,9 +272,6 @@ rt_bool_t rtgui_listctrl_event_handler(struct rtgui_widget* widget, struct rtgui rtgui_widget_get_rect(RTGUI_WIDGET(ctrl), &rect); /* update focus border */ rect.x2 -= 1; rect.y2 -= 1; - /* draw focused border */ - // if (RTGUI_WIDGET_IS_FOCUSED(RTGUI_WIDGET(ctrl))) - // rtgui_dc_draw_focus_rect(dc, &rect); rtgui_dc_end_drawing(dc); } } diff --git a/components/rtgui/widgets/notebook.c b/components/rtgui/widgets/notebook.c index 0ab8a375a2..06fc47cddb 100644 --- a/components/rtgui/widgets/notebook.c +++ b/components/rtgui/widgets/notebook.c @@ -3,11 +3,18 @@ #include #include +static void _rtgui_notebook_get_bar_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect); +static void _rtgui_notebook_get_page_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect); + static void _rtgui_notebook_constructor(rtgui_notebook_t *notebook) { + notebook->flag = 0; notebook->childs = RT_NULL; notebook->count = 0; notebook->current = RTGUI_NOT_FOUND; + + RTGUI_WIDGET(notebook)->gc.textalign = RTGUI_ALIGN_CENTER_HORIZONTAL | RTGUI_ALIGN_CENTER_VERTICAL; + rtgui_widget_set_event_handler(RTGUI_WIDGET(notebook), rtgui_notebook_event_handler); } static void _rtgui_notebook_destructor(rtgui_notebook_t *notebook) @@ -43,9 +50,21 @@ static void _rtgui_notebook_ondraw(rtgui_notebook_t *notebook) } else { + if (notebook->current == RTGUI_NOT_FOUND) + notebook->current = 0; + + _rtgui_notebook_get_bar_rect(notebook, &rect); + rtgui_dc_fill_rect(dc, &rect); + rect.x2 = rect.x1 + 80; /* draw tab bar */ for (index = 0; index < notebook->count; index ++) { + if (notebook->current == index) + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); + else + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX); + rtgui_dc_draw_text(dc, notebook->childs[index].title, &rect); + rect.x1 += 80; rect.x2 += 80; } /* draw current tab */ @@ -54,13 +73,87 @@ static void _rtgui_notebook_ondraw(rtgui_notebook_t *notebook) rtgui_dc_end_drawing(dc); } +static void _rtgui_notebook_onmouse(rtgui_notebook_t *notebook, struct rtgui_event_mouse* emouse) +{ + rtgui_rect_t rect; + + /* handle notebook bar */ + _rtgui_notebook_get_bar_rect(notebook, &rect); + rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect); + if (rtgui_rect_contains_point(&rect, emouse->x, emouse->y) == RT_EOK) + { + int index; + struct rtgui_dc* dc; + + index = (emouse->x - rect.x1) / 80; + if (index < notebook->count) + { + /* update tab bar */ + dc = rtgui_dc_begin_drawing(RTGUI_WIDGET(notebook)); + if (dc == RT_NULL) return; + + rtgui_notebook_set_current_by_index(notebook, index); + + _rtgui_notebook_get_bar_rect(notebook, &rect); + rtgui_dc_fill_rect(dc, &rect); + rect.x2 = rect.x1 + 80; + /* draw tab bar */ + for (index = 0; index < notebook->count; index ++) + { + if (notebook->current == index) + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_SUNKEN); + else + rtgui_dc_draw_border(dc, &rect, RTGUI_BORDER_BOX); + rtgui_dc_draw_text(dc, notebook->childs[index].title, &rect); + rect.x1 += 80; rect.x2 += 80; + } + + rtgui_dc_end_drawing(dc); + + return; + } + } + + /* handle on page */ + if (notebook->childs[notebook->current].widget->event_handler != RT_NULL) + notebook->childs[notebook->current].widget->event_handler(notebook->childs[notebook->current].widget, + &(emouse->parent)); +} + +static void _rtgui_notebook_get_page_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect) +{ + RT_ASSERT(notebook != RT_NULL); + RT_ASSERT(rect != RT_NULL); + + rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect); + + if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return; + else if (notebook->flag == RTGUI_NOTEBOOK_TOP) + rect->y1 = rect->y1 + 25; + else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM) + rect->y2 = rect->y2 - 25; +} + +static void _rtgui_notebook_get_bar_rect(rtgui_notebook_t *notebook, struct rtgui_rect* rect) +{ + RT_ASSERT(notebook != RT_NULL); + RT_ASSERT(rect != RT_NULL); + + rtgui_widget_get_rect(RTGUI_WIDGET(notebook), rect); + if (notebook->flag == RTGUI_NOTEBOOK_NOTAB) return; + else if (notebook->flag == RTGUI_NOTEBOOK_TOP) + rect->y2 = rect->y1 + 25; + else if (notebook->flag == RTGUI_NOTEBOOK_BOTTOM) + rect->y1 = rect->y2 - 25; +} + rtgui_type_t *rtgui_notebook_type_get(void) { static rtgui_type_t *noteboot_type = RT_NULL; if (!noteboot_type) { - noteboot_type = rtgui_type_create("notebook", RTGUI_WIDGET_TYPE, + noteboot_type = rtgui_type_create("notebook", RTGUI_CONTAINER_TYPE, sizeof(rtgui_notebook_t), RTGUI_CONSTRUCTOR(_rtgui_notebook_constructor), RTGUI_DESTRUCTOR(_rtgui_notebook_destructor)); @@ -69,16 +162,20 @@ rtgui_type_t *rtgui_notebook_type_get(void) return noteboot_type; } -rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect) +rtgui_notebook_tab_t *tabs; +struct rtgui_notebook *_notebook; +rtgui_notebook_t* rtgui_notebook_create(const rtgui_rect_t* rect, rt_uint8_t style) { struct rtgui_notebook* notebook; notebook = (struct rtgui_notebook*) rtgui_widget_create (RTGUI_NOTEBOOK_TYPE); if (notebook != RT_NULL) { + notebook->flag = style; rtgui_widget_set_rect(RTGUI_WIDGET(notebook), rect); } + _notebook = notebook; return notebook; } @@ -89,6 +186,7 @@ void rtgui_notebook_destroy(rtgui_notebook_t* notebook) void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_widget_t* child) { + rtgui_rect_t rect; RT_ASSERT(notebook != RT_NULL); notebook->count += 1; @@ -97,6 +195,15 @@ void rtgui_notebook_add(rtgui_notebook_t* notebook, const char* label, rtgui_wid notebook->childs[notebook->count - 1].title = rt_strdup(label); notebook->childs[notebook->count - 1].widget = child; + + tabs = notebook->childs; + + /* set parent */ + rtgui_widget_set_parent(child, RTGUI_WIDGET(notebook)); + + _rtgui_notebook_get_page_rect(notebook, &rect); + rtgui_widget_rect_to_device(RTGUI_WIDGET(notebook), &rect); + rtgui_widget_set_rect(child, &rect); } void rtgui_notebook_remove(rtgui_notebook_t* notebook, rt_uint16_t index) @@ -176,7 +283,7 @@ void rtgui_notebook_set_current_by_index(rtgui_notebook_t* notebook, rt_uint16_t { if (notebook->current != RTGUI_NOT_FOUND) rtgui_widget_hide(notebook->childs[notebook->current].widget); - + notebook->current = index; rtgui_widget_show(notebook->childs[notebook->current].widget); rtgui_widget_update(notebook->childs[notebook->current].widget); @@ -194,9 +301,25 @@ rtgui_widget_t* rtgui_notebook_get_index(rtgui_notebook_t* notebook, rt_uint16_t rt_bool_t rtgui_notebook_event_handler(struct rtgui_widget* widget, struct rtgui_event* event) { + struct rtgui_notebook* notebook; + + notebook = RTGUI_NOTEBOOK(widget); if (event->type == RTGUI_EVENT_PAINT) { - _rtgui_notebook_ondraw(RTGUI_NOTEBOOK(widget)); + _rtgui_notebook_ondraw(notebook); + } + else if (event->type == RTGUI_EVENT_MOUSE_BUTTON) + { + _rtgui_notebook_onmouse(notebook, (struct rtgui_event_mouse*)event); + } + else if (event->type == RTGUI_EVENT_KBD) + { + if (notebook->current != RTGUI_NOT_FOUND) + { + if (notebook->childs[notebook->current].widget->event_handler != RT_NULL) + return notebook->childs[notebook->current].widget->event_handler(notebook->childs[notebook->current].widget, + event); + } } else { diff --git a/components/rtgui/widgets/widget.c b/components/rtgui/widgets/widget.c index 7023065bfa..ecdabf5bdc 100644 --- a/components/rtgui/widgets/widget.c +++ b/components/rtgui/widgets/widget.c @@ -138,6 +138,19 @@ void rtgui_widget_set_rect(rtgui_widget_t* widget, const rtgui_rect_t* rect) } } +void rtgui_widget_set_parent(rtgui_widget_t* widget, rtgui_widget_t* parent) +{ + /* set parent and toplevel widget */ + widget->parent = parent; + + /* update children toplevel */ + if (parent->toplevel != RT_NULL && + RTGUI_IS_TOPLEVEL(parent->toplevel)) + { + widget->toplevel = rtgui_widget_get_toplevel(parent); + } +} + void rtgui_widget_get_extent(rtgui_widget_t* widget, rtgui_rect_t *rect) { RT_ASSERT(widget != RT_NULL); @@ -488,11 +501,37 @@ void rtgui_widget_show(rtgui_widget_t* widget) void rtgui_widget_hide(rtgui_widget_t* widget) { + rtgui_rect_t rect; + /* hide this widget */ RTGUI_WIDGET_HIDE(widget); - /* update the clip info of widget parent */ - rtgui_widget_update_clip(widget->parent); + if (widget->parent != RT_NULL) + { + int index; + rtgui_widget_t *parent; + rtgui_toplevel_t *toplevel; + + rect = widget->extent; + parent = widget->parent; + /* get the no transparent parent */ + while (parent != RT_NULL && parent->flag & RTGUI_WIDGET_FLAG_TRANSPARENT) + { + parent = parent->parent; + } + + /* union widget rect */ + rtgui_region_union_rect(&(widget->parent->clip), &(widget->parent->clip), &rect); + + /* handle extern rect */ + toplevel = RTGUI_TOPLEVEL(widget->toplevel); + /* subtract the external rect */ + for (index = 0; index < toplevel->external_clip_size; index ++) + { + rtgui_region_subtract_rect(&(widget->parent->clip), &(widget->parent->clip), + &(toplevel->external_clip_rect[index])); + } + } } rtgui_color_t rtgui_widget_get_parent_foreground(rtgui_widget_t* widget)