add more UI files into radio.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@150 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
bernard.xiong 2009-11-05 23:59:01 +00:00
parent 4148f59352
commit 852f73f7a0
8 changed files with 741 additions and 0 deletions

185
bsp/stm32_radio/filelist.c Normal file
View File

@ -0,0 +1,185 @@
#include <rtgui/rtgui_object.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/list.h>
#include <rtgui/widgets/view.h>
/* image for file and folder */
rtgui_image_t *file_image, *folder_image;
static void _filelist_view_constructor(filelist_view *view)
{
/* default rect */
struct rtgui_rect rect = {0, 0, 200, 200};
/* set default widget rect and set event handler */
rtgui_widget_set_event_handler(RTGUI_WIDGET(view),filelist_view_event_handler);
rtgui_widget_set_rect(RTGUI_WIDGET(view), &rect);
RTGUI_WIDGET_BACKGROUND(RTGUI_WIDGET(list)) = RTGUI_RGB(212, 208, 200);
view->count = 0;
view->current_directory = RT_NULL;
view->pattern = RT_NULL;
rtgui_list_init(&view->list);
}
rtgui_type_t *filelist_view_type_get(void)
{
static rtgui_type_t *filelist_view_type = RT_NULL;
if (!filelist_view_type)
{
filelist_view_type = rtgui_type_create("flview", RTGUI_VIEW_TYPE,
sizeof(filelist_view_t), RTGUI_CONSTRUCTOR(_filelist_view_constructor), RT_NULL);
}
return filelist_view_type;
}
rt_bool_t filelist_view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
struct filelist_view* view = RT_NULL;
view = FILELIST_VIEW(widget);
switch (event.type)
{
case RTGUI_EVENT_PAINT:
break;
case RTGUI_EVENT_RESIZE:
{
/* recalculate page items */
}
break;
case RTGUI_EVENT_KBD:
{
struct rtgui_event_kbd* ekbd = (struct rtgui_event_kbd*)event;
if (ekbd->type == RTGUI_KEYDOWN)
{
switch (ekbd->key)
{
case RTGUIK_UP:
break;
case RTGUIK_DOWN:
break;
default:
break;
}
}
}
break;
}
/* use view event handler */
return rtgui_view_event_handler(widget, event);
}
filelist_view_t* filelist_view_create(const char* directory, const char* pattern)
{
struct filelist_view* view = RT_NULL;
view = (struct filelist_view*) rtgui_widget_create(FILELIST_VIEW_TYPE);
if (view != RT_NULL)
{
view->pattern = rt_strdup(pattern);
filelist_view_set_directory(view, directory);
}
return list;
}
void filelist_view_destroy(filelist_view_t* view)
{
/* delete all file items */
filelist_view_clear(view);
/* destroy view */
rtgui_widget_destroy(RTGUI_WIDGET(view));
}
/* clear all file items */
void filelist_view_clear(filelist_view_t* view)
{
struct rtgui_list_node* node;
struct file_item* item;
while (view->list.next != RT_NULL)
{
node = view->list.next;
rtgui_list_remove(&view->list, node);
item = rtgui_list_entry(node, struct file_item, list);
rtgui_free(item->name);
rtgui_free(item);
}
}
void filelist_view_set_directory(filelist_view_t* view, const char* directory)
{
rt_uint8_t fullpath[256];
struct file_item *item;
RT_ASSERT(view != RT_NULL);
/* clear file items firstly */
filelist_view_clear(view);
if (directory != RT_NULL)
{
DIR* dir;
dir = opendir(directory);
if (dir != RT_NULL)
{
struct dfs_dirent* dirent;
struct dfs_stat s;
do
{
dirent = readdir(dir);
if (dirent == RT_NULL) break;
if (fnmatch(dirent->d_name, view->pattern, FNM_FILE_NAME) != 0) continue;
item = (struct file_item*) rt_malloc (sizeof(struct file_item));
if (item == RT_NULL) break;
rt_memset(&s, 0, sizeof(struct dfs_stat));
/* build full path for the file */
rt_sprintf(fullpath, "%s/%s", directory, dirent->d_name);
item->name = strdup(direct->d_name);
rtgui_list_init(&item->list);
stat(fullpath, &s);
if ( s.st_mode & DFS_S_IFDIR )
{
item->type = FITEM_DIR;
item->size = 0;
}
else
{
item->type = FITEM_FILE;
item->size = s.st_size;
}
rtgui_list_append(&view->list, &item->list);
view->count ++;
} while (dirent != RT_NULL);
closedir(dir);
}
}
if (view->count > 0)
{
/* select first one */
view->selected = rtgui_list_entry(view->list.next,
struct file_item, list);
}
else view->selected = RT_NULL;
/* update view */
rtgui_widget_update(RTGUI_WIDGET(view));
}

