Просмотр исходного кода

update notebook control; fix rtgui_widget_hide issue.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1226 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong@gmail.com 14 лет назад
Родитель
Сommit
97cc2b9e4c

+ 460 - 460
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 <rtgui/filerw.h>
-#include <rtgui/rtgui_system.h>
-
-#ifdef RTGUI_USING_DFS_FILERW
-#include <dfs_posix.h>
-
-/* 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 <stdio.h>
-
-/* 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;
-
+/*
+ * 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 <rtgui/filerw.h>
+#include <rtgui/rtgui_system.h>
+
+#ifdef RTGUI_USING_DFS_FILERW
+#include <dfs_posix.h>
+
+/* 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 <stdio.h>
+
+/* 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;
+}

+ 9 - 3
components/rtgui/include/rtgui/widgets/notebook.h

@@ -2,7 +2,7 @@
 #define __RTGUI_NOTEBOOK_H__
 
 #include <rtgui/rtgui.h>
-#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/container.h>
 
 /** 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);

+ 2 - 0
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 */

+ 2 - 0
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)
 	{

+ 90 - 11
components/rtgui/widgets/listctrl.c

@@ -15,6 +15,8 @@
 #include <rtgui/rtgui_theme.h>
 #include <rtgui/widgets/listctrl.h>
 
+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);
 					}
 				}

+ 127 - 4
components/rtgui/widgets/notebook.c

@@ -3,11 +3,18 @@
 #include <rtgui/rtgui_system.h>
 #include <rtgui/widgets/notebook.h>
 
+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
 	{

+ 41 - 2
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)