mirror of
https://gitee.com/zlgopen/awtk.git
synced 2024-11-29 18:48:09 +08:00
1.add api doc. 2.add lua generator
This commit is contained in:
parent
95e9f2f070
commit
0d420c9665
BIN
.sconsign.dblite
BIN
.sconsign.dblite
Binary file not shown.
@ -28,7 +28,8 @@ os.environ['LFTK_ROOT'] = LFTK_ROOT;
|
||||
os.environ['GTEST_ROOT'] = GTEST_ROOT;
|
||||
|
||||
DefaultEnvironment(CCFLAGS = OS_FLAGS + ' -DLFTK_ROOT=\\\"'+LFTK_ROOT+'\\\"',
|
||||
CPPPATH = [LFTK_SRC, LFTK_3RD_ROOT, LFTK_TOOLS_ROOT] + OS_CPPPATH,
|
||||
CPPPATH = [LFTK_ROOT, LFTK_SRC, LFTK_3RD_ROOT, LFTK_TOOLS_ROOT,
|
||||
] + OS_CPPPATH,
|
||||
LIBS=['lftk_base', 'platform'] + OS_LIBS,
|
||||
LINKFLAGS=OS_LINKFLAGS,
|
||||
OS_SUBSYSTEM_CONSOLE=OS_SUBSYSTEM_CONSOLE,
|
||||
@ -44,6 +45,7 @@ DefaultEnvironment(CCFLAGS = OS_FLAGS + ' -DLFTK_ROOT=\\\"'+LFTK_ROOT+'\\\"',
|
||||
os.path.join(LFTK_ROOT, 'src/image_loader'),
|
||||
os.path.join(LFTK_ROOT, 'tools/common'),
|
||||
os.path.join(LFTK_ROOT, 'tools/font_gen'),
|
||||
os.path.join(LFTK_ROOT, 'demos'),
|
||||
os.path.join(LFTK_ROOT, 'tools/image_gen'),
|
||||
os.path.join(LFTK_ROOT, 'tools/theme_gen')] + OS_LIBPATH)
|
||||
|
||||
@ -61,5 +63,6 @@ SConscript([
|
||||
'tools/theme_gen/SConscript',
|
||||
'tools/font_gen/SConscript',
|
||||
'tools/image_gen/SConscript',
|
||||
'lua/SConscript',
|
||||
'tests/SConscript'])
|
||||
'tests/SConscript',
|
||||
'lua/SConscript'
|
||||
])
|
||||
|
@ -1,9 +1,12 @@
|
||||
import os
|
||||
|
||||
env=DefaultEnvironment().Clone();
|
||||
env['LIBS'] = ['sdl_main_loop', 'sdl_lcd', 'SDL2', 'fontbitmap', 'imageloaderbitmap'] + env['LIBS']
|
||||
|
||||
env.Library('resource', ['resource.c']);
|
||||
|
||||
env['LIBS'] = ['resource', 'sdl_main_loop', 'sdl_lcd', 'SDL2', 'fontbitmap', 'imageloaderbitmap'] + env['LIBS']
|
||||
env['LINKFLAGS'] = env['OS_SUBSYSTEM_WINDOWS'] + env['LINKFLAGS'];
|
||||
env.Program('demo1', ['demo1_main.c', 'demo1_app.c', 'resource.c']);
|
||||
env.Program('demo1', ['demo1_main.c', 'demo1_app.c']);
|
||||
|
||||
|
||||
|
||||
|
@ -159,13 +159,13 @@ ret_t application_init() {
|
||||
check_button = check_button_create(win, 100, 150, 80, 30);
|
||||
widget_set_text(check_button, L"Food");
|
||||
|
||||
radio_button = radio_button_create(win, 10, 200, 80, 30);
|
||||
radio_button = check_button_create_radio(win, 10, 200, 80, 30);
|
||||
widget_set_text(radio_button, L"Book");
|
||||
|
||||
radio_button = radio_button_create(win, 100, 200, 80, 30);
|
||||
radio_button = check_button_create_radio(win, 100, 200, 80, 30);
|
||||
widget_set_text(radio_button, L"Food");
|
||||
|
||||
radio_button = radio_button_create(win, 190, 200, 80, 30);
|
||||
radio_button = check_button_create_radio(win, 190, 200, 80, 30);
|
||||
widget_set_text(radio_button, L"Pencil");
|
||||
widget_set_value(radio_button, TRUE);
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "resource.h"
|
||||
#include "base/platform.h"
|
||||
#include "base/lftk.h"
|
||||
|
||||
ret_t application_init(void);
|
||||
|
||||
@ -59,25 +59,12 @@ int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline
|
||||
int main(void) {
|
||||
#endif
|
||||
|
||||
platform_prepare();
|
||||
mem_init(s_heap_mem, sizeof(s_heap_mem));
|
||||
lftk_init(320, 480, s_heap_mem, sizeof(s_heap_mem));
|
||||
|
||||
resource_init();
|
||||
application_init();
|
||||
|
||||
#ifdef WITH_STM32F103ZE_RAW
|
||||
main_loop_stm32_raw_init(320, 480);
|
||||
#elif defined(WITH_RT_THREAD)
|
||||
main_loop_rtthread_init(320, 480);
|
||||
#else
|
||||
main_loop_sdl2_init(320, 480);
|
||||
#endif
|
||||
|
||||
application_init();
|
||||
|
||||
main_loop_run(default_main_loop());
|
||||
|
||||
main_loop_destroy(default_main_loop());
|
||||
lftk_run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2,9 +2,9 @@ const unsigned char theme_data[] = {
|
||||
0xfd,0xfc,0xfb,0xfa,0x00,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x02,0x00,0x6c,0x00,0x00,0x00,
|
||||
0x01,0x00,0x04,0x00,0x95,0x00,0x00,0x00,0x01,0x00,0x07,0x00,0xce,0x00,0x00,0x00,0x02,0x00,0x07,0x00,
|
||||
0xee,0x00,0x00,0x00,0x03,0x00,0x07,0x00,0x0e,0x01,0x00,0x00,0x04,0x00,0x07,0x00,0x2e,0x01,0x00,0x00,
|
||||
0x01,0x00,0x06,0x00,0x4e,0x01,0x00,0x00,0x01,0x00,0x0a,0x00,0x6e,0x01,0x00,0x00,0x07,0x00,0x0c,0x00,
|
||||
0x96,0x01,0x00,0x00,0x08,0x00,0x0c,0x00,0xba,0x01,0x00,0x00,0x07,0x00,0x0d,0x00,0xe0,0x01,0x00,0x00,
|
||||
0x08,0x00,0x0d,0x00,0x0a,0x02,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xf0,0xf0,0xf0,0xff,
|
||||
0x01,0x00,0x06,0x00,0x4e,0x01,0x00,0x00,0x01,0x00,0x0a,0x00,0x6e,0x01,0x00,0x00,0x06,0x00,0x0c,0x00,
|
||||
0x96,0x01,0x00,0x00,0x07,0x00,0x0c,0x00,0xba,0x01,0x00,0x00,0x06,0x00,0x0d,0x00,0xe0,0x01,0x00,0x00,
|
||||
0x07,0x00,0x0d,0x00,0x0a,0x02,0x00,0x00,0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xf0,0xf0,0xf0,0xff,
|
||||
0x06,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x04,0x00,0x00,0x00,0x0c,0x00,0x00,0x00,0x01,0x00,0x00,0x00,
|
||||
0x03,0x00,0x00,0x00,0x73,0x61,0x6e,0x73,0x00,0x05,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0xf0,0xf0,0xf0,
|
||||
0xff,0x02,0x00,0x00,0x00,0x80,0x80,0x80,0xff,0x09,0x00,0x00,0x00,0x80,0x80,0x80,0xff,0x06,0x00,0x00,
|
||||
|
@ -35,7 +35,7 @@
|
||||
#include "image_loader/image_loader_bitmap.h"
|
||||
|
||||
ret_t resource_init() {
|
||||
default_theme_init(theme_data);
|
||||
theme_init(theme_data);
|
||||
image_loader_t* bitmap_loader = image_loader_bitmap_create(10);
|
||||
font_manager_add(default_fm(), font_bitmap_create(font_font20));
|
||||
|
||||
|
@ -3,10 +3,8 @@ import sys
|
||||
|
||||
env=DefaultEnvironment().Clone()
|
||||
|
||||
env['LIBS'] = ['lua'] + env['LIBS']
|
||||
env.Library('lftk_lua', ['lftk_lua.c'])
|
||||
env.Program('lftk_run', ["lftk_run.c", 'lftk_lua.c'])
|
||||
env.Program('demo1', ["demo1.c"])
|
||||
env['LIBS'] = ['resource', 'sdl_main_loop', 'sdl_lcd', 'SDL2', 'fontbitmap', 'imageloaderbitmap', 'lua'] + env['LIBS']
|
||||
env.Program('run_lua', ["run_lua.c", 'lftk_lua.c'])
|
||||
|
||||
|
||||
|
||||
|
32
lua/button.lua
Normal file
32
lua/button.lua
Normal file
@ -0,0 +1,32 @@
|
||||
function on_click(ctx, evt)
|
||||
print('on_click');
|
||||
end
|
||||
|
||||
function application_init()
|
||||
local win = Window.create(NULL, 0, 0, 0, 0);
|
||||
ok = Button.create(win, 10, 5, 80, 30);
|
||||
ok:set_text(to_wstr("ok"));
|
||||
|
||||
print(ok, getmetatable(ok));
|
||||
label = Label.create(win, 100, 5, 80, 30);
|
||||
label:set_text(to_wstr("text"));
|
||||
print(ok, getmetatable(ok));
|
||||
print(label, getmetatable(label));
|
||||
|
||||
rid = ok:on(EventType.EVT_CLICK, function(evt)
|
||||
print(ok, getmetatable(ok));
|
||||
print(evt, getmetatable(evt));
|
||||
local e = PointerEvent.cast(evt);
|
||||
print(ok, getmetatable(ok));
|
||||
print(e, getmetatable(e));
|
||||
print("on click:" .. tostring(e.x) .. " " .. tostring(e.y))
|
||||
-- ok:off(rid)
|
||||
return Ret.OK;
|
||||
end);
|
||||
|
||||
print(tostring(rid))
|
||||
end
|
||||
|
||||
application_init()
|
||||
|
||||
|
92
lua/custom.c
Normal file
92
lua/custom.c
Normal file
@ -0,0 +1,92 @@
|
||||
|
||||
static lua_State* s_current_L = NULL;
|
||||
extern void luaL_openlib (lua_State *L, const char *libname, const luaL_Reg *l, int nup);
|
||||
|
||||
static const luaL_Reg* find_member(const luaL_Reg* funcs, const char* name) {
|
||||
const luaL_Reg* iter = funcs;
|
||||
|
||||
while(iter->name) {
|
||||
if(strcmp(iter->name, name) == 0) {
|
||||
return iter;
|
||||
}
|
||||
iter++;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* lftk_checkudata(lua_State* L, int idx, const char* name) {
|
||||
(void)name;
|
||||
return lua_touserdata(L, idx);
|
||||
}
|
||||
|
||||
static ret_t call_on_event(void* ctx, event_t* e) {
|
||||
lua_State* L = (lua_State*)s_current_L;
|
||||
int func_id = (char*)ctx - (char*)NULL;
|
||||
|
||||
lua_settop(L, 0);
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, func_id);
|
||||
lua_pushlightuserdata(L, e);
|
||||
|
||||
lua_pcall(L,1,1,0);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static int wrap_widget_on(lua_State* L) {
|
||||
ret_t ret = 0;
|
||||
widget_t* widget = (widget_t*)lftk_checkudata(L, 1, "lftk.widget_t");
|
||||
event_type_t type = (event_type_t)luaL_checkinteger(L, 2);
|
||||
|
||||
if(lua_isfunction(L, 3)) {
|
||||
int func_id = 0;
|
||||
lua_pushvalue(L, 3);
|
||||
func_id = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
ret = (ret_t)widget_on(widget, type, call_on_event, (char*)NULL + func_id);
|
||||
lua_pushnumber(L,(lua_Number)ret);
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int wrap_widget_off(lua_State* L) {
|
||||
ret_t ret = 0;
|
||||
printf("top=%d\n", lua_gettop(L));
|
||||
widget_t* widget = (widget_t*)lftk_checkudata(L, 1, "lftk.widget_t");
|
||||
uint32_t id = (uint32_t)luaL_checkinteger(L, 2);
|
||||
emitter_item_t* item = emitter_find(widget->emitter, id);
|
||||
printf("%s id=%d\n", __func__, id);
|
||||
if(item) {
|
||||
uint32_t func_id = (char*)(item->ctx) - (char*)NULL;
|
||||
luaL_unref(L, LUA_REGISTRYINDEX, func_id);
|
||||
ret = (ret_t)widget_off(widget, id);
|
||||
}
|
||||
|
||||
lua_pushnumber(L,(lua_Number)(ret));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int to_wstr(lua_State* L) {
|
||||
const char* str = (const char*)luaL_checkstring(L, 1);
|
||||
uint32_t size = (strlen(str) + 1) * sizeof(wchar_t);
|
||||
wchar_t* p = (wchar_t*)lua_newuserdata(L, size);
|
||||
|
||||
utf8_to_utf16(str, p, size);
|
||||
lua_pushlightuserdata(L, p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int to_str(lua_State* L) {
|
||||
const wchar_t* str = (const wchar_t*)lua_touserdata(L, 1);
|
||||
uint32_t size = (wcslen(str) + 1) * 3;
|
||||
char* p = (char*)lua_newuserdata(L, size);
|
||||
|
||||
utf8_from_utf16(str, p, size);
|
||||
lua_pushstring(L, p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
99
lua/demo1.c
99
lua/demo1.c
@ -1,99 +0,0 @@
|
||||
#define LUA_COMPAT_MODULE
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
|
||||
typedef struct _NumArray {
|
||||
int size;
|
||||
int values[1];
|
||||
} NumArray;
|
||||
|
||||
static NumArray *checkarray (lua_State *L) {
|
||||
void *ud = luaL_checkudata(L, 1, "lftk.array");
|
||||
luaL_argcheck(L, ud != NULL, 1, "`array' expected");
|
||||
return (NumArray *)ud;
|
||||
}
|
||||
|
||||
static int newarray(lua_State* L) {
|
||||
int n = luaL_checkint(L, 1);
|
||||
size_t nbytes = sizeof(NumArray) + (n - 1) * sizeof(double);
|
||||
NumArray* a = (NumArray*)calloc(1, nbytes);
|
||||
|
||||
lua_pushlightuserdata(L, (void*)a);
|
||||
luaL_getmetatable(L, "lftk.array");
|
||||
lua_setmetatable(L, -2);
|
||||
|
||||
a->size = n;
|
||||
|
||||
return 1; /* new userdatum is already on the stack */
|
||||
}
|
||||
|
||||
static int setarray(lua_State* L) {
|
||||
NumArray* a = checkarray(L);
|
||||
|
||||
int index = luaL_checkint(L, 2);
|
||||
double value = luaL_checknumber(L, 3);
|
||||
luaL_argcheck(L, a != NULL, 1, "`array' expected");
|
||||
luaL_argcheck(L, 1 <= index && index <= a->size, 2, "index out of range");
|
||||
|
||||
a->values[index - 1] = value;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int getarray(lua_State* L) {
|
||||
NumArray* a = checkarray(L);
|
||||
|
||||
int index = luaL_checkint(L, 2);
|
||||
luaL_argcheck(L, a != NULL, 1, "'array' expected");
|
||||
luaL_argcheck(L, 1 <= index && index <= a->size, 2, "index out of range");
|
||||
|
||||
lua_pushnumber(L, a->values[index - 1]);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int getsize(lua_State* L) {
|
||||
NumArray* a = checkarray(L);
|
||||
luaL_argcheck(L, a != NULL, 1, "`array' expected");
|
||||
|
||||
lua_pushnumber(L, a->size);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const struct luaL_Reg arraylib_f[] = {{"new", newarray}, {NULL, NULL}};
|
||||
|
||||
static const struct luaL_Reg arraylib_m[] = {
|
||||
{"set", setarray}, {"get", getarray}, {"size", getsize}, {NULL, NULL}};
|
||||
|
||||
int luaopen_array(lua_State* L) {
|
||||
luaL_newmetatable(L, "lftk.array");
|
||||
lua_pushstring(L, "__index");
|
||||
lua_pushvalue(L, -2); /* pushes the metatable */
|
||||
lua_settable(L, -3); /* metatable.__index = metatable */
|
||||
|
||||
luaL_openlib(L, NULL, arraylib_m, 0);
|
||||
luaL_openlib(L, "array", arraylib_f, 0);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void) {
|
||||
lua_State* L = luaL_newstate(); // 创建Lua状态机。
|
||||
luaL_openlibs(L); // 打开Lua状态机"L"中的所有Lua标准库。
|
||||
luaopen_array(L);
|
||||
|
||||
if(luaL_dofile(L, "./demo1.lua")) {
|
||||
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
lua_close(L); // 关闭Lua状态机。
|
||||
|
||||
return 0;
|
||||
}
|
@ -1,10 +0,0 @@
|
||||
print("hello")
|
||||
|
||||
a = array.new(1000)
|
||||
|
||||
print(a:size()) --> 1000
|
||||
|
||||
a:set(10, 3.4)
|
||||
|
||||
print(a:get(10)) --> 3.4
|
||||
|
2597
lua/lftk_lua.c
2597
lua/lftk_lua.c
File diff suppressed because it is too large
Load Diff
@ -1,26 +0,0 @@
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#include "base/mem.h"
|
||||
|
||||
extern void luaL_openlftk(lua_State* L);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
lua_State* L = luaL_newstate();
|
||||
static uint32_t s_mem_heap[10 * 1024];
|
||||
const char* lua_file = argc == 2 ? argv[1] : "./demo.lua";
|
||||
|
||||
luaL_openlibs(L);
|
||||
luaL_openlftk(L);
|
||||
|
||||
mem_init(s_mem_heap, sizeof(s_mem_heap));
|
||||
|
||||
if(luaL_dofile(L, lua_file)) {
|
||||
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
lua_close(L);
|
||||
|
||||
return 0;
|
||||
}
|
30
lua/run_lua.c
Normal file
30
lua/run_lua.c
Normal file
@ -0,0 +1,30 @@
|
||||
#include <lua.h>
|
||||
#include <lauxlib.h>
|
||||
#include <lualib.h>
|
||||
#include "base/lftk.h"
|
||||
#include "demos/resource.h"
|
||||
|
||||
extern void luaL_openlftk(lua_State* L);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
lua_State* L = luaL_newstate();
|
||||
static uint32_t s_heap_mem[10 * 1024];
|
||||
const char* lua_file = argc == 2 ? argv[1] : "./demo.lua";
|
||||
|
||||
luaL_openlibs(L);
|
||||
luaL_openlftk(L);
|
||||
|
||||
lftk_init(320, 480, s_heap_mem, sizeof(s_heap_mem));
|
||||
resource_init();
|
||||
|
||||
if (luaL_dofile(L, lua_file)) {
|
||||
fprintf(stderr, "%s\n", lua_tostring(L, -1));
|
||||
lua_pop(L, 1);
|
||||
} else {
|
||||
lftk_run();
|
||||
}
|
||||
|
||||
lua_close(L);
|
||||
|
||||
return 0;
|
||||
}
|
4
lua/str.lua
Normal file
4
lua/str.lua
Normal file
@ -0,0 +1,4 @@
|
||||
|
||||
local wstr = to_wstr("hello")
|
||||
local str = to_str(wstr)
|
||||
print(str);
|
24
lua/test.lua
Normal file
24
lua/test.lua
Normal file
@ -0,0 +1,24 @@
|
||||
function on_click(ctx, evt)
|
||||
print('on_click');
|
||||
end
|
||||
|
||||
function application_init()
|
||||
local win = Window.create(NULL, 0, 0, 0, 0);
|
||||
ok = Button.create(win, 10, 5, 80, 30);
|
||||
ok:set_text(to_wstr("ok"));
|
||||
|
||||
print(ok, getmetatable(ok));
|
||||
label = Label.create(win, 100, 5, 80, 30);
|
||||
label:set_text(to_wstr("text"));
|
||||
print(ok, getmetatable(ok));
|
||||
print(label, getmetatable(label));
|
||||
p = ProgressBar.create(win, 200, 5, 80, 30);
|
||||
print(ok, getmetatable(ok));
|
||||
print(label, getmetatable(label));
|
||||
print(p, getmetatable(p));
|
||||
|
||||
end
|
||||
|
||||
application_init()
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
|
||||
local v = value_t.create()
|
||||
local v = Value.create()
|
||||
local a = 100;
|
||||
|
||||
v:set_int8(100);
|
||||
@ -12,10 +12,13 @@ v:set_bool(true)
|
||||
v:set_bool()
|
||||
print(v:bool());
|
||||
|
||||
v:_set("test", 123);
|
||||
print(v:_get("test"));
|
||||
|
||||
print("VALUE_TYPE_INVALID=" .. VALUE_TYPE_INVALID);
|
||||
print("VALUE_TYPE_STRING=" .. VALUE_TYPE_STRING);
|
||||
print(v.type);
|
||||
print(ValueType)
|
||||
print(ValueType.INVALID);
|
||||
print(ValueType.BOOL);
|
||||
print(ValueType.FLOAT);
|
||||
|
||||
v:destroy();
|
||||
|
||||
lftk_quit();
|
||||
|
||||
|
20
lua/window.lua
Normal file
20
lua/window.lua
Normal file
@ -0,0 +1,20 @@
|
||||
function on_click(ctx, evt)
|
||||
print('on_click');
|
||||
end
|
||||
|
||||
function application_init()
|
||||
local win = Window.create(NULL, 0, 0, 0, 0);
|
||||
local ok = Button.create(win, 10, 5, 80, 30);
|
||||
ok:set_text(to_wstr("ok"));
|
||||
|
||||
rid = ok:on(EventType.EVT_CLICK, function(evt)
|
||||
print("on click:" .. tostring(rid))
|
||||
ok:off(rid)
|
||||
end);
|
||||
|
||||
print(tostring(rid))
|
||||
end
|
||||
|
||||
application_init()
|
||||
|
||||
|
@ -30,16 +30,16 @@ static ret_t button_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
button_t* button = BUTTON(widget);
|
||||
color_t color = color_init(0xff, 0xff, 0xff, 0xff);
|
||||
|
||||
canvas_set_fill_color(c, style_get_color(style, E_BG_COLOR, color));
|
||||
canvas_set_text_color(c, style_get_color(style, E_TEXT_COLOR, color));
|
||||
canvas_set_stroke_color(c, style_get_color(style, E_BORDER_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_BG_COLOR, color));
|
||||
canvas_set_text_color(c, style_get_color(style, STYLE_ID_TEXT_COLOR, color));
|
||||
canvas_set_stroke_color(c, style_get_color(style, STYLE_ID_BORDER_COLOR, color));
|
||||
|
||||
canvas_fill_rect(c, 0, 0, widget->w, widget->h);
|
||||
canvas_stroke_rect(c, 0, 0, widget->w, widget->h);
|
||||
|
||||
if (button->text.size > 0) {
|
||||
const char* font_name = style_get_str(style, E_FONT_NAME, NULL);
|
||||
uint16_t font_size = style_get_int(style, E_FONT_SIZE, 20);
|
||||
const char* font_name = style_get_str(style, STYLE_ID_FONT_NAME, NULL);
|
||||
uint16_t font_size = style_get_int(style, STYLE_ID_FONT_SIZE, 20);
|
||||
|
||||
canvas_set_font(c, font_name, font_size);
|
||||
w = canvas_measure_text(c, button->text.str, button->text.size);
|
||||
@ -89,9 +89,11 @@ static ret_t button_on_event(widget_t* widget, event_t* e) {
|
||||
widget_set_state(widget, WIDGET_STATE_PRESSED);
|
||||
break;
|
||||
case EVT_POINTER_UP: {
|
||||
event_t click_e = {EVT_CLICK, widget};
|
||||
pointer_event_t evt = *(pointer_event_t*)e;
|
||||
evt.e.type = EVT_CLICK;
|
||||
evt.e.target = widget;
|
||||
widget_set_state(widget, WIDGET_STATE_OVER);
|
||||
widget_dispatch(widget, &click_e);
|
||||
widget_dispatch(widget, (event_t*)&evt);
|
||||
break;
|
||||
}
|
||||
case EVT_POINTER_LEAVE:
|
||||
|
@ -27,13 +27,39 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class button_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 按钮控件。
|
||||
*/
|
||||
typedef struct _button_t {
|
||||
widget_t widget;
|
||||
wstr_t text;
|
||||
}button_t;
|
||||
|
||||
/**
|
||||
* @method button_create
|
||||
* @constructor
|
||||
* 创建button对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method button_set_text
|
||||
* 设置控件的文本。
|
||||
* @param {widget_t*} widget button对象。
|
||||
* @param {wchar_t*} text 文本。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t button_set_text(widget_t* widget, const wchar_t* text);
|
||||
|
||||
#define BUTTON(widget) ((button_t*)(widget))
|
||||
|
@ -57,12 +57,12 @@ static ret_t check_button_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
color_t color = color_init(0xff, 0xff, 0xff, 0xff);
|
||||
return_value_if_fail(widget != NULL && c != NULL, RET_BAD_PARAMS);
|
||||
|
||||
icon_name = style_get_str(style, E_ICON, NULL);
|
||||
icon_name = style_get_str(style, STYLE_ID_ICON, NULL);
|
||||
return_value_if_fail(icon_name != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(image_manager_load(default_im(), icon_name, &bitmap) == RET_OK, RET_FAIL);
|
||||
|
||||
canvas_set_text_color(c, style_get_color(style, E_TEXT_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, E_BG_COLOR, color));
|
||||
canvas_set_text_color(c, style_get_color(style, STYLE_ID_TEXT_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_BG_COLOR, color));
|
||||
|
||||
if (bitmap.data != NULL) {
|
||||
rect_t src;
|
||||
@ -77,8 +77,8 @@ static ret_t check_button_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
|
||||
x += widget->h;
|
||||
if (check_button->text.size > 0) {
|
||||
const char* font_name = style_get_str(style, E_FONT_NAME, NULL);
|
||||
uint16_t font_size = style_get_int(style, E_FONT_SIZE, 20);
|
||||
const char* font_name = style_get_str(style, STYLE_ID_FONT_NAME, NULL);
|
||||
uint16_t font_size = style_get_int(style, STYLE_ID_FONT_SIZE, 20);
|
||||
|
||||
canvas_set_font(c, font_name, font_size);
|
||||
y = (widget->h >> 1);
|
||||
@ -178,7 +178,7 @@ widget_t* check_button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h)
|
||||
return widget;
|
||||
}
|
||||
|
||||
widget_t* radio_button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
widget_t* check_button_create_radio(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h) {
|
||||
widget_t* widget = check_button_create(parent, x, y, w, h);
|
||||
check_button_t* check_button = CHECK_BUTTON(widget);
|
||||
return_value_if_fail(widget != NULL, NULL);
|
||||
|
@ -27,18 +27,70 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class check_button_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 勾选控件。
|
||||
*/
|
||||
typedef struct _check_button_t {
|
||||
widget_t widget;
|
||||
/**
|
||||
* @property {bool_t} value
|
||||
* @readonly
|
||||
* 值。
|
||||
*/
|
||||
bool_t value;
|
||||
bool_t radio;
|
||||
wstr_t text;
|
||||
}check_button_t;
|
||||
|
||||
/**
|
||||
* @method check_button_create
|
||||
* @constructor
|
||||
* 创建check_button对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* check_button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
widget_t* radio_button_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
/**
|
||||
* @method check_button_create_radio
|
||||
* @constructor
|
||||
* 创建check_button对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* check_button_create_radio(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method check_button_set_text
|
||||
* 设置控件的文本。
|
||||
* @param {widget_t*} widget check_button对象。
|
||||
* @param {wchar_t*} text 文本。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t check_button_set_text(widget_t* widget, const wchar_t* text);
|
||||
|
||||
/**
|
||||
* @method check_button_set_value
|
||||
* 设置控件的值。
|
||||
* @param {widget_t*} widget check_button对象。
|
||||
* @param {uint32_t} value 值
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t check_button_set_value(widget_t* widget, bool_t value);
|
||||
|
||||
#define CHECK_BUTTON(widget) ((check_button_t*)(widget))
|
||||
|
@ -35,13 +35,13 @@ static ret_t dialog_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
dialog_t* dialog = DIALOG(widget);
|
||||
color_t color = color_init(0x80, 0x80, 0x80, 0xff);
|
||||
|
||||
canvas_set_fill_color(c, style_get_color(style, E_FG_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_FG_COLOR, color));
|
||||
canvas_fill_rect(c, 0, 0, widget->w, TITLE_H);
|
||||
|
||||
canvas_set_fill_color(c, style_get_color(style, E_BG_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_BG_COLOR, color));
|
||||
canvas_fill_rect(c, 0, TITLE_H, widget->w, widget->h - TITLE_H);
|
||||
|
||||
canvas_set_stroke_color(c, style_get_color(style, E_BORDER_COLOR, color));
|
||||
canvas_set_stroke_color(c, style_get_color(style, STYLE_ID_BORDER_COLOR, color));
|
||||
canvas_stroke_rect(c, 0, 0, widget->w, widget->h);
|
||||
|
||||
if (dialog->icon.data != NULL) {
|
||||
@ -58,11 +58,11 @@ static ret_t dialog_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
x += TITLE_H;
|
||||
y = (TITLE_H >> 1);
|
||||
if (dialog->title.size > 0) {
|
||||
const char* font_name = style_get_str(style, E_FONT_NAME, NULL);
|
||||
uint16_t font_size = style_get_int(style, E_FONT_SIZE, 20);
|
||||
const char* font_name = style_get_str(style, STYLE_ID_FONT_NAME, NULL);
|
||||
uint16_t font_size = style_get_int(style, STYLE_ID_FONT_SIZE, 20);
|
||||
|
||||
canvas_set_font(c, font_name, font_size);
|
||||
canvas_set_fill_color(c, style_get_color(style, E_FG_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_FG_COLOR, color));
|
||||
canvas_draw_text(c, dialog->title.str, dialog->title.size, x, y);
|
||||
}
|
||||
|
||||
@ -139,14 +139,14 @@ ret_t dialog_set_title(widget_t* widget, const wchar_t* title) {
|
||||
|
||||
uint32_t dialog_modal(widget_t* widget) {
|
||||
dialog_t* dialog = DIALOG(widget);
|
||||
bool_t running = default_main_loop()->running;
|
||||
bool_t running = main_loop_get_default()->running;
|
||||
return_value_if_fail(dialog != NULL, RET_BAD_PARAMS);
|
||||
|
||||
log_debug("%s run\n", __func__);
|
||||
|
||||
widget_invalidate(widget, NULL);
|
||||
main_loop_run(default_main_loop());
|
||||
default_main_loop()->running = running;
|
||||
main_loop_run(main_loop_get_default());
|
||||
main_loop_get_default()->running = running;
|
||||
|
||||
log_debug("%s quit\n", __func__);
|
||||
|
||||
@ -158,7 +158,7 @@ ret_t dialog_quit(widget_t* widget, uint32_t code) {
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
dialog->quit_code = code;
|
||||
main_loop_quit(default_main_loop());
|
||||
main_loop_quit(main_loop_get_default());
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
@ -27,6 +27,12 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class dialog_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 对话框控件。
|
||||
*/
|
||||
typedef struct _dialog_t {
|
||||
widget_t widget;
|
||||
bitmap_t icon;
|
||||
@ -35,12 +41,57 @@ typedef struct _dialog_t {
|
||||
uint32_t quit_code;
|
||||
}dialog_t;
|
||||
|
||||
/**
|
||||
* @method dialog_create
|
||||
* @constructor
|
||||
* 创建dialog对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* dialog_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method dialog_set_icon
|
||||
* 设置对话框的标题图标。
|
||||
* @param {widget_t*} widget dialog对象。
|
||||
* @param {char*} name 图标名称。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t dialog_set_icon(widget_t* widget, const char* name);
|
||||
|
||||
/**
|
||||
* @method dialog_set_title
|
||||
* 设置对话框的标题文本。
|
||||
* @param {widget_t*} widget dialog对象。
|
||||
* @param {wchar_t*} title 标题。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t dialog_set_title(widget_t* widget, const wchar_t* title);
|
||||
|
||||
/**
|
||||
* @method dialog_modal
|
||||
* 模态显示对话框。
|
||||
* @param {widget_t*} widget dialog对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
uint32_t dialog_modal(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method dialog_quit
|
||||
* 退出模态显示。
|
||||
* @param {widget_t*} widget dialog对象。
|
||||
* @param {uint32_t} code 退出码,作为dialog_modal的返回值。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t dialog_quit(widget_t* widget, uint32_t code);
|
||||
|
||||
#define DIALOG(widget) ((dialog_t*)(widget))
|
||||
|
@ -32,6 +32,7 @@ emitter_t* emitter_init(emitter_t* emitter) {
|
||||
return_value_if_fail(emitter, NULL);
|
||||
memset(emitter, 0x00, sizeof(emitter_t));
|
||||
emitter->enable = TRUE;
|
||||
emitter->curr_id = 1;
|
||||
|
||||
return emitter;
|
||||
}
|
||||
@ -87,21 +88,66 @@ static ret_t emitter_extends(emitter_t* emitter, uint32_t nr) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t emitter_on(emitter_t* emitter, uint16_t etype, event_handler handler, void* ctx) {
|
||||
uint32_t emitter_on(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx) {
|
||||
emitter_item_t* iter = NULL;
|
||||
return_value_if_fail(emitter != NULL && handler != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(emitter_extends(emitter, 1) == RET_OK, RET_FAIL);
|
||||
return_value_if_fail(emitter != NULL && handler != NULL, 0);
|
||||
return_value_if_fail(emitter_extends(emitter, 1) == RET_OK, 0);
|
||||
|
||||
iter = emitter->items + emitter->size;
|
||||
iter->type = etype;
|
||||
iter->ctx = ctx;
|
||||
iter->handler = handler;
|
||||
iter->id = emitter->curr_id++;
|
||||
|
||||
emitter->size++;
|
||||
|
||||
return RET_OK;
|
||||
return iter->id;
|
||||
}
|
||||
|
||||
ret_t emitter_off(emitter_t* emitter, uint16_t etype, event_handler handler, void* ctx) {
|
||||
emitter_item_t* emitter_find(emitter_t* emitter, uint32_t id) {
|
||||
return_value_if_fail(emitter != NULL, NULL);
|
||||
|
||||
if (emitter->items) {
|
||||
uint32_t i = 0;
|
||||
uint32_t size = emitter->size;
|
||||
emitter_item_t* items = emitter->items;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
emitter_item_t* iter = items + i;
|
||||
if (iter->id == id) {
|
||||
return iter;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret_t emitter_off(emitter_t* emitter, uint32_t id) {
|
||||
return_value_if_fail(emitter != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (emitter->items) {
|
||||
uint32_t i = 0;
|
||||
uint32_t size = emitter->size;
|
||||
emitter_item_t* items = emitter->items;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
emitter_item_t* iter = items + i;
|
||||
if (iter->id == id) {
|
||||
for (; i < (size - 1); i++) {
|
||||
items[i] = items[i + 1];
|
||||
}
|
||||
emitter->size--;
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return RET_FAIL;
|
||||
}
|
||||
|
||||
ret_t emitter_off_by_func(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx) {
|
||||
return_value_if_fail(emitter != NULL && handler != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (emitter->items) {
|
||||
|
@ -27,9 +27,10 @@
|
||||
BEGIN_C_DECLS
|
||||
|
||||
typedef struct _emitter_item_t {
|
||||
uint32_t id;
|
||||
uint16_t type;
|
||||
void* ctx;
|
||||
event_handler handler;
|
||||
event_func_t handler;
|
||||
}emitter_item_t;
|
||||
|
||||
typedef struct _emitter_t {
|
||||
@ -38,13 +39,17 @@ typedef struct _emitter_t {
|
||||
uint8_t stop;
|
||||
uint8_t enable;
|
||||
emitter_item_t* items;
|
||||
uint32_t curr_id;
|
||||
}emitter_t;
|
||||
|
||||
emitter_t* emitter_create(void);
|
||||
emitter_t* emitter_init(emitter_t* emitter);
|
||||
ret_t emitter_dispatch(emitter_t* emitter, event_t* e);
|
||||
ret_t emitter_on(emitter_t* emitter, uint16_t etype, event_handler handler, void* ctx);
|
||||
ret_t emitter_off(emitter_t* emitter, uint16_t etype, event_handler handler, void* ctx);
|
||||
|
||||
uint32_t emitter_on(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx);
|
||||
ret_t emitter_off(emitter_t* emitter, uint32_t id);
|
||||
emitter_item_t* emitter_find(emitter_t* emitter, uint32_t id);
|
||||
ret_t emitter_off_by_func(emitter_t* emitter, uint16_t etype, event_func_t handler, void* ctx);
|
||||
|
||||
ret_t emitter_stop(emitter_t* emitter);
|
||||
ret_t emitter_enable(emitter_t* emitter);
|
||||
|
@ -34,18 +34,18 @@ static const key_type_value_t widget_name_value[] = {{"widget", 0, WIDGET_NONE},
|
||||
{"progress_bar", 0, WIDGET_PROGRESS_BAR}};
|
||||
|
||||
static const key_type_value_t style_name_value[] = {
|
||||
{"bg-color", TYPE_COLOR, E_BG_COLOR}, {"fg-color", TYPE_COLOR, E_FG_COLOR},
|
||||
{"text-color", TYPE_COLOR, E_TEXT_COLOR}, {"border-color", TYPE_COLOR, E_BORDER_COLOR},
|
||||
{"font-name", TYPE_STRING, E_FONT_NAME}, {"font-size", TYPE_INT, E_FONT_SIZE},
|
||||
{"font-style", TYPE_INT, E_FONT_STYLE}, {"text-align-h", TYPE_INT, E_TEXT_ALIGN_H},
|
||||
{"text-align-v", TYPE_INT, E_TEXT_ALIGN_V}, {"icon", TYPE_STRING, E_ICON},
|
||||
{"bg-color", TYPE_COLOR, STYLE_ID_BG_COLOR}, {"fg-color", TYPE_COLOR, STYLE_ID_FG_COLOR},
|
||||
{"text-color", TYPE_COLOR, STYLE_ID_TEXT_COLOR}, {"border-color", TYPE_COLOR, STYLE_ID_BORDER_COLOR},
|
||||
{"font-name", TYPE_STRING, STYLE_ID_FONT_NAME}, {"font-size", TYPE_INT, STYLE_ID_FONT_SIZE},
|
||||
{"font-style", TYPE_INT, STYLE_ID_FONT_STYLE}, {"text-align-h", TYPE_INT, STYLE_ID_TEXT_ALIGN_H},
|
||||
{"text-align-v", TYPE_INT, STYLE_ID_TEXT_ALIGN_V}, {"icon", TYPE_STRING, STYLE_ID_ICON},
|
||||
};
|
||||
|
||||
static const key_type_value_t state_name_value[] = {
|
||||
{"normal", 0, WIDGET_STATE_NORMAL}, {"over", 0, WIDGET_STATE_OVER},
|
||||
{"pressed", 0, WIDGET_STATE_PRESSED}, {"disable", 0, WIDGET_STATE_DISABLE},
|
||||
{"focus", 0, WIDGET_STATE_FOCUS}, {"selected", 0, WIDGET_STATE_SELECTED},
|
||||
{"checked", 0, WIDGET_STATE_CHECKED}, {"unchecked", 0, WIDGET_STATE_UNCHECKED}};
|
||||
{"normal", 0, WIDGET_STATE_NORMAL}, {"over", 0, WIDGET_STATE_OVER},
|
||||
{"pressed", 0, WIDGET_STATE_PRESSED}, {"disable", 0, WIDGET_STATE_DISABLE},
|
||||
{"focused", 0, WIDGET_STATE_FOCUSED}, {"checked", 0, WIDGET_STATE_CHECKED},
|
||||
{"unchecked", 0, WIDGET_STATE_UNCHECKED}};
|
||||
|
||||
static const key_type_value_t align_v_name_value[] = {
|
||||
{"top", 0, ALIGN_V_TOP}, {"middle", 0, ALIGN_V_MIDDLE}, {"bottom", 0, ALIGN_V_BOTTOM}};
|
||||
|
36
src/base/events.c
Normal file
36
src/base/events.c
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* File: events.c
|
||||
* Author: Li XianJing <xianjimli@hotmail.com>
|
||||
* Brief: events structs
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Li XianJing <xianjimli@hotmail.com>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-03-02 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/events.h"
|
||||
|
||||
pointer_event_t* pointer_event_cast(event_t* event) {
|
||||
return_value_if_fail(event != NULL, NULL);
|
||||
return_value_if_fail(event->type >= EVT_POINTER_DOWN && event->type <= EVT_CLICK, NULL);
|
||||
|
||||
return (pointer_event_t*)event;
|
||||
}
|
||||
|
||||
key_event_t* key_event_cast(event_t* event) {
|
||||
return_value_if_fail(event != NULL, NULL);
|
||||
return_value_if_fail(event->type >= EVT_KEY_DOWN && event->type <= EVT_KEY_UP, NULL);
|
||||
|
||||
return (key_event_t*)event;
|
||||
}
|
@ -26,45 +26,192 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @enum event_type_t
|
||||
* @scriptable
|
||||
* 类型常量定义。
|
||||
*/
|
||||
typedef enum _event_type_t {
|
||||
/**
|
||||
* @const EVT_NONE
|
||||
* 无效事件名称。
|
||||
*/
|
||||
EVT_NONE,
|
||||
/**
|
||||
* @const EVT_POINTER_DOWN
|
||||
* 指针按下事件名。
|
||||
*/
|
||||
EVT_POINTER_DOWN,
|
||||
/**
|
||||
* @const EVT_POINTER_MOVE
|
||||
* 指针移动事件名。
|
||||
*/
|
||||
EVT_POINTER_MOVE,
|
||||
/**
|
||||
* @const EVT_POINTER_UP
|
||||
* 指针抬起事件名。
|
||||
*/
|
||||
EVT_POINTER_UP,
|
||||
/**
|
||||
* @const EVT_POINTER_ENTER
|
||||
* 指针进入事件名。
|
||||
*/
|
||||
EVT_POINTER_ENTER,
|
||||
/**
|
||||
* @const EVT_POINTER_LEAVE
|
||||
* 指针离开事件名。
|
||||
*/
|
||||
EVT_POINTER_LEAVE,
|
||||
/**
|
||||
* @const EVT_CLICK
|
||||
* 点击事件名。
|
||||
*/
|
||||
EVT_CLICK,
|
||||
/**
|
||||
* @const EVT_KEY_DOWN
|
||||
* 键按下事件名。
|
||||
*/
|
||||
EVT_KEY_DOWN,
|
||||
/**
|
||||
* @const EVT_KEY_UP
|
||||
* 键抬起事件名。
|
||||
*/
|
||||
EVT_KEY_UP,
|
||||
/**
|
||||
* @const EVT_MOVE
|
||||
* Widget移动事件名。
|
||||
*/
|
||||
EVT_MOVE,
|
||||
/**
|
||||
* @const EVT_RESIZE
|
||||
* Widget调整大小事件名。
|
||||
*/
|
||||
EVT_RESIZE,
|
||||
/**
|
||||
* @const EVT_DESTROY
|
||||
* 对象销毁事件名。
|
||||
*/
|
||||
EVT_DESTROY,
|
||||
/**
|
||||
* @const EVT_MOVE_RESIZE
|
||||
* Widget调整大小/移动事件名。
|
||||
*/
|
||||
EVT_MOVE_RESIZE,
|
||||
/**
|
||||
* @const EVT_PROP_CHANGED
|
||||
* 对象的属性改变事件名。
|
||||
*/
|
||||
EVT_PROP_CHANGED
|
||||
}event_type_t;
|
||||
|
||||
/**
|
||||
* @class event_t
|
||||
* @scriptable
|
||||
* 事件基类。
|
||||
*/
|
||||
typedef struct _event_t {
|
||||
/**
|
||||
* @property {int16_t} type
|
||||
* @readonly
|
||||
* 类型。
|
||||
*/
|
||||
uint16_t type;
|
||||
void* target;
|
||||
}event_t;
|
||||
|
||||
/**
|
||||
* @class pointer_event_t
|
||||
* @scriptable
|
||||
* @parent event_t
|
||||
* 指针事件。
|
||||
*/
|
||||
|
||||
typedef struct _pointer_event_t {
|
||||
event_t e;
|
||||
/**
|
||||
* @property {xy_t} x
|
||||
* @readonly
|
||||
* x坐标。
|
||||
*/
|
||||
xy_t x;
|
||||
/**
|
||||
* @property {xy_t} y
|
||||
* @readonly
|
||||
* y坐标。
|
||||
*/
|
||||
xy_t y;
|
||||
uint8_t button;
|
||||
/**
|
||||
* @property {uint8_t} button
|
||||
* @readonly
|
||||
* button。
|
||||
*/
|
||||
xy_t button;
|
||||
/**
|
||||
* @property {bool_t} pressed
|
||||
* @readonly
|
||||
* 指针是否按下。
|
||||
*/
|
||||
uint8_t pressed:1;
|
||||
}pointer_event_t;
|
||||
|
||||
/**
|
||||
* @method pointer_event_cast
|
||||
* @constructor
|
||||
* 把event对象转pointer_event_t对象
|
||||
* @param {event_t*} event event对象。
|
||||
*
|
||||
* @return {pointer_event_t*} 对象。
|
||||
*/
|
||||
pointer_event_t* pointer_event_cast(event_t* event);
|
||||
|
||||
|
||||
/**
|
||||
* @class key_event_t
|
||||
* @scriptable
|
||||
* @parent event_t
|
||||
* 按键事件。
|
||||
*/
|
||||
|
||||
typedef struct _key_event_t {
|
||||
event_t e;
|
||||
/**
|
||||
* @property {uint8_t} key
|
||||
* @readonly
|
||||
* 键值。
|
||||
*/
|
||||
uint8_t key;
|
||||
/**
|
||||
* @property {bool_t} alt
|
||||
* @readonly
|
||||
* alt键是否按下。
|
||||
*/
|
||||
uint8_t alt:1;
|
||||
/**
|
||||
* @property {bool_t} ctrl
|
||||
* @readonly
|
||||
* ctrl键是否按下。
|
||||
*/
|
||||
uint8_t ctrl:1;
|
||||
/**
|
||||
* @property {bool_t} shift
|
||||
* @readonly
|
||||
* shift键是否按下。
|
||||
*/
|
||||
uint8_t shift:1;
|
||||
}key_event_t;
|
||||
|
||||
typedef ret_t (*event_handler)(void* ctx, event_t* e);
|
||||
/**
|
||||
* @method key_event_cast
|
||||
* @constructor
|
||||
* 把event对象转key_event_t对象
|
||||
* @param {event_t*} event event对象。
|
||||
*
|
||||
* @return {key_event_t*} 对象。
|
||||
*/
|
||||
key_event_t* key_event_cast(event_t* event);
|
||||
|
||||
|
||||
typedef ret_t (*event_func_t)(void* ctx, event_t* e);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
|
@ -26,10 +26,28 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class group_box_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 分组控件。
|
||||
*/
|
||||
typedef struct _group_box_t {
|
||||
widget_t widget;
|
||||
}group_box_t;
|
||||
|
||||
/**
|
||||
* @method group_box_create
|
||||
* @constructor
|
||||
* 创建group_box对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* group_box_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
END_C_DECLS
|
||||
|
@ -28,13 +28,41 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class image_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 图片控件。
|
||||
*/
|
||||
typedef struct _image_t {
|
||||
widget_t widget;
|
||||
bitmap_t bitmap;
|
||||
}image_t;
|
||||
|
||||
/**
|
||||
* @method image_create
|
||||
* @constructor
|
||||
* 创建image对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* image_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method image_set_image_name
|
||||
* 设置控件的图片名称。
|
||||
* @param {widget_t*} widget image对象。
|
||||
* @param {char*} name 图片名称。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t image_set_image_name(widget_t* widget, const char* name);
|
||||
|
||||
ret_t image_set_image(widget_t* widget, bitmap_t* image);
|
||||
|
||||
#define IMAGE(widget) (image_t*)(widget)
|
||||
|
@ -34,14 +34,14 @@ static ret_t label_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
return_value_if_fail(widget != NULL && c != NULL, RET_BAD_PARAMS);
|
||||
|
||||
canvas_set_font(c, NULL, 20);
|
||||
canvas_set_fill_color(c, style_get_color(style, E_BG_COLOR, color));
|
||||
canvas_set_text_color(c, style_get_color(style, E_TEXT_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_BG_COLOR, color));
|
||||
canvas_set_text_color(c, style_get_color(style, STYLE_ID_TEXT_COLOR, color));
|
||||
|
||||
canvas_fill_rect(c, 0, 0, widget->w, widget->h);
|
||||
w = canvas_measure_text(c, label->text.str, label->text.size);
|
||||
|
||||
text_align_h = style_get_int(style, E_TEXT_ALIGN_H, label->text_align_h);
|
||||
text_align_v = style_get_int(style, E_TEXT_ALIGN_V, label->text_align_v);
|
||||
text_align_h = style_get_int(style, STYLE_ID_TEXT_ALIGN_H, label->text_align_h);
|
||||
text_align_v = style_get_int(style, STYLE_ID_TEXT_ALIGN_V, label->text_align_v);
|
||||
|
||||
switch (text_align_v) {
|
||||
case ALIGN_V_TOP:
|
||||
|
@ -27,21 +27,89 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class label_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 文本控件。
|
||||
*/
|
||||
typedef struct _label_t {
|
||||
widget_t widget;
|
||||
wstr_t text;
|
||||
/**
|
||||
* @property {uint8_t} border
|
||||
* @readonly
|
||||
* 边距。
|
||||
*/
|
||||
uint8_t border;
|
||||
/**
|
||||
* @property {uint8_t} text_align_v
|
||||
* @readonly
|
||||
* 文本垂直对齐方式。
|
||||
*/
|
||||
uint8_t text_align_v;
|
||||
/**
|
||||
* @property {uint8_t} text_align_h
|
||||
* @readonly
|
||||
* 文本水平对齐方式。
|
||||
*/
|
||||
uint8_t text_align_h;
|
||||
}label_t;
|
||||
|
||||
/**
|
||||
* @method label_create
|
||||
* @constructor
|
||||
* 创建label对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* label_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
ret_t label_set_text(widget_t* widget, const wchar_t* text);
|
||||
/**
|
||||
* @method label_set_border
|
||||
* 设置控件的边距。
|
||||
* @param {widget_t*} widget label对象。
|
||||
* @param {uint8_t} border 边距
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t label_set_border(widget_t* widget, uint8_t border);
|
||||
|
||||
/**
|
||||
* @method label_set_text_align_h
|
||||
* 设置控件的文本水平对齐方式。
|
||||
* @param {widget_t*} widget label对象。
|
||||
* @param {uint8_t} text_align_h 文本水平对齐方式。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t label_set_text_align_h(widget_t* widget, uint8_t text_align_h);
|
||||
|
||||
/**
|
||||
* @method label_set_text_align_v
|
||||
* 设置控件的文本垂直对齐方式。
|
||||
* @param {widget_t*} widget label对象。
|
||||
* @param {uint8_t} text_align_v 文本垂直对齐方式。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t label_set_text_align_v(widget_t* widget, uint8_t text_align_v);
|
||||
|
||||
/**
|
||||
* @method label_set_text
|
||||
* 设置控件的文本。
|
||||
* @param {widget_t*} widget label对象。
|
||||
* @param {wchar_t*} text 文本。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t label_set_text(widget_t* widget, const wchar_t* text);
|
||||
|
||||
#define LABEL(widget) ((label_t*)(widget))
|
||||
|
||||
END_C_DECLS
|
||||
|
51
src/base/lftk.c
Executable file
51
src/base/lftk.c
Executable file
@ -0,0 +1,51 @@
|
||||
/**
|
||||
* File: lftk.c
|
||||
* Author: Li XianJing <xianjimli@hotmail.com>
|
||||
* Brief: lftk
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Li XianJing <xianjimli@hotmail.com>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-03-03 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#include "base/mem.h"
|
||||
#include "base/lftk.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/platform.h"
|
||||
#include "base/main_loop.h"
|
||||
|
||||
ret_t lftk_init(wh_t w, wh_t h, uint32_t* heap, uint32_t size) {
|
||||
return_value_if_fail(platform_prepare() == RET_OK, RET_FAIL);
|
||||
return_value_if_fail(mem_init(heap, size) == RET_OK, RET_FAIL);
|
||||
return_value_if_fail(main_loop_init(w, h) != NULL, RET_FAIL);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t lftk_run() {
|
||||
main_loop_run(main_loop_get_default());
|
||||
main_loop_destroy(main_loop_get_default());
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
static ret_t lftk_quit_idle(const f_timer_t* timer) {
|
||||
return main_loop_quit(main_loop_get_default());
|
||||
}
|
||||
|
||||
ret_t lftk_quit() {
|
||||
return timer_add(lftk_quit_idle, NULL, 0);
|
||||
}
|
||||
|
||||
|
65
src/base/lftk.h
Executable file
65
src/base/lftk.h
Executable file
@ -0,0 +1,65 @@
|
||||
/**
|
||||
* File: lftk.h
|
||||
* Author: Li XianJing <xianjimli@hotmail.com>
|
||||
* Brief: lftk
|
||||
*
|
||||
* Copyright (c) 2018 - 2018 Li XianJing <xianjimli@hotmail.com>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* License file for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* History:
|
||||
* ================================================================
|
||||
* 2018-03-03 Li XianJing <xianjimli@hotmail.com> created
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LFTK_MAIN_H
|
||||
#define LFTK_MAIN_H
|
||||
|
||||
#include "base/types_def.h"
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @method lftk_init
|
||||
* 初始化LFTK。
|
||||
* @global
|
||||
* @scriptable no
|
||||
* @param {wh_t} w LCD宽度。
|
||||
* @param {wh_t} h LCD高度。
|
||||
* @param {uint32_t*} heap 动态内存空间。
|
||||
* @param {uint32_t} size 动态内存空间的大小。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t lftk_init(wh_t w, wh_t h, uint32_t* heap, uint32_t size);
|
||||
|
||||
/**
|
||||
* @method lftk_run
|
||||
* 进入LFTK事件主循环。
|
||||
* @global
|
||||
* @scriptable no
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t lftk_run();
|
||||
|
||||
/**
|
||||
* @method lftk_quit
|
||||
* 退出LFTK事件主循环。
|
||||
* @global
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t lftk_quit();
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
#endif/*LFTK_MAIN_H*/
|
||||
|
@ -41,7 +41,9 @@ struct _main_loop_t {
|
||||
bool_t running;
|
||||
};
|
||||
|
||||
main_loop_t* default_main_loop(void);
|
||||
main_loop_t* main_loop_init(int w, int h);
|
||||
|
||||
main_loop_t* main_loop_get_default(void);
|
||||
|
||||
ret_t main_loop_run(main_loop_t* l);
|
||||
ret_t main_loop_quit(main_loop_t* l);
|
||||
|
@ -33,9 +33,9 @@ static ret_t progress_bar_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
color_t color = color_init(0xff, 0xff, 0xff, 0xff);
|
||||
return_value_if_fail(widget != NULL && c != NULL, RET_BAD_PARAMS);
|
||||
|
||||
canvas_set_text_color(c, style_get_color(style, E_TEXT_COLOR, color));
|
||||
canvas_set_text_color(c, style_get_color(style, STYLE_ID_TEXT_COLOR, color));
|
||||
|
||||
canvas_set_fill_color(c, style_get_color(style, E_FG_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_FG_COLOR, color));
|
||||
if (progress_bar->vertical) {
|
||||
h = (widget->h * progress_bar->value) / 100;
|
||||
canvas_fill_rect(c, x, y + widget->h - h, widget->w, h);
|
||||
@ -44,7 +44,7 @@ static ret_t progress_bar_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
canvas_fill_rect(c, x, y, w, widget->h);
|
||||
}
|
||||
|
||||
canvas_set_fill_color(c, style_get_color(style, E_BG_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_BG_COLOR, color));
|
||||
if (progress_bar->vertical) {
|
||||
h = widget->h - h;
|
||||
canvas_fill_rect(c, x, y, widget->w, h);
|
||||
@ -54,7 +54,7 @@ static ret_t progress_bar_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
canvas_fill_rect(c, x, y, w, widget->h);
|
||||
}
|
||||
|
||||
canvas_set_stroke_color(c, style_get_color(style, E_BORDER_COLOR, color));
|
||||
canvas_set_stroke_color(c, style_get_color(style, STYLE_ID_BORDER_COLOR, color));
|
||||
canvas_stroke_rect(c, 0, 0, widget->w, widget->h);
|
||||
|
||||
if (progress_bar->show_text) {
|
||||
|
@ -26,17 +26,76 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class progress_bar_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 进度条控件。
|
||||
*/
|
||||
typedef struct _progress_bar_t {
|
||||
widget_t widget;
|
||||
uint8_t value; /*0-100*/
|
||||
/**
|
||||
* @property {uint8_t} value
|
||||
* @readonly
|
||||
* 进度条的值[0-100]。
|
||||
*/
|
||||
uint8_t value;
|
||||
/**
|
||||
* @property {bool_t} vertical
|
||||
* @readonly
|
||||
* 进度条的是否为垂直方向。
|
||||
*/
|
||||
bool_t vertical;
|
||||
/**
|
||||
* @property {bool_t} show_text
|
||||
* @readonly
|
||||
* 是否显示文本。
|
||||
*/
|
||||
bool_t show_text;
|
||||
}progress_bar_t;
|
||||
|
||||
/**
|
||||
* @method progress_bar_create
|
||||
* @constructor
|
||||
* 创建progress_bar对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* progress_bar_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method progress_bar_set_value
|
||||
* 设置进度条的进度。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {uint8_t} value 进度
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t progress_bar_set_value(widget_t* widget, uint8_t value);
|
||||
|
||||
/**
|
||||
* @method progress_bar_set_vertical
|
||||
* 设置进度条的方向。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {bool_t} vertical 是否为垂直方向。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t progress_bar_set_vertical(widget_t* widget, bool_t vertical);
|
||||
|
||||
/**
|
||||
* @method progress_bar_set_show_text
|
||||
* 设置进度条的是否显示文本。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {bool_t} show_text 是否显示文本。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t progress_bar_set_show_text(widget_t* widget, bool_t show_text);
|
||||
|
||||
#define PROGRESS_BAR(widget) ((progress_bar_t*)(widget))
|
||||
|
@ -26,16 +26,56 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class point_t
|
||||
* @scriptable
|
||||
* 点。包括一个x坐标和一个y坐标。
|
||||
*/
|
||||
typedef struct _point_t {
|
||||
xy_t x;
|
||||
xy_t y;
|
||||
/**
|
||||
* @property {xy_t} x
|
||||
* @readonly
|
||||
* x坐标。
|
||||
*/
|
||||
xy_t x;
|
||||
/**
|
||||
* @property {xy_t} y
|
||||
* @readonly
|
||||
* y坐标。
|
||||
*/
|
||||
xy_t y;
|
||||
}point_t;
|
||||
|
||||
/**
|
||||
* @class rect_t
|
||||
* @scriptable
|
||||
* 矩形。包括一个x坐标、y坐标、宽度和高度。
|
||||
*/
|
||||
typedef struct _rect_t {
|
||||
xy_t x;
|
||||
xy_t y;
|
||||
wh_t w;
|
||||
wh_t h;
|
||||
/**
|
||||
* @property {xy_t} x
|
||||
* @readonly
|
||||
* x坐标。
|
||||
*/
|
||||
xy_t x;
|
||||
/**
|
||||
* @property {xy_t} y
|
||||
* @readonly
|
||||
* y坐标。
|
||||
*/
|
||||
xy_t y;
|
||||
/**
|
||||
* @property {wh_t} w
|
||||
* @readonly
|
||||
* 宽度。
|
||||
*/
|
||||
wh_t w;
|
||||
/**
|
||||
* @property {wh_t} h
|
||||
* @readonly
|
||||
* 高度。
|
||||
*/
|
||||
wh_t h;
|
||||
}rect_t;
|
||||
|
||||
#define rect_init(r, xx, yy, ww, hh) r.x = (xx); r.y = (yy); r.w = (ww); r.h = (hh);
|
||||
|
@ -113,16 +113,14 @@ const uint8_t* theme_find_style(theme_t* t, uint16_t type, uint8_t subtype, uint
|
||||
}
|
||||
|
||||
static theme_t s_theme;
|
||||
theme_t* default_theme() {
|
||||
return_value_if_fail(s_theme.data != NULL, NULL);
|
||||
|
||||
theme_t* theme_get_default() {
|
||||
return &s_theme;
|
||||
}
|
||||
|
||||
theme_t* default_theme_init(const uint8_t* data) {
|
||||
theme_t* theme_init(const uint8_t* data) {
|
||||
return_value_if_fail(data != NULL, NULL);
|
||||
|
||||
s_theme.data = data;
|
||||
|
||||
return default_theme();
|
||||
return theme_get_default();
|
||||
}
|
||||
|
130
src/base/theme.h
130
src/base/theme.h
@ -26,6 +26,10 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class style_t
|
||||
* 控件风格的参数。
|
||||
*/
|
||||
typedef struct _style_t {
|
||||
const uint8_t* data;
|
||||
}style_t;
|
||||
@ -34,41 +38,131 @@ uint32_t style_get_int(style_t* s, uint32_t name, uint32_t defval);
|
||||
color_t style_get_color(style_t* s, uint32_t name, color_t defval);
|
||||
const char* style_get_str(style_t* s, uint32_t name, const char* defval);
|
||||
|
||||
/**
|
||||
* @class theme_t
|
||||
* 主题。
|
||||
*/
|
||||
typedef struct _theme_t {
|
||||
const uint8_t* data;
|
||||
}theme_t;
|
||||
|
||||
theme_t* default_theme(void);
|
||||
theme_t* default_theme_init(const uint8_t* data);
|
||||
theme_t* theme_get_default(void);
|
||||
theme_t* theme_init(const uint8_t* data);
|
||||
|
||||
const uint8_t* theme_find_style(theme_t* t, uint16_t type, uint8_t subtype, uint8_t state);
|
||||
|
||||
enum {
|
||||
E_BG_COLOR = 1,
|
||||
E_FG_COLOR,
|
||||
E_FONT_NAME,
|
||||
E_FONT_SIZE,
|
||||
E_FONT_STYLE,
|
||||
E_TEXT_COLOR,
|
||||
E_TEXT_ALIGN_H,
|
||||
E_TEXT_ALIGN_V,
|
||||
E_BORDER_COLOR,
|
||||
E_ICON
|
||||
};
|
||||
/**
|
||||
* @enum style_type_t
|
||||
* 类型常量定义。
|
||||
*/
|
||||
typedef enum _style_id_t {
|
||||
/**
|
||||
* @const STYLE_ID_BG_COLOR
|
||||
* 背景颜色。
|
||||
*/
|
||||
STYLE_ID_BG_COLOR = 1,
|
||||
/**
|
||||
* @const STYLE_ID_BG_COLOR
|
||||
* 前景颜色。
|
||||
*/
|
||||
STYLE_ID_FG_COLOR,
|
||||
/**
|
||||
* @const STYLE_ID_FONT_NAME
|
||||
* 字体名称。
|
||||
*/
|
||||
STYLE_ID_FONT_NAME,
|
||||
/**
|
||||
* @const STYLE_ID_FONT_SIZE
|
||||
* 字体大小。
|
||||
*/
|
||||
STYLE_ID_FONT_SIZE,
|
||||
/**
|
||||
* @const STYLE_ID_FONT_STYLE
|
||||
* 字体风格(粗体、斜体等)。
|
||||
*/
|
||||
STYLE_ID_FONT_STYLE,
|
||||
/**
|
||||
* @const STYLE_ID_TEXT_COLOR
|
||||
* 文本颜色。
|
||||
*/
|
||||
STYLE_ID_TEXT_COLOR,
|
||||
/**
|
||||
* @const STYLE_ID_TEXT_ALIGN_H
|
||||
* 文本水平对齐的方式。
|
||||
*/
|
||||
STYLE_ID_TEXT_ALIGN_H,
|
||||
/**
|
||||
* @const STYLE_ID_TEXT_ALIGN_V
|
||||
* 文本垂直对齐的方式。
|
||||
*/
|
||||
STYLE_ID_TEXT_ALIGN_V,
|
||||
/**
|
||||
* @const STYLE_ID_BORDER_COLOR
|
||||
* 边框颜色。
|
||||
*/
|
||||
STYLE_ID_BORDER_COLOR,
|
||||
/**
|
||||
* @const STYLE_ID_ICON
|
||||
* 图标的名称。
|
||||
*/
|
||||
STYLE_ID_ICON
|
||||
}style_id_t;
|
||||
|
||||
enum {
|
||||
/**
|
||||
* @enum align_v_t
|
||||
* @scriptable
|
||||
* 类型常量定义。
|
||||
*/
|
||||
typedef enum _align_v_t {
|
||||
/**
|
||||
* @const ALIGN_V_NONE
|
||||
* 无效对齐方式。
|
||||
*/
|
||||
ALIGN_V_NONE= 0,
|
||||
/**
|
||||
* @const ALIGN_V_MIDDLE
|
||||
* 居中对齐。
|
||||
*/
|
||||
ALIGN_V_MIDDLE,
|
||||
/**
|
||||
* @const ALIGN_V_TOP
|
||||
* 顶部对齐。
|
||||
*/
|
||||
ALIGN_V_TOP,
|
||||
/**
|
||||
* @const ALIGN_V_BOTTOM
|
||||
* 底部对齐。
|
||||
*/
|
||||
ALIGN_V_BOTTOM
|
||||
};
|
||||
}align_v_t;
|
||||
|
||||
enum {
|
||||
/**
|
||||
* @enum align_h_t
|
||||
* @scriptable
|
||||
* 类型常量定义。
|
||||
*/
|
||||
typedef enum _align_h_t {
|
||||
/**
|
||||
* @const ALIGN_H_NONE
|
||||
* 无效对齐方式。
|
||||
*/
|
||||
ALIGN_H_NONE = 0,
|
||||
/**
|
||||
* @const ALIGN_H_CENTER
|
||||
* 居中对齐。
|
||||
*/
|
||||
ALIGN_H_CENTER,
|
||||
/**
|
||||
* @const ALIGN_H_LEFT
|
||||
* 左边对齐。
|
||||
*/
|
||||
ALIGN_H_LEFT,
|
||||
/**
|
||||
* @const ALIGN_H_RIGHT
|
||||
* 右边对齐。
|
||||
*/
|
||||
ALIGN_H_RIGHT
|
||||
};
|
||||
}align_h_t;
|
||||
|
||||
#define THEME_MAGIC 0xFAFBFCFD
|
||||
|
||||
|
@ -33,14 +33,56 @@ typedef int xy_t;
|
||||
typedef uint32_t id_t;
|
||||
typedef uint32_t wh_t;
|
||||
|
||||
/**
|
||||
* @enum ret_t
|
||||
* @scriptable
|
||||
* 函数返回值常量定义。
|
||||
*/
|
||||
typedef enum _ret_t {
|
||||
/**
|
||||
* @const RET_OK
|
||||
* 成功。
|
||||
*/
|
||||
RET_OK,
|
||||
/**
|
||||
* @const RET_OOM
|
||||
* Out of memory。
|
||||
*/
|
||||
RET_OOM,
|
||||
/**
|
||||
* @const RET_FAIL
|
||||
* 失败。
|
||||
*/
|
||||
RET_FAIL,
|
||||
/**
|
||||
* @const RET_QUIT
|
||||
* 退出。通常用于主循环。
|
||||
*/
|
||||
RET_QUIT,
|
||||
/**
|
||||
* @const RET_FOUND
|
||||
* 找到。
|
||||
*/
|
||||
RET_FOUND,
|
||||
/**
|
||||
* @const RET_REMOVE
|
||||
* 移出。通常用于定时器。
|
||||
*/
|
||||
RET_REMOVE,
|
||||
/**
|
||||
* @const RET_REPEAT
|
||||
* 重复。通常用于定时器。
|
||||
*/
|
||||
RET_REPEAT,
|
||||
/**
|
||||
* @const RET_NOT_FOUND
|
||||
* 没找到。
|
||||
*/
|
||||
RET_NOT_FOUND,
|
||||
/**
|
||||
* @const RET_BAD_PARAMS
|
||||
* 无效参数。
|
||||
*/
|
||||
RET_BAD_PARAMS
|
||||
}ret_t;
|
||||
|
||||
@ -138,3 +180,4 @@ enum {
|
||||
};
|
||||
|
||||
#endif/*TYPES_DEF_H*/
|
||||
|
||||
|
@ -174,14 +174,14 @@ pointer_t value_pointer(const value_t* v) {
|
||||
value_t* value_set_float(value_t* v, float value) {
|
||||
return_value_if_fail(v != NULL, NULL);
|
||||
|
||||
v->type = VALUE_TYPE_FLOAT32;
|
||||
v->type = VALUE_TYPE_FLOAT;
|
||||
v->value.f32 = value;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
float value_float(const value_t* v) {
|
||||
return_value_if_fail(v->type == VALUE_TYPE_FLOAT32, 0.0);
|
||||
return_value_if_fail(v->type == VALUE_TYPE_FLOAT, 0.0);
|
||||
|
||||
return v->value.f32;
|
||||
}
|
||||
@ -189,14 +189,14 @@ float value_float(const value_t* v) {
|
||||
value_t* value_set_double(value_t* v, double value) {
|
||||
return_value_if_fail(v != NULL, NULL);
|
||||
|
||||
v->type = VALUE_TYPE_FLOAT64;
|
||||
v->type = VALUE_TYPE_DOUBLE;
|
||||
v->value.f64 = value;
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
double value_double(const value_t* v) {
|
||||
return_value_if_fail(v->type == VALUE_TYPE_FLOAT64, 0);
|
||||
return_value_if_fail(v->type == VALUE_TYPE_DOUBLE, 0);
|
||||
|
||||
return v->value.f64;
|
||||
}
|
||||
@ -269,10 +269,10 @@ int value_int(const value_t* v) {
|
||||
case VALUE_TYPE_UINT64: {
|
||||
return (int)v->value.u64;
|
||||
}
|
||||
case VALUE_TYPE_FLOAT32: {
|
||||
case VALUE_TYPE_FLOAT: {
|
||||
return (int)v->value.f32;
|
||||
}
|
||||
case VALUE_TYPE_FLOAT64: {
|
||||
case VALUE_TYPE_DOUBLE: {
|
||||
return (int)v->value.f64;
|
||||
}
|
||||
case VALUE_TYPE_STRING: {
|
||||
@ -287,11 +287,6 @@ int value_int(const value_t* v) {
|
||||
|
||||
value_t* value_set_int(value_t* v, int32_t value) { return value_set_int32(v, value); }
|
||||
|
||||
value_t* value_create() {
|
||||
return MEM_ZALLOC(value_t);
|
||||
}
|
||||
|
||||
void value_destroy(value_t* v) {
|
||||
MEM_FREE(v);
|
||||
}
|
||||
value_t* value_create() { return MEM_ZALLOC(value_t); }
|
||||
|
||||
void value_destroy(value_t* v) { MEM_FREE(v); }
|
||||
|
@ -88,15 +88,15 @@ typedef enum _value_type_t {
|
||||
*/
|
||||
VALUE_TYPE_POINTER,
|
||||
/**
|
||||
* @const VALUE_TYPE_FLOAT32
|
||||
* @const VALUE_TYPE_FLOAT
|
||||
* float类型。
|
||||
*/
|
||||
VALUE_TYPE_FLOAT32,
|
||||
VALUE_TYPE_FLOAT,
|
||||
/**
|
||||
* @const VALUE_TYPE_FLOAT64
|
||||
* @const VALUE_TYPE_DOUBLE
|
||||
* double类型。
|
||||
*/
|
||||
VALUE_TYPE_FLOAT64,
|
||||
VALUE_TYPE_DOUBLE,
|
||||
/**
|
||||
* @const VALUE_TYPE_STRING
|
||||
* char*类型。
|
||||
@ -314,6 +314,7 @@ uint64_t value_uint64(const value_t* v);
|
||||
/**
|
||||
* @method value_set_pointer
|
||||
* 设置类型为pointer的值。
|
||||
* @scriptable no
|
||||
* @param {value_t*} v value对象。
|
||||
* @param {pointer_t} value 待设置的值。
|
||||
*
|
||||
@ -324,6 +325,7 @@ value_t* value_set_pointer(value_t* v, pointer_t value);
|
||||
/**
|
||||
* @method value_pointer
|
||||
* 获取类型为pointer的值。
|
||||
* @scriptable no
|
||||
* @param {value_t*} v value对象。
|
||||
*
|
||||
* @return {void*} 值。
|
||||
|
@ -108,11 +108,11 @@ ret_t widget_set_enable(widget_t* widget, bool_t enable) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t widget_set_selected(widget_t* widget, bool_t selected) {
|
||||
ret_t widget_set_focused(widget_t* widget, bool_t focused) {
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (widget->selected != selected) {
|
||||
widget->selected = selected;
|
||||
if (widget->focused != focused) {
|
||||
widget->focused = focused;
|
||||
widget_update_style(widget);
|
||||
widget_invalidate(widget, NULL);
|
||||
}
|
||||
@ -132,7 +132,7 @@ ret_t widget_set_state(widget_t* widget, widget_state_t state) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t widget_remove_children(widget_t* widget) {
|
||||
ret_t widget_destroy_children(widget_t* widget) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
@ -169,7 +169,7 @@ ret_t widget_remove_child(widget_t* widget, widget_t* child) {
|
||||
return array_remove(widget->children, NULL, child) ? RET_OK : RET_NOT_FOUND;
|
||||
}
|
||||
|
||||
widget_t* widget_lookup_child(widget_t* widget, const char* name) {
|
||||
static widget_t* widget_lookup_child(widget_t* widget, const char* name) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
return_value_if_fail(widget != NULL && name != NULL, NULL);
|
||||
@ -186,7 +186,7 @@ widget_t* widget_lookup_child(widget_t* widget, const char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
widget_t* widget_lookup(widget_t* widget, const char* name) {
|
||||
static widget_t* widget_lookup_all(widget_t* widget, const char* name) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
return_value_if_fail(widget != NULL && name != NULL, NULL);
|
||||
@ -197,7 +197,7 @@ widget_t* widget_lookup(widget_t* widget, const char* name) {
|
||||
if (strcmp(iter->name, name) == 0) {
|
||||
return iter;
|
||||
} else {
|
||||
iter = widget_lookup(iter, name);
|
||||
iter = widget_lookup_all(iter, name);
|
||||
if (iter != NULL) {
|
||||
return iter;
|
||||
}
|
||||
@ -208,7 +208,15 @@ widget_t* widget_lookup(widget_t* widget, const char* name) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret_t widget_set_visible(widget_t* widget, bool_t visible) {
|
||||
widget_t* widget_lookup(widget_t* widget, const char* name, bool_t recursive) {
|
||||
if (recursive) {
|
||||
return widget_lookup_all(widget, name);
|
||||
} else {
|
||||
return widget_lookup_child(widget, name);
|
||||
}
|
||||
}
|
||||
|
||||
static ret_t widget_set_visible_self(widget_t* widget, bool_t visible) {
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
|
||||
if (widget->visible != visible) {
|
||||
@ -220,7 +228,7 @@ ret_t widget_set_visible(widget_t* widget, bool_t visible) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t widget_set_visible_recursive(widget_t* widget, bool_t visible) {
|
||||
static ret_t widget_set_visible_recursive(widget_t* widget, bool_t visible) {
|
||||
uint32_t i = 0;
|
||||
uint32_t n = 0;
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
@ -236,6 +244,14 @@ ret_t widget_set_visible_recursive(widget_t* widget, bool_t visible) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
ret_t widget_set_visible(widget_t* widget, bool_t visible, bool_t recursive) {
|
||||
if (recursive) {
|
||||
return widget_set_visible_recursive(widget, visible);
|
||||
} else {
|
||||
return widget_set_visible_self(widget, visible);
|
||||
}
|
||||
}
|
||||
|
||||
widget_t* widget_find_target(widget_t* widget, xy_t x, xy_t y) {
|
||||
widget_t* ret = NULL;
|
||||
return_value_if_fail(widget != NULL, NULL);
|
||||
@ -266,7 +282,7 @@ ret_t widget_dispatch(widget_t* widget, event_t* e) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret_t widget_on(widget_t* widget, event_type_t type, event_handler on_event, void* ctx) {
|
||||
ret_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx) {
|
||||
return_value_if_fail(widget != NULL && on_event != NULL, RET_BAD_PARAMS);
|
||||
if (widget->emitter == NULL) {
|
||||
widget->emitter = emitter_create();
|
||||
@ -275,11 +291,18 @@ ret_t widget_on(widget_t* widget, event_type_t type, event_handler on_event, voi
|
||||
return emitter_on(widget->emitter, type, on_event, ctx);
|
||||
}
|
||||
|
||||
ret_t widget_off(widget_t* widget, event_type_t type, event_handler on_event, void* ctx) {
|
||||
ret_t widget_off(widget_t* widget, uint32_t id) {
|
||||
return_value_if_fail(widget != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(widget->emitter != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return emitter_off(widget->emitter, id);
|
||||
}
|
||||
|
||||
ret_t widget_off_by_func(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx) {
|
||||
return_value_if_fail(widget != NULL && on_event != NULL, RET_BAD_PARAMS);
|
||||
return_value_if_fail(widget->emitter != NULL, RET_BAD_PARAMS);
|
||||
|
||||
return emitter_off(widget->emitter, type, on_event, ctx);
|
||||
return emitter_off_by_func(widget->emitter, type, on_event, ctx);
|
||||
}
|
||||
|
||||
ret_t widget_paint(widget_t* widget, canvas_t* c) {
|
||||
@ -576,7 +599,7 @@ ret_t widget_destroy(widget_t* widget) {
|
||||
}
|
||||
|
||||
if (widget->children != NULL) {
|
||||
widget_remove_children(widget);
|
||||
widget_destroy_children(widget);
|
||||
array_destroy(widget->children);
|
||||
}
|
||||
|
||||
@ -615,11 +638,11 @@ ret_t widget_update_style(widget_t* widget) {
|
||||
state = widget->state;
|
||||
if (!widget->enable) {
|
||||
state = WIDGET_STATE_DISABLE;
|
||||
} else if (widget->selected) {
|
||||
state = WIDGET_STATE_SELECTED;
|
||||
} else if (widget->focused) {
|
||||
state = WIDGET_STATE_FOCUSED;
|
||||
}
|
||||
|
||||
widget->style.data = theme_find_style(default_theme(), widget->type, widget->subtype, state);
|
||||
widget->style.data = theme_find_style(theme_get_default(), widget->type, widget->subtype, state);
|
||||
|
||||
return RET_OK;
|
||||
}
|
||||
@ -642,7 +665,10 @@ widget_t* widget_init(widget_t* widget, widget_t* parent, uint8_t type) {
|
||||
if (!widget->vt) {
|
||||
widget->vt = widget_vtable_default();
|
||||
}
|
||||
widget_update_style(widget);
|
||||
|
||||
if(type != WIDGET_WINDOW_MANAGER) {
|
||||
widget_update_style(widget);
|
||||
}
|
||||
|
||||
return widget;
|
||||
}
|
||||
|
@ -31,21 +31,135 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
struct _widget_t;
|
||||
typedef struct _widget_t widget_t;
|
||||
|
||||
/**
|
||||
* @enum widget_state_t
|
||||
* @scriptable
|
||||
* 控件状态常量定义。
|
||||
*/
|
||||
typedef enum _widget_state_t {
|
||||
/**
|
||||
* @const WIDGET_STATE_NONE
|
||||
* 无效状态。
|
||||
*/
|
||||
WIDGET_STATE_NONE,
|
||||
/**
|
||||
* @const WIDGET_STATE_NORMAL
|
||||
* 正常状态。
|
||||
*/
|
||||
WIDGET_STATE_NORMAL,
|
||||
/**
|
||||
* @const WIDGET_STATE_PRESSED
|
||||
* 指针按下状态。
|
||||
*/
|
||||
WIDGET_STATE_PRESSED,
|
||||
/**
|
||||
* @const WIDGET_STATE_OVER
|
||||
* 指针悬浮状态。
|
||||
*/
|
||||
WIDGET_STATE_OVER,
|
||||
/**
|
||||
* @const WIDGET_STATE_DISABLE
|
||||
* 禁用状态。
|
||||
*/
|
||||
WIDGET_STATE_DISABLE,
|
||||
WIDGET_STATE_FOCUS,
|
||||
WIDGET_STATE_SELECTED,
|
||||
/**
|
||||
* @const WIDGET_STATE_FOCUSED
|
||||
* 聚焦状态。
|
||||
*/
|
||||
WIDGET_STATE_FOCUSED,
|
||||
/**
|
||||
* @const WIDGET_STATE_CHECKED
|
||||
* 勾选状态。
|
||||
*/
|
||||
WIDGET_STATE_CHECKED,
|
||||
/**
|
||||
* @const WIDGET_STATE_UNCHECKED
|
||||
* 没勾选状态。
|
||||
*/
|
||||
WIDGET_STATE_UNCHECKED
|
||||
}widget_state_t;
|
||||
|
||||
/**
|
||||
* @enum widget_type_t
|
||||
* @scriptable
|
||||
* 控件类型常量定义。
|
||||
*/
|
||||
typedef enum _widget_type_t {
|
||||
/**
|
||||
* @const WIDGET_NONE
|
||||
* 无效类型。
|
||||
*/
|
||||
WIDGET_NONE = 0,
|
||||
/**
|
||||
* @const WIDGET_WINDOW_MANAGER
|
||||
* 窗口管理器。
|
||||
*/
|
||||
WIDGET_WINDOW_MANAGER,
|
||||
/**
|
||||
* @const WIDGET_NORMAL_WINDOW
|
||||
* 窗口。
|
||||
*/
|
||||
WIDGET_NORMAL_WINDOW,
|
||||
/**
|
||||
* @const WIDGET_TOOLBAR
|
||||
* 工具条。
|
||||
*/
|
||||
WIDGET_TOOLBAR,
|
||||
/**
|
||||
* @const WIDGET_DIALOG
|
||||
* 对话框。
|
||||
*/
|
||||
WIDGET_DIALOG,
|
||||
/**
|
||||
* @const WIDGET_POPUP
|
||||
* 弹出框。
|
||||
*/
|
||||
WIDGET_POPUP,
|
||||
/**
|
||||
* @const WIDGET_LABEL
|
||||
* 简单文本。
|
||||
*/
|
||||
WIDGET_LABEL,
|
||||
/**
|
||||
* @const WIDGET_BUTTON
|
||||
* 按钮。
|
||||
*/
|
||||
WIDGET_BUTTON,
|
||||
/**
|
||||
* @const WIDGET_IMAGE
|
||||
* 图片。
|
||||
*/
|
||||
WIDGET_IMAGE,
|
||||
/**
|
||||
* @const WIDGET_EDIT
|
||||
* 文本编辑器。
|
||||
*/
|
||||
WIDGET_EDIT,
|
||||
/**
|
||||
* @const WIDGET_PROGRESS_BAR
|
||||
* 进度条。
|
||||
*/
|
||||
WIDGET_PROGRESS_BAR,
|
||||
/**
|
||||
* @const WIDGET_GROUP_BOX
|
||||
* 分组框。
|
||||
*/
|
||||
WIDGET_GROUP_BOX,
|
||||
/**
|
||||
* @const WIDGET_CHECK_BUTTON
|
||||
* 多选按钮。
|
||||
*/
|
||||
WIDGET_CHECK_BUTTON,
|
||||
/**
|
||||
* @const WIDGET_RADIO_BUTTON
|
||||
* 单选按钮。
|
||||
*/
|
||||
WIDGET_RADIO_BUTTON,
|
||||
}widget_type_t;
|
||||
|
||||
struct _widget_t;
|
||||
typedef struct _widget_t widget_t;
|
||||
|
||||
typedef ret_t (*widget_invalidate_t)(widget_t* widget, rect_t* r);
|
||||
typedef ret_t (*widget_on_event_t)(widget_t* widget, event_t* e);
|
||||
typedef ret_t (*widget_on_paint_self_t)(widget_t* widget, canvas_t* c);
|
||||
@ -82,93 +196,456 @@ typedef struct _widget_vtable_t {
|
||||
widget_destroy_t destroy;
|
||||
}widget_vtable_t;
|
||||
|
||||
enum {
|
||||
WIDGET_NONE = 0,
|
||||
WIDGET_WINDOW_MANAGER,
|
||||
WIDGET_NORMAL_WINDOW,
|
||||
WIDGET_TOOLBAR,
|
||||
WIDGET_DIALOG,
|
||||
WIDGET_POPUP,
|
||||
WIDGET_LABEL,
|
||||
WIDGET_BUTTON,
|
||||
WIDGET_IMAGE,
|
||||
WIDGET_EDIT,
|
||||
WIDGET_PROGRESS_BAR,
|
||||
WIDGET_GROUP_BOX,
|
||||
WIDGET_CHECK_BUTTON,
|
||||
WIDGET_RADIO_BUTTON,
|
||||
};
|
||||
|
||||
/**
|
||||
* @class widget_t
|
||||
* @scriptable
|
||||
* 窗口基类。
|
||||
*/
|
||||
struct _widget_t {
|
||||
/**
|
||||
* @property {xy_t} x
|
||||
* @readonly
|
||||
* x坐标。
|
||||
*/
|
||||
xy_t x;
|
||||
/**
|
||||
* @property {xy_t} y
|
||||
* @readonly
|
||||
* y坐标。
|
||||
*/
|
||||
xy_t y;
|
||||
/**
|
||||
* @property {wh_t} w
|
||||
* @readonly
|
||||
* 宽度。
|
||||
*/
|
||||
wh_t w;
|
||||
/**
|
||||
* @property {wh_t} h
|
||||
* @readonly
|
||||
* 高度。
|
||||
*/
|
||||
wh_t h;
|
||||
/**
|
||||
* @property {uint8_t} type
|
||||
* @readonly
|
||||
* 类型。
|
||||
*/
|
||||
uint8_t type;
|
||||
/**
|
||||
* @property {uint8_t} subtype
|
||||
* @readonly
|
||||
* 子类型,仅用于控制控件的Style。
|
||||
*/
|
||||
uint8_t subtype:4; /*for style*/
|
||||
/**
|
||||
* @property {uint8_t} state
|
||||
* @readonly
|
||||
* 控件的状态。
|
||||
*/
|
||||
uint8_t state:4;
|
||||
/**
|
||||
* @property {bool_t} enable
|
||||
* @readonly
|
||||
* 启用/禁用状态。
|
||||
*/
|
||||
uint8_t enable:1;
|
||||
/**
|
||||
* @property {bool_t} visible
|
||||
* @readonly
|
||||
* 是否可见。
|
||||
*/
|
||||
uint8_t visible:1;
|
||||
uint8_t selected:1;
|
||||
/**
|
||||
* @property {bool_t} focused
|
||||
* @readonly
|
||||
* 是否得到焦点。
|
||||
*/
|
||||
uint8_t focused:1;
|
||||
/**
|
||||
* @property {bool_t} initializing
|
||||
* @readonly
|
||||
* @scriptable no
|
||||
* 标识控件是否还在初始化中。
|
||||
*/
|
||||
uint8_t initializing:1;
|
||||
/**
|
||||
* @property {char*} name
|
||||
* @readonly
|
||||
* 控件名字
|
||||
*/
|
||||
char name[NAME_LEN+1];
|
||||
|
||||
style_t style;
|
||||
/**
|
||||
* @property {widget_t*} parent
|
||||
* @readonly
|
||||
* 父控件
|
||||
*/
|
||||
widget_t* parent;
|
||||
/**
|
||||
* @property {widget_t*} target
|
||||
* @readonly
|
||||
* @scriptable no
|
||||
* 接收事件的子控件。
|
||||
*/
|
||||
widget_t* target;
|
||||
/**
|
||||
* @property {array_t*} children
|
||||
* @readonly
|
||||
* @scriptable no
|
||||
* 全部子控件。
|
||||
*/
|
||||
array_t* children;
|
||||
/**
|
||||
* @property {emitter*} emitter
|
||||
* @private
|
||||
* 事件发射器。
|
||||
*/
|
||||
emitter_t* emitter;
|
||||
/**
|
||||
* @property {style_t} style
|
||||
* @private
|
||||
* Style数据。
|
||||
*/
|
||||
style_t style;
|
||||
/**
|
||||
* @property {widget_vtable_t} vt
|
||||
* @private
|
||||
* 虚函数表。
|
||||
*/
|
||||
const widget_vtable_t* vt;
|
||||
};
|
||||
|
||||
/**
|
||||
* @method widget_init
|
||||
* 初始化控件。仅在子类控件构造函数中使用。
|
||||
* @private
|
||||
* @param {widget_t*} widget widget对象。
|
||||
* @param {widget_t*} parent widget的父控件。
|
||||
* @param {uint8_t} type 控件的类型。
|
||||
*
|
||||
* @return {widget*} widget对象本身。
|
||||
*/
|
||||
widget_t* widget_init(widget_t* widget, widget_t* parent, uint8_t type);
|
||||
|
||||
/**
|
||||
* @method widget_update_style
|
||||
* 让控件根据自己当前状态更新style。
|
||||
* @private
|
||||
* @param {widget_t*} widget widget对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_update_style(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method widget_count_children
|
||||
* 获取子控件的个数。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
*
|
||||
* @return {uint32_t} 子控件的个数。
|
||||
*/
|
||||
uint32_t widget_count_children(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method widget_get_child
|
||||
* 获取指定索引的子控件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {uint32_t} index 索引
|
||||
*
|
||||
* @return {widget_t*} 子控件。
|
||||
*/
|
||||
widget_t* widget_get_child(widget_t* widget, uint32_t index);
|
||||
|
||||
/**
|
||||
* @method widget_move
|
||||
* 移动控件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_move(widget_t* widget, xy_t x, xy_t y);
|
||||
|
||||
/**
|
||||
* @method widget_resize
|
||||
* 调整控件的大小。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_resize(widget_t* widget, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method widget_move_resize
|
||||
* 移动控件并调整控件的大小。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_move_resize(widget_t* widget, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
/**
|
||||
* @method widget_set_value
|
||||
* 设置控件的值。只是对widget_set_prop的包装,值的意义由子类控件决定。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {uint32_t} value 值
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_value(widget_t* widget, uint32_t value);
|
||||
|
||||
/**
|
||||
* @method widget_set_text
|
||||
* 设置控件的文本。只是对widget_set_prop的包装,文本的意义由子类控件决定。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {wchar_t*} text 文本。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_text(widget_t* widget, const wchar_t* text);
|
||||
|
||||
/**
|
||||
* @method widget_get_value
|
||||
* 获取控件的值。只是对widget_get_prop的包装,值的意义由子类控件决定。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
*
|
||||
* @return {uint32_t} 返回值。
|
||||
*/
|
||||
uint32_t widget_get_value(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method widget_get_text
|
||||
* 获取控件的文本。只是对widget_get_prop的包装,文本的意义由子类控件决定。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
*
|
||||
* @return {wchar_t*} 返回文本。
|
||||
*/
|
||||
const wchar_t* widget_get_text(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method widget_to_local
|
||||
* 将全局坐标转换成控件内的本地坐标,即相对于控件左上角的坐标。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {point_t*} p 坐标点。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_to_local(widget_t* widget, point_t* p);
|
||||
|
||||
/**
|
||||
* @method widget_to_global
|
||||
* 将控件内的本地坐标转换成全局坐标。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {point_t*} p 坐标点。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_to_global(widget_t* widget, point_t* p);
|
||||
|
||||
/**
|
||||
* @method widget_set_name
|
||||
* 设置控件的名称。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {char*} name 名称。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_name(widget_t* widget, const char* name);
|
||||
|
||||
/**
|
||||
* @method widget_set_enable
|
||||
* 设置控件的可用性。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {bool_t} enable 是否启动。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_enable(widget_t* widget, bool_t enable);
|
||||
ret_t widget_set_selected(widget_t* widget, bool_t selected);
|
||||
|
||||
/**
|
||||
* @method widget_set_focused
|
||||
* 设置控件的是否聚焦。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {bool_t} focused 是否聚焦。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_focused(widget_t* widget, bool_t focused);
|
||||
|
||||
/**
|
||||
* @method widget_set_state
|
||||
* 设置控件的状态。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {widget_state_t} state 状态。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_state(widget_t* widget, widget_state_t state);
|
||||
|
||||
ret_t widget_remove_children(widget_t* widget);
|
||||
/**
|
||||
* @method widget_destroy_children
|
||||
* 销毁全部子控件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_destroy_children(widget_t* widget);
|
||||
|
||||
/**
|
||||
* @method widget_add_child
|
||||
* 加入一个子控件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {widget_t*} child 子控件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_add_child(widget_t* widget, widget_t* child);
|
||||
|
||||
/**
|
||||
* @method widget_remove_child
|
||||
* 移出指定的子控件(并不销毁)。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {widget_t*} child 子控件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_remove_child(widget_t* widget, widget_t* child);
|
||||
|
||||
/**
|
||||
* @method widget_find_target
|
||||
* 查找x/y坐标对应的子控件。
|
||||
* @private
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {xy_t} x x坐标。
|
||||
* @param {xy_t} y y坐标。
|
||||
*
|
||||
* @return {widget*} 子控件或NULL。
|
||||
*/
|
||||
widget_t* widget_find_target(widget_t* widget, xy_t x, xy_t y);
|
||||
widget_t* widget_lookup(widget_t* widget, const char* name);
|
||||
widget_t* widget_lookup_child(widget_t* widget, const char* name);
|
||||
|
||||
ret_t widget_set_visible(widget_t* widget, bool_t visible);
|
||||
ret_t widget_set_visible_recursive(widget_t* widget, bool_t visible);
|
||||
/**
|
||||
* @method widget_lookup
|
||||
* 查找指定名称的子控件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {char*} name 子控件的名称。
|
||||
* @param {bool_t} recursive 是否递归查找全部子控件。
|
||||
*
|
||||
* @return {widget_t*} 子控件或NULL。
|
||||
*/
|
||||
widget_t* widget_lookup(widget_t* widget, const char* name, bool_t recursive);
|
||||
|
||||
ret_t widget_dispatch(widget_t* widget, event_t* e);
|
||||
ret_t widget_on(widget_t* widget, event_type_t type, event_handler on_event, void* ctx);
|
||||
ret_t widget_off(widget_t* widget, event_type_t type, event_handler on_event, void* ctx);
|
||||
/**
|
||||
* @method widget_set_visible
|
||||
* 设置控件的可见性。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {bool_t} visible 是否可见。
|
||||
* @param {bool_t} recursive 是否递归设置全部子控件。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_visible(widget_t* widget, bool_t visible, bool_t recursive);
|
||||
|
||||
ret_t widget_paint(widget_t* widget, canvas_t* c);
|
||||
/**
|
||||
* @method widget_on
|
||||
* 注册指定事件的处理函数。
|
||||
* @scriptable custom
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {event_type_t} type 事件类型。
|
||||
* @param {event_func_t} on_event 事件处理函数。
|
||||
* @param {void*} ctx 事件处理函数上下文。
|
||||
*
|
||||
* @return {uint32_t} 返回id,用于widget_off。
|
||||
*/
|
||||
uint32_t widget_on(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx);
|
||||
|
||||
/**
|
||||
* @method widget_off
|
||||
* 注销指定事件的处理函数。
|
||||
* @scriptable custom
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {uint32_t} id widget_on返回的ID。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_off(widget_t* widget, uint32_t id);
|
||||
|
||||
/**
|
||||
* @method widget_off_by_func
|
||||
* 注销指定事件的处理函数。
|
||||
* @scriptable no
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {event_type_t} type 事件类型。
|
||||
* @param {event_func_t} on_event 事件处理函数。
|
||||
* @param {void*} ctx 事件处理函数上下文。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_off_by_func(widget_t* widget, event_type_t type, event_func_t on_event, void* ctx);
|
||||
|
||||
/**
|
||||
* @method widget_invalidate
|
||||
* 请求重绘指定的区域。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {rect_t*} r 矩形对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_invalidate(widget_t* widget, rect_t* r);
|
||||
|
||||
/*virtual functions wrapper*/
|
||||
/**
|
||||
* @method widget_paint
|
||||
* 绘制控件到一个canvas上。
|
||||
* @private
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {canvas_t*} c 画布对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_paint(widget_t* widget, canvas_t* c);
|
||||
|
||||
/**
|
||||
* @method widget_dispatch
|
||||
* 分发一个事件。
|
||||
* @private
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {event_t*} e 事件。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_dispatch(widget_t* widget, event_t* e);
|
||||
|
||||
ret_t widget_on_paint_self(widget_t* widget, canvas_t* c);
|
||||
ret_t widget_on_paint_children(widget_t* widget, canvas_t* c);
|
||||
|
||||
/**
|
||||
* @method widget_get_prop
|
||||
* 通用的获取控件属性的函数。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {char*} name 属性的名称。
|
||||
* @param {value_t*} v 属性的值。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_get_prop(widget_t* widget, const char* name, value_t* v);
|
||||
|
||||
/**
|
||||
* @method widget_set_prop
|
||||
* 通用的设置控件属性的函数。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {char*} name 属性的名称。
|
||||
* @param {value_t*} v 属性的值。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_set_prop(widget_t* widget, const char* name, const value_t* v);
|
||||
|
||||
ret_t widget_on_paint(widget_t* widget, canvas_t* c);
|
||||
ret_t widget_on_keydown(widget_t* widget, key_event_t* e);
|
||||
ret_t widget_on_keyup(widget_t* widget, key_event_t* e);
|
||||
@ -176,8 +653,34 @@ ret_t widget_on_click(widget_t* widget, pointer_event_t* e);
|
||||
ret_t widget_on_pointer_down(widget_t* widget, pointer_event_t* e);
|
||||
ret_t widget_on_pointer_move(widget_t* widget, pointer_event_t* e);
|
||||
ret_t widget_on_pointer_up(widget_t* widget, pointer_event_t* e);
|
||||
|
||||
/**
|
||||
* @method widget_grab
|
||||
* 让指定子控件抓住事件。抓住之后,事件由窗口直接分发给该控件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {widget_t*} child 子控件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_grab(widget_t* widget, widget_t* child);
|
||||
|
||||
/**
|
||||
* @method widget_ungrab
|
||||
* 让指定子控件放弃抓住事件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
* @param {widget_t*} child 子控件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_ungrab(widget_t* widget, widget_t* child);
|
||||
|
||||
/**
|
||||
* @method widget_destroy
|
||||
* 销毁控件。
|
||||
* @param {widget_t*} widget 控件对象。
|
||||
*
|
||||
* @return {ret_t} 返回RET_OK表示成功,否则表示失败。
|
||||
*/
|
||||
ret_t widget_destroy(widget_t* widget);
|
||||
|
||||
#define WIDGET(w) (&(w.widget))
|
||||
|
@ -27,7 +27,7 @@ static ret_t window_on_paint_self(widget_t* widget, canvas_t* c) {
|
||||
style_t* style = &(widget->style);
|
||||
color_t color = color_init(0xe9, 0xe9, 0xe9, 0xff);
|
||||
|
||||
canvas_set_fill_color(c, style_get_color(style, E_BG_COLOR, color));
|
||||
canvas_set_fill_color(c, style_get_color(style, STYLE_ID_BG_COLOR, color));
|
||||
canvas_fill_rect(c, widget->x, widget->y, widget->w, widget->h);
|
||||
|
||||
return RET_OK;
|
||||
|
@ -26,10 +26,28 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class window_t
|
||||
* @parent widget_t
|
||||
* @scriptable
|
||||
* 窗口。
|
||||
*/
|
||||
typedef struct _window_t {
|
||||
widget_t widget;
|
||||
}window_t;
|
||||
|
||||
/**
|
||||
* @method window_create
|
||||
* @constructor
|
||||
* 创建window对象
|
||||
* @param {widget_t*} parent 父控件
|
||||
* @param {xy_t} x x坐标
|
||||
* @param {xy_t} y y坐标
|
||||
* @param {wh_t} w 宽度
|
||||
* @param {wh_t} h 高度
|
||||
*
|
||||
* @return {widget_t*} 对象。
|
||||
*/
|
||||
widget_t* window_create(widget_t* parent, xy_t x, xy_t y, wh_t w, wh_t h);
|
||||
|
||||
END_C_DECLS
|
||||
|
@ -26,6 +26,11 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
/**
|
||||
* @class window_manager_t
|
||||
* @parent widget_t
|
||||
* 窗口管理器。
|
||||
*/
|
||||
typedef struct _window_manager_t {
|
||||
widget_t widget;
|
||||
|
||||
|
@ -163,7 +163,7 @@ rt_bool_t on_event(struct rtgui_object* object, rtgui_event_t* event) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
main_loop_t* main_loop_rtthread_init(int w, int h) {
|
||||
main_loop_t* main_loop_init(int w, int h) {
|
||||
lcd_t* lcd = NULL;
|
||||
widget_t* wm = default_wm();
|
||||
main_loop_t* base = &(loop.base);
|
||||
@ -194,4 +194,4 @@ main_loop_t* main_loop_rtthread_init(int w, int h) {
|
||||
return base;
|
||||
}
|
||||
|
||||
main_loop_t* default_main_loop() { return &loop.base; }
|
||||
main_loop_t* main_loop_get_default() { return &loop.base; }
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
main_loop_t* main_loop_rtthread_init(int w, int h);
|
||||
main_loop_t* main_loop_init(int w, int h);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
|
@ -197,7 +197,7 @@ static ret_t main_loop_sdl2_create_window(main_loop_sdl2_t* l, font_manager_t* f
|
||||
}
|
||||
|
||||
static main_loop_sdl2_t loop;
|
||||
main_loop_t* main_loop_sdl2_init(int w, int h) {
|
||||
main_loop_t* main_loop_init(int w, int h) {
|
||||
widget_t* wm = default_wm();
|
||||
font_manager_t* fm = default_fm();
|
||||
main_loop_t* base = &(loop.base);
|
||||
@ -215,4 +215,4 @@ main_loop_t* main_loop_sdl2_init(int w, int h) {
|
||||
return base;
|
||||
}
|
||||
|
||||
main_loop_t* default_main_loop() { return &loop.base; }
|
||||
main_loop_t* main_loop_get_default() { return &loop.base; }
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
main_loop_t* main_loop_sdl2_init(int w, int h);
|
||||
main_loop_t* main_loop_init(int w, int h);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
|
@ -132,7 +132,7 @@ static ret_t main_loop_stm32_raw_destroy(main_loop_t* l) {
|
||||
return RET_OK;
|
||||
}
|
||||
|
||||
main_loop_t* main_loop_stm32_raw_init(int w, int h) {
|
||||
main_loop_t* main_loop_init(int w, int h) {
|
||||
lcd_t* lcd = NULL;
|
||||
widget_t* wm = default_wm();
|
||||
main_loop_t* base = &(loop.base);
|
||||
@ -152,4 +152,4 @@ main_loop_t* main_loop_stm32_raw_init(int w, int h) {
|
||||
return base;
|
||||
}
|
||||
|
||||
main_loop_t* default_main_loop() { return &loop.base; }
|
||||
main_loop_t* main_loop_get_default() { return &loop.base; }
|
||||
|
@ -26,7 +26,7 @@
|
||||
|
||||
BEGIN_C_DECLS
|
||||
|
||||
main_loop_t* main_loop_stm32_raw_init(int w, int h);
|
||||
main_loop_t* main_loop_init(int w, int h);
|
||||
|
||||
END_C_DECLS
|
||||
|
||||
|
@ -68,7 +68,7 @@ static ret_t ui_builder_default_on_widget_start(ui_builder_t* b, uint16_t type,
|
||||
widget = check_button_create(parent, x, y, w, h);
|
||||
break;
|
||||
case WIDGET_RADIO_BUTTON:
|
||||
widget = radio_button_create(parent, x, y, w, h);
|
||||
widget = check_button_create_radio(parent, x, y, w, h);
|
||||
break;
|
||||
default:
|
||||
log_debug("%s: not supported type %d\n", __func__, type);
|
||||
|
@ -11,9 +11,9 @@ TEST(Button, basic) {
|
||||
value_t v2;
|
||||
widget_t* b = button_create(NULL, 10, 20, 30, 40);
|
||||
|
||||
ASSERT_EQ(button_set_text(b, L"OK"), RET_OK);
|
||||
ASSERT_EQ(widget_set_text(b, L"OK"), RET_OK);
|
||||
ASSERT_EQ(wcscmp(BUTTON(b)->text.str, L"OK"), 0);
|
||||
ASSERT_EQ(button_set_text(b, L"Cancel"), RET_OK);
|
||||
ASSERT_EQ(widget_set_text(b, L"Cancel"), RET_OK);
|
||||
ASSERT_EQ(wcscmp(BUTTON(b)->text.str, L"Cancel"), 0);
|
||||
|
||||
value_set_wstr(&v1, L"button");
|
||||
|
@ -1,3 +1,3 @@
|
||||
#include "base/main_loop.h"
|
||||
|
||||
main_loop_t* default_main_loop() { return NULL; }
|
||||
main_loop_t* main_loop_get_default() { return NULL; }
|
||||
|
@ -29,7 +29,7 @@ TEST(Emitter, basic) {
|
||||
ASSERT_EQ(emitter_dispatch(&emitter, &e), RET_OK);
|
||||
ASSERT_EQ(n, 1);
|
||||
|
||||
ASSERT_EQ(emitter_off(&emitter, type, on_event, &n), RET_OK);
|
||||
ASSERT_EQ(emitter_off_by_func(&emitter, type, on_event, &n), RET_OK);
|
||||
ASSERT_EQ(emitter_dispatch(&emitter, &e), RET_OK);
|
||||
ASSERT_EQ(n, 1);
|
||||
|
||||
|
@ -22,15 +22,15 @@ TEST(ThemeGen, basic) {
|
||||
|
||||
style.data = theme_find_style(&theme, WIDGET_NONE, 0, WIDGET_STATE_NORMAL);
|
||||
ASSERT_EQ(style.data != NULL, true);
|
||||
ASSERT_EQ(style_get_int(&style, E_FONT_SIZE, 0), 12);
|
||||
ASSERT_EQ(style_get_int(&style, E_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, E_FG_COLOR, 0), 0xfffcfbfa);
|
||||
ASSERT_EQ(style_get_str(&style, E_FONT_NAME, ""), string("sans"));
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_FONT_SIZE, 0), 12);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_FG_COLOR, 0), 0xfffcfbfa);
|
||||
ASSERT_EQ(style_get_str(&style, STYLE_ID_FONT_NAME, ""), string("sans"));
|
||||
|
||||
style.data = theme_find_style(&theme, WIDGET_PROGRESS_BAR, 0, WIDGET_STATE_NORMAL);
|
||||
ASSERT_EQ(style.data != NULL, true);
|
||||
ASSERT_EQ(style_get_int(&style, E_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, E_FG_COLOR, 0), 0x7f00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_FG_COLOR, 0), 0x7f00ffff);
|
||||
}
|
||||
|
||||
TEST(ThemeGen, state) {
|
||||
@ -46,13 +46,13 @@ TEST(ThemeGen, state) {
|
||||
|
||||
style.data = theme_find_style(&theme, WIDGET_BUTTON, 0, WIDGET_STATE_OVER);
|
||||
ASSERT_EQ(style.data != NULL, true);
|
||||
ASSERT_EQ(style_get_int(&style, E_FONT_SIZE, 0), 12);
|
||||
ASSERT_EQ(style_get_int(&style, E_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, E_FG_COLOR, 0), 0xfffcfbfa);
|
||||
ASSERT_EQ(style_get_str(&style, E_FONT_NAME, ""), string("sans"));
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_FONT_SIZE, 0), 12);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_FG_COLOR, 0), 0xfffcfbfa);
|
||||
ASSERT_EQ(style_get_str(&style, STYLE_ID_FONT_NAME, ""), string("sans"));
|
||||
|
||||
style.data = theme_find_style(&theme, WIDGET_BUTTON, 0, WIDGET_STATE_PRESSED);
|
||||
ASSERT_EQ(style.data != NULL, true);
|
||||
ASSERT_EQ(style_get_int(&style, E_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, E_FG_COLOR, 0), 0x7f00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_BG_COLOR, 0), 0xff00ffff);
|
||||
ASSERT_EQ(style_get_int(&style, STYLE_ID_FG_COLOR, 0), 0x7f00ffff);
|
||||
}
|
||||
|
@ -35,8 +35,8 @@ TEST(UILoader, basic) {
|
||||
ASSERT_EQ(builder->root->type == WIDGET_DIALOG, TRUE);
|
||||
ASSERT_EQ(widget_count_children(builder->root), 1);
|
||||
|
||||
ok = widget_lookup(builder->root, "ok");
|
||||
cancel = widget_lookup(builder->root, "cancel");
|
||||
ok = widget_lookup(builder->root, "ok", TRUE);
|
||||
cancel = widget_lookup(builder->root, "cancel", TRUE);
|
||||
|
||||
ASSERT_EQ(ok != NULL, true);
|
||||
ASSERT_EQ(ok->type == WIDGET_BUTTON, true);
|
||||
|
@ -20,8 +20,8 @@ TEST(UILoaderXML, basic) {
|
||||
ASSERT_EQ(builder->root->type == WIDGET_DIALOG, TRUE);
|
||||
ASSERT_EQ(widget_count_children(builder->root), 1);
|
||||
|
||||
ok = widget_lookup(builder->root, "ok");
|
||||
cancel = widget_lookup(builder->root, "cancel");
|
||||
ok = widget_lookup(builder->root, "ok", TRUE);
|
||||
cancel = widget_lookup(builder->root, "cancel", TRUE);
|
||||
|
||||
ASSERT_EQ(ok != NULL, true);
|
||||
ASSERT_EQ(ok->type == WIDGET_BUTTON, true);
|
||||
|
@ -29,17 +29,14 @@ TEST(Widget, moveresize) {
|
||||
ASSERT_EQ(widget_set_enable(&w, FALSE), RET_OK);
|
||||
ASSERT_EQ(w.enable, FALSE);
|
||||
|
||||
ASSERT_EQ(widget_set_visible(&w, TRUE), RET_OK);
|
||||
ASSERT_EQ(widget_set_visible(&w, TRUE, TRUE), RET_OK);
|
||||
ASSERT_EQ(w.visible, TRUE);
|
||||
|
||||
ASSERT_EQ(widget_set_visible(&w, FALSE), RET_OK);
|
||||
ASSERT_EQ(widget_set_visible(&w, FALSE, TRUE), RET_OK);
|
||||
ASSERT_EQ(w.visible, FALSE);
|
||||
|
||||
ASSERT_EQ(widget_set_selected(&w, TRUE), RET_OK);
|
||||
ASSERT_EQ(w.selected, TRUE);
|
||||
|
||||
ASSERT_EQ(widget_set_selected(&w, FALSE), RET_OK);
|
||||
ASSERT_EQ(w.selected, FALSE);
|
||||
ASSERT_EQ(widget_set_focused(&w, FALSE), RET_OK);
|
||||
ASSERT_EQ(w.focused, FALSE);
|
||||
}
|
||||
|
||||
TEST(Widget, props) {
|
||||
@ -121,17 +118,17 @@ TEST(Widget, children) {
|
||||
ASSERT_EQ(widget_set_name(&c6, "c6"), RET_OK);
|
||||
ASSERT_EQ(widget_set_name(&group, "group"), RET_OK);
|
||||
|
||||
ASSERT_EQ(widget_lookup_child(&w, "c1"), &c1);
|
||||
ASSERT_EQ(widget_lookup_child(&w, "c2"), &c2);
|
||||
ASSERT_EQ(widget_lookup_child(&w, "c3"), &c3);
|
||||
ASSERT_EQ(widget_lookup(&w, "c1", FALSE), &c1);
|
||||
ASSERT_EQ(widget_lookup(&w, "c2", FALSE), &c2);
|
||||
ASSERT_EQ(widget_lookup(&w, "c3", FALSE), &c3);
|
||||
|
||||
ASSERT_EQ(widget_lookup(&w, "c1"), &c1);
|
||||
ASSERT_EQ(widget_lookup(&w, "c2"), &c2);
|
||||
ASSERT_EQ(widget_lookup(&w, "c3"), &c3);
|
||||
ASSERT_EQ(widget_lookup(&w, "c1", TRUE), &c1);
|
||||
ASSERT_EQ(widget_lookup(&w, "c2", TRUE), &c2);
|
||||
ASSERT_EQ(widget_lookup(&w, "c3", TRUE), &c3);
|
||||
|
||||
ASSERT_EQ(widget_lookup(&w, "c4"), &c4);
|
||||
ASSERT_EQ(widget_lookup(&w, "c5"), &c5);
|
||||
ASSERT_EQ(widget_lookup(&w, "c6"), &c6);
|
||||
ASSERT_EQ(widget_lookup(&w, "c4", TRUE), &c4);
|
||||
ASSERT_EQ(widget_lookup(&w, "c5", TRUE), &c5);
|
||||
ASSERT_EQ(widget_lookup(&w, "c6", TRUE), &c6);
|
||||
|
||||
widget_move_resize(&c1, 10, 10, 20, 20);
|
||||
ASSERT_EQ(widget_find_target(&w, 11, 11), &c1);
|
||||
|
20
tools/idl_gen/.vscode/launch.json
vendored
Normal file
20
tools/idl_gen/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
// 使用 IntelliSense 了解相关属性。
|
||||
// 悬停以查看现有属性的描述。
|
||||
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch gen_lua",
|
||||
"program": "${workspaceFolder}/gen_lua.js"
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "launch",
|
||||
"name": "Launch gen_idl",
|
||||
"program": "${workspaceFolder}/gen_idl.js"
|
||||
}
|
||||
]
|
||||
}
|
@ -50,6 +50,10 @@ function parseProperty(comment) {
|
||||
property.name = arr[3];
|
||||
} else if (iter.indexOf('@readonly') >= 0) {
|
||||
property.readonly = true;
|
||||
} else if (iter.indexOf(' @private') >= 0) {
|
||||
property.isPrivate = true;
|
||||
} else if (iter.indexOf(' @scriptable') >= 0 && iter.indexOf('no') >= 0) {
|
||||
property.isPrivate = true;
|
||||
}
|
||||
});
|
||||
|
||||
@ -68,6 +72,14 @@ function parseMethod(comment) {
|
||||
method.isDeconstructor = true;
|
||||
} else if (iter.indexOf(' @constructor') >= 0) {
|
||||
method.isConstructor = true;
|
||||
} else if (iter.indexOf(' @global') >= 0) {
|
||||
method.isGlobal = true;
|
||||
} else if (iter.indexOf(' @private') >= 0) {
|
||||
method.isPrivate = true;
|
||||
} else if (iter.indexOf(' @scriptable') >= 0 && iter.indexOf('no') >= 0) {
|
||||
method.isPrivate = true;
|
||||
} else if (iter.indexOf(' @scriptable') >= 0 && iter.indexOf('custom') >= 0) {
|
||||
method.isCustom = true;
|
||||
} else if (iter.indexOf(' @param') >= 0) {
|
||||
const param = {};
|
||||
const arr = parseTokens(iter);
|
||||
@ -105,9 +117,21 @@ function extractIDL(result, filename, content) {
|
||||
cls.properties = [];
|
||||
cls.header = filename;
|
||||
} else if (comment.indexOf(' @method') >= 0) {
|
||||
cls.methods.push(parseMethod(comment));
|
||||
const m = parseMethod(comment);
|
||||
if (m && !m.isPrivate) {
|
||||
if (m.isGlobal) {
|
||||
m.type = 'method';
|
||||
m.header = filename;
|
||||
result.push(m);
|
||||
} else {
|
||||
cls.methods.push(m);
|
||||
}
|
||||
}
|
||||
} else if (comment.indexOf(' @property') >= 0) {
|
||||
cls.properties.push(parseProperty(comment));
|
||||
const p = parseProperty(comment);
|
||||
if (p && !p.isPrivate) {
|
||||
cls.properties.push(p);
|
||||
}
|
||||
} else if (comment.indexOf(' @const') >= 0) {
|
||||
cls.consts.push(parseConst(comment));
|
||||
} else if (comment.indexOf(' @enum') >= 0) {
|
||||
@ -129,13 +153,14 @@ function extractIDL(result, filename, content) {
|
||||
|
||||
function genOneFile(result, filename) {
|
||||
const content = fs.readFileSync(filename).toString();
|
||||
const name = filename.match(/[a-z|_\d|\.|A-Z]*\/[a-z|_\d|\.|A-Z]*$/);
|
||||
const name = filename.match(/[a-z|_\d|\.|A-Z]*\/[a-z|_\d|\.|A-Z]*$/)[0];
|
||||
console.log(filename);
|
||||
extractIDL(result, name, content);
|
||||
}
|
||||
|
||||
function genAll() {
|
||||
const result = [];
|
||||
glob('../../src/**/value.h', null, function (er, files) {
|
||||
glob('../../src/**/*.h', null, function (er, files) {
|
||||
files.forEach(iter => {
|
||||
genOneFile(result, iter);
|
||||
});
|
||||
@ -144,4 +169,4 @@ function genAll() {
|
||||
})
|
||||
}
|
||||
|
||||
genAll();
|
||||
genAll();
|
||||
|
@ -1,7 +1,27 @@
|
||||
const fs = require('fs');
|
||||
|
||||
/*https://www.codingnow.com/2000/download/lua_manual.html*/
|
||||
/*http://book.luaer.cn/_3.htm*/
|
||||
/**
|
||||
* Ref:
|
||||
* https://www.codingnow.com/2000/download/lua_manual.html
|
||||
* http://book.luaer.cn/_3.htm
|
||||
* http://www.cnblogs.com/luweimy/p/3972353.html
|
||||
*/
|
||||
|
||||
const builtin = `#include "custom.c"\n\n`;
|
||||
|
||||
function toLuaClassName(name) {
|
||||
name = name.replace(/_t$/, '');
|
||||
name = name.replace(/(^|_)[a-z]/g, r => {
|
||||
if(r.length > 1) {
|
||||
r = r.substr(1);
|
||||
}
|
||||
|
||||
return r.toUpperCase();
|
||||
});
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
function genDecl(index, type, name) {
|
||||
let str = '';
|
||||
str += ` ${type} ${name} = `;
|
||||
@ -13,18 +33,27 @@ function genDecl(index, type, name) {
|
||||
}
|
||||
} else {
|
||||
if (type.indexOf('char*') >= 0) {
|
||||
str += `(${type})luaL_checkstring(L,${index+1});\n`;
|
||||
str += `(${type})luaL_checkstring(L, ${index+1});\n`;
|
||||
} else if (type.indexOf('wchar_t*') >= 0) {
|
||||
str += `(${type})lua_touserdata(L, ${index+1});\n`;
|
||||
} else if (type.indexOf('void*') >= 0) {
|
||||
if(name !== 'ctx') {
|
||||
str += `(${type})lua_touserdata(L, ${index+1});\n`;
|
||||
} else {
|
||||
str += ' NULL;\n';
|
||||
}
|
||||
} else if (type.indexOf('*') >= 0) {
|
||||
const type_name = type.replace(/\*/g, '');
|
||||
str += `(${type})luaL_checkudata(L, ${index+1}, "lftk.${type_name}");\n`;
|
||||
} else if (type.indexOf('int') >= 0) {
|
||||
str += `(${type})luaL_checkinteger(L,${index+1});\n`;
|
||||
str += `(${type})lftk_checkudata(L, ${index+1}, "lftk.${type_name}");\n`;
|
||||
} else if (type.indexOf('float') >= 0 || type.indexOf('double') >= 0) {
|
||||
str += `(${type})luaL_checknumber(L, ${index+1});\n`;
|
||||
} else if (type.indexOf('bool_t') >= 0) {
|
||||
str += `(${type})lua_toboolean(L, ${index+1});\n`;
|
||||
} else if (type.indexOf('func_t') >= 0) {
|
||||
str += `(${type})lua_tocfunction(L, ${index+1});\n`;
|
||||
} else {
|
||||
str += `(${type})luaL_checknumber(L,${index+1});\n`;
|
||||
str += `(${type})luaL_checkinteger(L, ${index+1});\n`;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return str;
|
||||
@ -47,6 +76,8 @@ function genReturnData(type, name) {
|
||||
let str = '';
|
||||
if (type.indexOf('char*') >= 0) {
|
||||
str = ` lua_pushstring(L,(char*)(${name}));\n`;
|
||||
} else if (type.indexOf('wchar_t*') >= 0) {
|
||||
str = ` lua_pushlightuserdata(L,(void*)(${name}));\n`;
|
||||
} else if (type.indexOf('*') >= 0) {
|
||||
str = ` lua_pushlightuserdata(L,(void*)(${name}));\n`;
|
||||
} else if (type.indexOf('int') >= 0) {
|
||||
@ -60,10 +91,10 @@ function genReturnData(type, name) {
|
||||
return str;
|
||||
}
|
||||
|
||||
function genMethodCall(cls, m) {
|
||||
function genCallMethod(cls, m) {
|
||||
const ret_type = m.return;
|
||||
let str = ret_type == 'void' ? ' ' : ' ret = '
|
||||
str += `${m.name}(`;
|
||||
str += `(${ret_type})${m.name}(`;
|
||||
m.params.forEach((iter, index) => {
|
||||
if (index > 0) {
|
||||
str += ', ' + iter.name;
|
||||
@ -79,13 +110,14 @@ function genMethodCall(cls, m) {
|
||||
str += ' return 0;\n';
|
||||
} else {
|
||||
str += genReturnData(ret_type, 'ret');
|
||||
if (m.constructor) {
|
||||
if (m.isConstructor) {
|
||||
str += ` luaL_getmetatable(L, "lftk.${cls.name}");\n`;
|
||||
str += ` lua_setmetatable(L, -2);\n`;
|
||||
}
|
||||
str += '\n';
|
||||
str += ' return 1;\n';
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
@ -93,7 +125,7 @@ function genMethod(cls, m) {
|
||||
const args_nr = m.params.length;
|
||||
let str = `static int wrap_${m.name}(lua_State* L) {\n`;
|
||||
str += genParamsDecl(m);
|
||||
str += genMethodCall(cls, m);
|
||||
str += genCallMethod(cls, m);
|
||||
str += '}\n\n';
|
||||
|
||||
return str;
|
||||
@ -109,6 +141,7 @@ function genSetProperty(index, cls, p) {
|
||||
str += ' ';
|
||||
if (p.readonly) {
|
||||
str += ` printf("${p.name} is readonly\\n");\n`;
|
||||
str += ` return 0;\n`;
|
||||
} else {
|
||||
str += genDecl(2, p.type, p.name);
|
||||
str += ` obj->${p.name} = ${p.name};\n`;
|
||||
@ -127,6 +160,7 @@ function genGetProperty(index, cls, p) {
|
||||
}
|
||||
str += ' ';
|
||||
str += genReturnData(p.type, `obj->${p.name}`);
|
||||
str += ' return 1;\n';
|
||||
str += ' }\n';
|
||||
|
||||
return str;
|
||||
@ -136,43 +170,80 @@ function methodToShortName(clsName, methodName) {
|
||||
return methodName.replace(clsName.replace(/_t$/, '') + "_", '')
|
||||
}
|
||||
|
||||
function genClass(cls) {
|
||||
function genSetProp(cls) {
|
||||
let str = '';
|
||||
const clsName = cls.name;
|
||||
|
||||
cls.methods.forEach(m => {
|
||||
str += genMethod(cls, m);
|
||||
str += `static int wrap_${clsName}_set_prop(lua_State* L) {\n`;
|
||||
str += genDecl(0, cls.name + '*', "obj");
|
||||
str += genDecl(1, "const char*", "name");
|
||||
str += '(void)obj;\n';
|
||||
str += '(void)name;\n';
|
||||
|
||||
let hasSetProps = false;
|
||||
cls.properties.forEach((m, index) => {
|
||||
str += genSetProperty(index, cls, m);
|
||||
hasSetProps = true;
|
||||
});
|
||||
|
||||
if (cls.properties.length > 0) {
|
||||
str += `static int wrap_${clsName}_set_prop(lua_State* L) {\n`;
|
||||
str += genDecl(0, cls.name + '*', "obj");
|
||||
str += genDecl(1, "const char*", "name");
|
||||
|
||||
cls.properties.forEach((m, index) => {
|
||||
str += genSetProperty(index, cls, m);
|
||||
});
|
||||
str += ` else {\n`;
|
||||
str += ` printf("not supported %s\\n", name);\n`;
|
||||
str += ` }\n`;
|
||||
|
||||
str += ` return 0;\n`;
|
||||
str += `}\n`;
|
||||
|
||||
str += `static int wrap_${clsName}_get_prop(lua_State* L) {\n`;
|
||||
str += genDecl(0, cls.name + '*', "obj");
|
||||
str += genDecl(1, "const char*", "name");
|
||||
|
||||
cls.properties.forEach((m, index) => {
|
||||
str += genGetProperty(index, cls, m);
|
||||
});
|
||||
|
||||
str += ` else {\n`;
|
||||
str += ` printf("not supported %s\\n", name);\n`;
|
||||
str += ` }\n`;
|
||||
str += ` return 1;\n`;
|
||||
str += `}\n`;
|
||||
if (hasSetProps) {
|
||||
str += ` else {\n `;
|
||||
}
|
||||
if (cls.parent) {
|
||||
str += ` return wrap_${cls.parent}_set_prop(L);\n`;
|
||||
} else if (hasSetProps) {
|
||||
str += ` printf("%s: not supported %s\\n", __func__, name);\n`;
|
||||
str += ` return 0;\n`;
|
||||
}
|
||||
if (hasSetProps) {
|
||||
str += ` }\n`;
|
||||
} else {
|
||||
str += ` printf("%s: not supported %s\\n", __func__, name);\n`;
|
||||
str += ` return 0;\n`;
|
||||
}
|
||||
|
||||
str += `}\n\n`;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function genGetProp(cls) {
|
||||
let str = '';
|
||||
const clsName = cls.name;
|
||||
|
||||
str += `static int wrap_${clsName}_get_prop(lua_State* L) {\n`;
|
||||
str += genDecl(0, cls.name + '*', "obj");
|
||||
str += genDecl(1, "const char*", "name");
|
||||
str += ` const luaL_Reg* ret = find_member(${cls.name}_member_funcs, name);\n\n`;
|
||||
|
||||
str += ' (void)obj;\n';
|
||||
str += ' (void)name;\n';
|
||||
str += ' if(ret) {\n';
|
||||
str += ' lua_pushcfunction(L, ret->func);\n';
|
||||
str += ' return 1;\n';
|
||||
str += ' }\n';
|
||||
|
||||
cls.properties.forEach((m, index) => {
|
||||
str += genGetProperty(index, cls, m);
|
||||
});
|
||||
|
||||
str += ` else {\n`;
|
||||
if (cls.parent) {
|
||||
str += ` return wrap_${cls.parent}_get_prop(L);\n`;
|
||||
} else {
|
||||
str += ` printf("%s: not supported %s\\n", __func__, name);\n`;
|
||||
str += ` return 1;\n`;
|
||||
}
|
||||
str += ` }\n`;
|
||||
|
||||
str += `}\n\n`;
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function genClassInit(cls) {
|
||||
let str = '';
|
||||
const clsName = cls.name;
|
||||
|
||||
str += `static void ${cls.name}_init(lua_State* L) {\n`;
|
||||
str += ' static const struct luaL_Reg static_funcs[] = {\n'
|
||||
@ -184,42 +255,77 @@ function genClass(cls) {
|
||||
});
|
||||
|
||||
str += ` {NULL, NULL}\n`;
|
||||
str += ' };\n'
|
||||
|
||||
str += ' static const struct luaL_Reg member_funcs[] = {\n'
|
||||
cls.methods.forEach(m => {
|
||||
const name = methodToShortName(cls.name, m.name);
|
||||
if (!m.isConstructor) {
|
||||
str += ` {"${name}", wrap_${m.name}},\n`;
|
||||
}
|
||||
});
|
||||
if (cls.properties.length > 0) {
|
||||
str += ` {"_set", wrap_${clsName}_set_prop},\n`;
|
||||
str += ` {"_get", wrap_${clsName}_get_prop},\n`;
|
||||
}
|
||||
str += ' };\n\n'
|
||||
|
||||
str += ' static const struct luaL_Reg index_funcs[] = {\n'
|
||||
str += ` {"__index", wrap_${clsName}_get_prop},\n`;
|
||||
str += ` {"__newindex", wrap_${clsName}_set_prop},\n`;
|
||||
str += ` {NULL, NULL}\n`;
|
||||
str += ' };\n'
|
||||
str += ' };\n\n'
|
||||
|
||||
str += ` luaL_newmetatable(L, "lftk.${cls.name}");\n`;
|
||||
str += ` lua_pushstring(L, "__index");\n`;
|
||||
str += ' lua_pushvalue(L, -2);\n';
|
||||
str += ' lua_settable(L, -3);\n';
|
||||
str += ` luaL_openlib(L, NULL, member_funcs, 0);\n`;
|
||||
str += ` luaL_openlib(L, "${cls.name}", static_funcs, 0);\n`;
|
||||
str += ` luaL_openlib(L, NULL, index_funcs, 0);\n`;
|
||||
str += ` luaL_openlib(L, "${toLuaClassName(cls.name)}", static_funcs, 0);\n`;
|
||||
|
||||
str += '}\n\n';
|
||||
str += ' lua_settop(L, 0);\n';
|
||||
str += '}\n';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function genMethods(cls) {
|
||||
let str = '';
|
||||
const clsName = cls.name;
|
||||
|
||||
cls.methods.forEach(m => {
|
||||
if(!m.isPrivate && !m.isCustom) {
|
||||
str += genMethod(cls, m);
|
||||
}
|
||||
});
|
||||
|
||||
str += `\nstatic const struct luaL_Reg ${cls.name}_member_funcs[] = {\n`
|
||||
cls.methods.forEach(m => {
|
||||
const name = methodToShortName(cls.name, m.name);
|
||||
if (!m.isConstructor) {
|
||||
str += ` {"${name}", wrap_${m.name}},\n`;
|
||||
}
|
||||
});
|
||||
str += ` {NULL, NULL}\n`;
|
||||
str += '};\n\n'
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function genClass(cls) {
|
||||
let str = '';
|
||||
|
||||
str += genMethods(cls);
|
||||
str += genSetProp(cls);
|
||||
str += genGetProp(cls);
|
||||
str += genClassInit(cls);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function genEnum(cls) {
|
||||
let str = `static void ${cls.name}_init(lua_State* L) {\n`;
|
||||
|
||||
str += ' lua_newtable(L);\n';
|
||||
str += ` lua_setglobal(L, "${toLuaClassName(cls.name)}");\n`;
|
||||
str += ` lua_getglobal(L, "${toLuaClassName(cls.name)}");\n\n`;
|
||||
|
||||
const clsNamePrefix = cls.name.toUpperCase().replace(/_T$/, "_");
|
||||
cls.consts.forEach(iter => {
|
||||
const name = iter.name;
|
||||
str += ` lua_pushinteger(L, ${name});\n`;
|
||||
str += ` lua_setglobal(L, "${name}");\n`;
|
||||
const name = iter.name.replace(clsNamePrefix, "");
|
||||
|
||||
str += ` lua_pushstring(L, "${name}");\n`
|
||||
str += ` lua_pushinteger(L, ${iter.name});\n`;
|
||||
str += ` lua_settable(L, -3); \n\n`;
|
||||
});
|
||||
|
||||
str += '}\n\n';
|
||||
|
||||
return str;
|
||||
@ -235,14 +341,13 @@ function genOne(cls) {
|
||||
}
|
||||
}
|
||||
|
||||
function genAll() {
|
||||
let result = '#define LUA_COMPAT_MODULE\n';
|
||||
function genIncludes(json) {
|
||||
let result = '/*XXX: generated by lua_gen. dont edit it.*/\n';
|
||||
|
||||
result += '#include "lua.h"\n';
|
||||
result += '#include "lualib.h"\n';
|
||||
result += '#include "lauxlib.h"\n';
|
||||
|
||||
const content = fs.readFileSync('idl.json').toString();
|
||||
const json = JSON.parse(content);
|
||||
|
||||
result += '#include "base/utf8.h"\n';
|
||||
json.forEach(iter => {
|
||||
if (result.indexOf(iter.header) <= 0) {
|
||||
result += `#include "${iter.header}"\n`;
|
||||
@ -250,17 +355,88 @@ function genAll() {
|
||||
});
|
||||
result += "\n";
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function genFuncDecls(json) {
|
||||
let result = '';
|
||||
|
||||
json.forEach(iter => {
|
||||
if (iter.type == 'class') {
|
||||
const clsName = iter.name;
|
||||
result += `static int wrap_${clsName}_get_prop(lua_State* L);\n`;
|
||||
result += `static int wrap_${clsName}_set_prop(lua_State* L);\n`;
|
||||
}
|
||||
});
|
||||
result += '\n';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function genInit(json) {
|
||||
let result = '';
|
||||
|
||||
result += `\nvoid luaL_openlftk(lua_State* L) {\n`;
|
||||
result += ` globals_init(L);\n`;
|
||||
json.forEach(iter => {
|
||||
if(iter.type === 'class' || iter.type === 'enum') {
|
||||
result += ` ${iter.name}_init(L);\n`;
|
||||
}
|
||||
});
|
||||
result += ' s_current_L = L;\n';
|
||||
result += '}\n';
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function genGlobals(json) {
|
||||
let str = '';
|
||||
|
||||
json.forEach(iter => {
|
||||
if (iter.type == 'method') {
|
||||
str += genMethod({}, iter);
|
||||
}
|
||||
});
|
||||
|
||||
str += 'static void globals_init(lua_State* L) {\n';
|
||||
|
||||
json.forEach(iter => {
|
||||
if (iter.type == 'method') {
|
||||
str += ` lua_pushcfunction(L, wrap_${iter.name});\n`;
|
||||
str += ` lua_setglobal(L, "${iter.name}");\n`;
|
||||
} else if (iter.type == 'const') {
|
||||
str += ` lua_pushinteger(L, ${iter.name});\n`;
|
||||
str += ` lua_setglobal(L, "${iter.name}");\n`;
|
||||
}
|
||||
});
|
||||
|
||||
str += ' lua_pushcfunction(L, to_str);\n';
|
||||
str += ' lua_setglobal(L, "to_str");\n';
|
||||
str += ' lua_pushcfunction(L, to_wstr);\n';
|
||||
str += ' lua_setglobal(L, "to_wstr");\n';
|
||||
|
||||
str += '}\n\n';
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
function genAll(json) {
|
||||
let result = genIncludes(json);
|
||||
|
||||
result += builtin;
|
||||
result += genFuncDecls(json);
|
||||
result += genGlobals(json);
|
||||
json.forEach(iter => {
|
||||
result += genOne(iter);
|
||||
});
|
||||
|
||||
result += `\nvoid luaL_openlftk(lua_State* L) {\n`;
|
||||
json.forEach(iter => {
|
||||
result += ` ${iter.name}_init(L);\n`;
|
||||
});
|
||||
result += '}\n';
|
||||
result += genInit(json);
|
||||
|
||||
fs.writeFileSync('../../lua/lftk_lua.c', result);
|
||||
return result;
|
||||
}
|
||||
|
||||
genAll();
|
||||
function run() {
|
||||
fs.writeFileSync('../../lua/lftk_lua.c', genAll(JSON.parse(fs.readFileSync('idl.json').toString())));
|
||||
}
|
||||
|
||||
run();
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user