View File

@ -0,0 +1,48 @@
#ifndef __FILE_LIST_VIEW_H__
#define __FILE_LIST_VIEW_H__
#define FITEM_FILE 0x0
#define FITEM_DIR 0x1
struct file_item
{
char* name;
rt_uint32_t type;
rt_uint32_t size;
/* files under same directory */
rtgui_list_t list;
};
/** Gets the type of a filelist view */
#define FILELIST_VIEW_TYPE (filelist_view_type_get())
/** Casts the object to a filelist */
#define FILELIST_VIEW(obj) (RTGUI_OBJECT_CAST((obj), FILELIST_VIEW_TYPE, filelist_view_t))
/** Checks if the object is a filelist view */
#define IS_FILELIST_VIEW(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), FILELIST_VIEW_TYPE))
struct filelist_view
{
struct rtgui_view parent;
/* widget private data */
/* total number of items */
rt_uint32_t count;
/* the selected item */
struct file_item* selected;
/* current directory */
rt_uint8_t* current_directory;
rt_uint8_t* pattern;
/* the number of item in a page */
rt_uint16_t page_items;
/* item_list */
rtgui_list_t item_list;
};
typedef struct filelist_view filelist_view_t;
#endif

139
bsp/stm32_radio/fnmatch.c Normal file
View File

