1.add api doc. 2.add lua generator

This commit is contained in:
jim 2018-03-04 08:32:52 +08:00
parent 95e9f2f070
commit 0d420c9665
68 changed files with 5982 additions and 693 deletions

Binary file not shown.

View File

@ -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'
])

View File

@ -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']);

View File

@ -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);

View File

@ -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;
}

View File

@ -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,

View File

@ -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));

View File

@ -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
View 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
View 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;
}

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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
View File

@ -0,0 +1,4 @@
local wstr = to_wstr("hello")
local str = to_str(wstr)
print(str);

24
lua/test.lua Normal file
View 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()

View File

@ -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
View 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()

View File

@ -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:

View File

@ -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))

View File

@ -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);

View File

@ -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))

View File

@ -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;
}

View File

@ -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))

View File

@ -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) {

View File

@ -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);

View File

@ -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
View 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;
}

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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:

View File

@ -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
View 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
View 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*/

View File

@ -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);

View File

@ -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) {

View File

@ -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))

View File

@ -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);

View File

@ -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();
}

View File

@ -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

View File

@ -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*/

View File

@ -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); }

View File

@ -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*}

View File

@ -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;
}

View File

@ -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} idwidget_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))

View File

@ -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;

View File

@ -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

View File

@ -26,6 +26,11 @@
BEGIN_C_DECLS
/**
* @class window_manager_t
* @parent widget_t
*
*/
typedef struct _window_manager_t {
widget_t widget;

View File

@ -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; }

View File

@ -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

View File

@ -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; }

View File

@ -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

View File

@ -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; }

View File

@ -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

View File

@ -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);

View File

@ -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");

View File

@ -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; }

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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
View 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"
}
]
}

View File

@ -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();

View File

@ -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