@ -0,0 +1,139 @@
#include <ctype.h>
#include <fnmatch.h>
#include <string.h>
#define NOTFIRST 128
#define STRUCT_CHARCLASS(c) { #c , is##c }
static struct charclass {
char * class;
int (*istype)(int);
} allclasses[] = {
STRUCT_CHARCLASS(alnum),
STRUCT_CHARCLASS(alpha),
STRUCT_CHARCLASS(blank),
STRUCT_CHARCLASS(cntrl),
STRUCT_CHARCLASS(digit),
STRUCT_CHARCLASS(graph),
STRUCT_CHARCLASS(lower),
STRUCT_CHARCLASS(print),
STRUCT_CHARCLASS(punct),
STRUCT_CHARCLASS(space),
STRUCT_CHARCLASS(upper),
STRUCT_CHARCLASS(xdigit),
};
/* look for "class:]" in pattern */
static struct charclass *charclass_lookup(const char *pattern) {
unsigned int i;
for (i = 0; i< sizeof(allclasses)/sizeof(*allclasses); i++) {
int len = strlen(allclasses[i].class);
if (!strncmp(pattern, allclasses[i].class, len)) {
pattern += len;
if (strncmp(pattern, ":]", 2)) goto noclass;
return &allclasses[i];
}
}
noclass:
return NULL;
}
static int match(char c,char d,int flags) {
if (flags&FNM_CASEFOLD)
return (tolower(c)==tolower(d));
else
return (c==d);
}
int fnmatch(const char *pattern, const char *string, int flags) {
if (*string==0) {
while (*pattern=='*') ++pattern;
return (!!*pattern);
}
if (*string=='.' && *pattern!='.' && (flags&FNM_PERIOD)) {
/* don't match if FNM_PERIOD and this is the first char */
if (!(flags&NOTFIRST))
return FNM_NOMATCH;
/* don't match if FNM_PERIOD and FNM_PATHNAME and previous was '/' */
if ((flags&(FNM_PATHNAME)) && string[-1]=='/')
return FNM_NOMATCH;
}
flags|=NOTFIRST;
switch (*pattern) {
case '[':
{
int neg=0;
const char* start; /* first member of character class */
++pattern;
if (*string=='/' && flags&FNM_PATHNAME) return FNM_NOMATCH;
if (*pattern=='!') { neg=1; ++pattern; }
start=pattern;
while (*pattern) {
int res=0;
if (*pattern==']' && pattern!=start) break;
if (*pattern=='[' && pattern[1]==':') {
/* MEMBER - stupid POSIX char classes */
const struct charclass *cc;
if (!(cc = charclass_lookup(pattern+2))) goto invalidclass;
pattern += strlen(cc->class) + 4;
if (flags&FNM_CASEFOLD
&& (cc->istype == isupper || cc->istype == islower)) {
res = islower(tolower(*string));
} else {
res = ((*(cc->istype))(*string));
}
} else {
invalidclass:
if (pattern[1]=='-' && pattern[2]!=']') {
/* MEMBER - character range */
if (*string>=*pattern && *string<=pattern[2]) res=1;
if (flags&FNM_CASEFOLD) {
if (tolower(*string)>=tolower(*pattern) && tolower(*string)<=tolower(pattern[2])) res=1;
}
pattern+=3;
} else {
/* MEMBER - literal character match */
res=match(*pattern,*string,flags);
++pattern;
}
}
if ((res&&!neg) || ((neg&&!res) && *pattern==']')) {
while (*pattern && *pattern!=']') ++pattern;
return fnmatch(pattern+!!*pattern,string+1,flags);
} else if (res && neg)
return FNM_NOMATCH;
}
}
break;
case '\\':
if (flags&FNM_NOESCAPE) {
if (*string=='\\')
return fnmatch(pattern+1,string+1,flags);
} else {
if (*string==pattern[1])
return fnmatch(pattern+2,string+1,flags);
}
break;
case '*':
if ((*string=='/' && flags&FNM_PATHNAME) || fnmatch(pattern,string+1,flags))
return fnmatch(pattern+1,string,flags);
return 0;
case 0:
if (*string==0 || (*string=='/' && (flags&FNM_LEADING_DIR)))
return 0;
break;
case '?':
if (*string=='/' && flags&FNM_PATHNAME) break;
return fnmatch(pattern+1,string+1,flags);
default:
if (match(*pattern,*string,flags))
return fnmatch(pattern+1,string+1,flags);
break;
}
return FNM_NOMATCH;
}

21
bsp/stm32_radio/fnmatch.h Normal file
View File

@ -0,0 +1,21 @@
#ifndef _FNMATCH_H
#define _FNMATCH_H
#include <sys/cdefs.h>
__BEGIN_DECLS
int fnmatch(const char *pattern, const char *string, int flags) __THROW;
#define FNM_NOESCAPE 1
#define FNM_PATHNAME 2
#define FNM_FILE_NAME 2
#define FNM_PERIOD 4
#define FNM_LEADING_DIR 8
#define FNM_CASEFOLD 16
#define FNM_NOMATCH 1
__END_DECLS
#endif

77
bsp/stm32_radio/info.c Normal file
View File

@ -0,0 +1,77 @@
#include <rtgui/rtgui.h>
#include <rtgui/image.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/workbench.h>
#include "network.xpm"
static rtgui_image_t *network_image = RT_NULL;
static rtgui_image_t *usb_image = RT_NULL;
static rtgui_image_t *power_image = RT_NULL;
static rt_bool_t view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
if (event->type == RTGUI_EVENT_PAINT)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return RT_FALSE;
rtgui_widget_get_rect(widget, &rect);
rtgui_dc_fill_rect(dc, &rect);
if (network_image != RT_NULL)
{
rect.x1 = rect.x2 - (network_image->w + 2);
rtgui_image_blit(network_image, dc, &rect);
}
rtgui_dc_end_drawing(dc);
return RT_FALSE;
}
return rtgui_view_event_handler(widget, event);
}
static void info_entry(void* parameter)
{
rt_mq_t mq;
struct rtgui_view* view;
struct rtgui_workbench* workbench;
mq = rt_mq_create("qInfo", 256, 4, RT_IPC_FLAG_FIFO);
rtgui_thread_register(rt_thread_self(), mq);
network_image = rtgui_image_create_from_mem("xpm",
network_xpm, sizeof(network_xpm));
workbench = rtgui_workbench_create("info", "workbench");
if (workbench == RT_NULL) return;
view = rtgui_view_create("view");
rtgui_widget_set_event_handler(RTGUI_WIDGET(view), view_event_handler);
rtgui_workbench_add_view(workbench, view);
rtgui_view_show(view);
rtgui_workbench_event_loop(workbench);
rtgui_thread_deregister(rt_thread_self());
rt_mq_delete(mq);
}
void info_init()
{
rt_thread_t tid;
tid = rt_thread_create("info",
info_entry, RT_NULL,
2048, 25, 10);
if (tid != RT_NULL) rt_thread_startup(tid);
}

103
bsp/stm32_radio/key.c Normal file
View File

@ -0,0 +1,103 @@
#include <rtthread.h>
#include <stm32f10x.h>
#include <rtgui/event.h>
#include <rtgui/rtgui_server.h>
/*
key_enter PA0
key_down PA1
key_up PA2
key_right PC2
key_left PC3
*/
#define key_enter_GETVALUE() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_0)
#define key_down_GETVALUE() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_1)
#define key_up_GETVALUE() GPIO_ReadInputDataBit(GPIOA,GPIO_Pin_2)
#define key_right_GETVALUE() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_2)
#define key_left_GETVALUE() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_3)
static void key_thread_entry(void *parameter)
{
rt_time_t next_delay;
struct rtgui_event_kbd kbd_event;
GPIO_InitTypeDef GPIO_InitStructure;
/* init gpio configuration */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOC,ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2;
GPIO_Init(GPIOA,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 | GPIO_Pin_3;
GPIO_Init(GPIOC,&GPIO_InitStructure);
/* init keyboard event */
RTGUI_EVENT_KBD_INIT(&kbd_event);
kbd_event.mod = RTGUI_KMOD_NONE;
kbd_event.unicode = 0;
while (1)
{
next_delay = 20;
kbd_event.type = RTGUI_KEYDOWN;
if ( key_enter_GETVALUE() == 0 )
{
rt_thread_delay(next_delay);
if (key_enter_GETVALUE() == 0)
{
/* HOME key */
rt_kprintf("key_home\n");
kbd_event.key = RTGUIK_HOME;
}
else
{
rt_kprintf("key_enter\n");
kbd_event.key = RTGUIK_RETURN;
}
}
if ( key_down_GETVALUE() == 0 )
{
rt_kprintf("key_down\n");
kbd_event.key = RTGUIK_DOWN;
}
if ( key_up_GETVALUE() == 0 )
{
rt_kprintf("key_up\n");
kbd_event.key = RTGUIK_UP;
}
if ( key_right_GETVALUE() == 0 )
{
rt_kprintf("key_right\n");
kbd_event.key = RTGUIK_RIGHT;
}
if ( key_left_GETVALUE() == 0 )
{
rt_kprintf("key_left\n");
kbd_event.key = RTGUIK_LEFT;
}
/* post down event */
rtgui_server_post_event(&(kbd_event.parent), sizeof(kbd_event));
/* wait next key press */
rt_thread_delay(next_delay);
/* post up event */
kbd_event.type = RTGUI_KEYUP;
rtgui_server_post_event(&(kbd_event.parent), sizeof(kbd_event));
}
}
void rt_hw_key_init()
{
rt_thread_t key_tid;
key_tid = rt_thread_create("key",
key_thread_entry, RT_NULL,
512, 30, 5);
if (key_tid != RT_NULL) rt_thread_startup(key_tid);
}

73
bsp/stm32_radio/today.c Normal file
View File

@ -0,0 +1,73 @@
#include <rtgui/rtgui.h>
#include <rtgui/image.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/workbench.h>
static rtgui_image_t *background = RT_NULL;
static rt_bool_t view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
if (event->type == RTGUI_EVENT_PAINT)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return RT_FALSE;
rtgui_widget_get_rect(widget, &rect);
rtgui_dc_fill_rect(dc, &rect);
if (background != RT_NULL)
rtgui_image_blit(background, dc, &rect);
rtgui_dc_draw_text(dc, "Radio Today", &rect);
rtgui_dc_end_drawing(dc);
return RT_FALSE;
}
return rtgui_view_event_handler(widget, event);
}
static void today_entry(void* parameter)
{
rt_mq_t mq;
struct rtgui_view* view;
struct rtgui_workbench* workbench;
mq = rt_mq_create("qToday", 256, 4, RT_IPC_FLAG_FIFO);
rtgui_thread_register(rt_thread_self(), mq);
/* create background image */
background = rtgui_image_create_from_file("png",
"/bg.png", RT_FALSE);
workbench = rtgui_workbench_create("main", "workbench");
if (workbench == RT_NULL) return;
view = rtgui_view_create("Today");
rtgui_widget_set_event_handler(RTGUI_WIDGET(view), view_event_handler);
rtgui_workbench_add_view(workbench, view);
rtgui_view_show(view);
rtgui_workbench_event_loop(workbench);
rtgui_thread_deregister(rt_thread_self());
rt_mq_delete(mq);
}
void today_init()
{
rt_thread_t tid;
tid = rt_thread_create("today",
today_entry, RT_NULL,
2048, 25, 10);
if (tid != RT_NULL) rt_thread_startup(tid);
}

View File

@ -0,0 +1,95 @@
#include <rtgui/rtgui.h>
#include <rtgui/rtgui_system.h>
#include <rtgui/widgets/view.h>
#include <rtgui/widgets/workbench.h>
static rt_bool_t view_event_handler(struct rtgui_widget* widget, struct rtgui_event* event)
{
/* 我们目前只对绘制事件感兴趣 */
if (event->type == RTGUI_EVENT_PAINT)
{
struct rtgui_dc* dc;
struct rtgui_rect rect;
/* 获得一个设备上下文 */
dc = rtgui_dc_begin_drawing(widget);
if (dc == RT_NULL) return RT_FALSE; /* 如果获取失败代表什么?这个控件是隐藏的或... */
rtgui_widget_get_rect(widget, &rect); /* 获得控件的可视区域 */
/* 先对所在可视区域全部填充为背景色 */
rtgui_dc_fill_rect(dc, &rect);
/* 绘制一个hello! */
rtgui_dc_draw_text(dc, "hello world", &rect);
/* 通知RTGUI绘制结束 */
rtgui_dc_end_drawing(dc);
return RT_FALSE;
}
/* 如果不是绘制事件使用view原来的事件处理函数处理 */
return rtgui_view_event_handler(widget, event);
}
static void workbench_entry(void* parameter)
{
rt_mq_t mq;
struct rtgui_view* view;
struct rtgui_workbench* workbench;
/* 创建GUI应用需要的消息队列 */
mq = rt_mq_create("qWB", 256, 4, RT_IPC_FLAG_FIFO);
/* 注册当前线程为GUI线程 */
rtgui_thread_register(rt_thread_self(), mq);
/* 创建一个工作台 */
workbench = rtgui_workbench_create("main", "workbench");
if (workbench == RT_NULL) return;
/* 创建一个工作台上的一个视图 */
view = rtgui_view_create("view");
rtgui_widget_set_event_handler(RTGUI_WIDGET(view), view_event_handler);
/* 在工作台上添加一个视图 */
rtgui_workbench_add_view(workbench, view);
/* 显示这个视图 */
rtgui_view_show(view);
/* 执行工作台事件循环 */
rtgui_workbench_event_loop(workbench);
/* 去注册GUI线程 */
rtgui_thread_deregister(rt_thread_self());
rt_mq_delete(mq);
}
void workbench_init()
{
static rt_bool_t inited = RT_FALSE;
if (inited == RT_FALSE) /* 避免重复初始化而做的保护 */
{
rt_thread_t tid;
tid = rt_thread_create("wb",
workbench_entry, RT_NULL,
2048, 25, 10);
if (tid != RT_NULL) rt_thread_startup(tid);
inited = RT_TRUE;
}
}
#ifdef RT_USING_RTGUI
#include <finsh.h>
void workbench()
{
workbench_init();
}
/* finsh的命令输出可以直接执行workbench()函数以执行上面的函数 */
FINSH_FUNCTION_EXPORT(workbench, workbench demo)
#endif