Convert the main menu screen to lua lol
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <luavgl.h>
|
||||
|
||||
#include "lv_analog_time.h"
|
||||
|
||||
static int luavgl_analog_time_create(lua_State *L)
|
||||
{
|
||||
return luavgl_obj_create_helper(L, lv_analog_time_create);
|
||||
}
|
||||
|
||||
static void _lv_analog_time_set_hands(void *obj, lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, -1)) {
|
||||
luaL_argerror(L, -1, "expect date table.");
|
||||
return;
|
||||
}
|
||||
|
||||
const void *hour, *minute, *second;
|
||||
lua_getfield(L, -1, "hour");
|
||||
|
||||
hour = luavgl_toimgsrc(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "minute");
|
||||
minute = luavgl_toimgsrc(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "second");
|
||||
second = luavgl_toimgsrc(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lv_analog_time_set_hands(obj, hour, minute, second);
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
static const luavgl_value_setter_t analog_time_property_table[] = {
|
||||
{"hands", SETTER_TYPE_STACK, {.setter_stack = _lv_analog_time_set_hands}},
|
||||
{"period", SETTER_TYPE_INT, {.setter = (setter_int_t)lv_analog_time_set_period}},
|
||||
};
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
static int luavgl_analog_time_set_property_kv(lua_State *L, void *data)
|
||||
{
|
||||
lv_obj_t *obj = data;
|
||||
int ret = luavgl_set_property(L, obj, analog_time_property_table);
|
||||
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a base obj property? */
|
||||
ret = luavgl_obj_set_property_kv(L, obj);
|
||||
if (ret != 0) {
|
||||
printf("unkown property for analog_time: %s\n", lua_tostring(L, -2));
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int luavgl_analog_time_set(lua_State *L)
|
||||
{
|
||||
lv_obj_t *obj = luavgl_to_obj(L, 1);
|
||||
|
||||
if (!lua_istable(L, -1)) {
|
||||
luaL_error(L, "expect a table on 2nd para.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
luavgl_iterate(L, -1, luavgl_analog_time_set_property_kv, obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luavgl_analog_time_pause(lua_State *L)
|
||||
{
|
||||
lv_obj_t *obj = luavgl_to_obj(L, 1);
|
||||
lv_analog_time_pause(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int luavgl_analog_time_resume(lua_State *L)
|
||||
{
|
||||
lv_obj_t *obj = luavgl_to_obj(L, 1);
|
||||
lv_analog_time_resume(obj);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg luavgl_analog_time_methods[] = {
|
||||
{"set", luavgl_analog_time_set },
|
||||
{"pause", luavgl_analog_time_pause },
|
||||
{"resume", luavgl_analog_time_resume},
|
||||
|
||||
{NULL, NULL },
|
||||
};
|
||||
|
||||
void luavgl_analog_time_init(lua_State *L)
|
||||
{
|
||||
luavgl_obj_newmetatable(L, &lv_analog_time_class, "lv_analog_time",
|
||||
luavgl_analog_time_methods);
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_getmetatable(L, "widgets");
|
||||
lua_getfield(L, -1, "__index");
|
||||
lua_pushcfunction(L, luavgl_analog_time_create);
|
||||
lua_setfield(L, -2, "AnalogTime");
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <luavgl.h>
|
||||
|
||||
static int luavgl_extension_create(lua_State *L)
|
||||
{
|
||||
return luavgl_obj_create_helper(L, lv_obj_create);
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
static const luavgl_value_setter_t extension_property_table[] = {
|
||||
{"dummy", SETTER_TYPE_STACK, {.setter_stack = _lv_dummy_set}},
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
static int luavgl_extension_set_property_kv(lua_State *L, void *data)
|
||||
{
|
||||
lv_obj_t *obj = data;
|
||||
int ret = luavgl_set_property(L, obj, extension_property_table);
|
||||
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a base obj property? */
|
||||
ret = luavgl_obj_set_property_kv(L, obj);
|
||||
if (ret != 0) {
|
||||
printf("unkown property for extension.\n");
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int luavgl_extension_set(lua_State *L)
|
||||
{
|
||||
lv_obj_t *obj = luavgl_to_obj(L, 1);
|
||||
|
||||
if (!lua_istable(L, -1)) {
|
||||
luaL_error(L, "expect a table on 2nd para.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
luavgl_iterate(L, -1, luavgl_extension_set_property_kv, obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg luavgl_extension_methods[] = {
|
||||
{"set", luavgl_extension_set},
|
||||
|
||||
{NULL, NULL},
|
||||
};
|
||||
|
||||
void luavgl_extension_init(lua_State *L)
|
||||
{
|
||||
luavgl_obj_newmetatable(L, &lv_btn_class, "lv_extension",
|
||||
luavgl_extension_methods);
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_getmetatable(L, "widgets");
|
||||
lua_getfield(L, -1, "__index");
|
||||
lua_pushcfunction(L, luavgl_extension_create);
|
||||
lua_setfield(L, -2, "Extension");
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
@@ -0,0 +1,253 @@
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_analog_time.h"
|
||||
#include "lv_pointer.h"
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#if LV_USE_ANALOG_TIME
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS &lv_analog_time_class
|
||||
|
||||
#define UNIT_ONE_SECOND (1000)
|
||||
#define UNIT_ONE_MINUTE (60 * UNIT_ONE_SECOND)
|
||||
#define UNIT_ONE_HOUR (60 * UNIT_ONE_MINUTE)
|
||||
#define UNIT_ONE_DAY (24 * UNIT_ONE_HOUR)
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_analog_time_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj);
|
||||
static void lv_analog_time_destructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj);
|
||||
static void update_time(lv_obj_t* obj);
|
||||
static void timer_cb(lv_timer_t* timer);
|
||||
static lv_obj_t* create_hand(lv_obj_t* obj, const char* img);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
const lv_obj_class_t lv_analog_time_class = {
|
||||
.constructor_cb = lv_analog_time_constructor,
|
||||
.destructor_cb = lv_analog_time_destructor,
|
||||
.instance_size = sizeof(lv_analog_time_t),
|
||||
.base_class = &lv_obj_class,
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_obj_t* lv_analog_time_create(lv_obj_t* parent)
|
||||
{
|
||||
lv_obj_t* obj = lv_obj_class_create_obj(MY_CLASS, parent);
|
||||
lv_obj_class_init_obj(obj);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void lv_analog_time_set_hands(lv_obj_t* obj, const void* hour,
|
||||
const void* minute, const void* second)
|
||||
{
|
||||
lv_analog_time_t* analog = (lv_analog_time_t*)obj;
|
||||
uint32_t period = UNIT_ONE_MINUTE; /* default */
|
||||
|
||||
/* remove hand if it's null */
|
||||
if (analog->second) {
|
||||
lv_obj_del(analog->second);
|
||||
analog->second = NULL;
|
||||
}
|
||||
|
||||
if (analog->minute) {
|
||||
lv_obj_del(analog->minute);
|
||||
analog->minute = NULL;
|
||||
}
|
||||
|
||||
if (analog->hour) {
|
||||
lv_obj_del(analog->hour);
|
||||
analog->hour = NULL;
|
||||
}
|
||||
|
||||
/* create hand if not null */
|
||||
|
||||
if (hour) {
|
||||
analog->hour = create_hand(obj, hour);
|
||||
|
||||
/* for hour, we use minute as unit*/
|
||||
lv_pointer_set_range(analog->hour, 0, 24 * 60, 0, 3600 * 2);
|
||||
|
||||
/* update period should be faster than 1minute(default) */
|
||||
}
|
||||
|
||||
if (minute) {
|
||||
analog->minute = create_hand(obj, minute);
|
||||
|
||||
/* for minute, update per second */
|
||||
lv_pointer_set_range(analog->minute, 0, 60 * 60, 0, 3600);
|
||||
|
||||
/* update period should be faster than 1second */
|
||||
if (period > 1 * UNIT_ONE_SECOND) {
|
||||
period = UNIT_ONE_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
if (second) {
|
||||
analog->second = create_hand(obj, second);
|
||||
|
||||
/* update per second */
|
||||
lv_pointer_set_range(analog->second, 0, 60 * UNIT_ONE_SECOND, 0, 3600);
|
||||
|
||||
/* update period should be faster than 1second */
|
||||
if (period > 1 * UNIT_ONE_SECOND) {
|
||||
period = UNIT_ONE_SECOND;
|
||||
}
|
||||
}
|
||||
|
||||
if (period < analog->period)
|
||||
analog->period = period;
|
||||
|
||||
if (analog->hour || analog->minute || analog->second) {
|
||||
lv_timer_resume(analog->timer);
|
||||
} else {
|
||||
/* no more needed */
|
||||
lv_timer_pause(analog->timer);
|
||||
}
|
||||
|
||||
update_time(obj);
|
||||
}
|
||||
|
||||
void lv_analog_time_pause(lv_obj_t* obj)
|
||||
{
|
||||
lv_analog_time_t* analog = (lv_analog_time_t*)obj;
|
||||
lv_timer_pause(analog->timer);
|
||||
}
|
||||
|
||||
void lv_analog_time_resume(lv_obj_t* obj)
|
||||
{
|
||||
lv_analog_time_t* analog = (lv_analog_time_t*)obj;
|
||||
lv_timer_resume(analog->timer);
|
||||
update_time(obj);
|
||||
}
|
||||
|
||||
void lv_analog_time_set_period(lv_obj_t* obj, uint32_t period)
|
||||
{
|
||||
lv_analog_time_t* analog = (lv_analog_time_t*)obj;
|
||||
analog->period = period;
|
||||
lv_timer_set_period(analog->timer, period);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_analog_time_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
LV_UNUSED(class_p);
|
||||
LV_TRACE_OBJ_CREATE("begin");
|
||||
|
||||
lv_analog_time_t* analog = (lv_analog_time_t*)obj;
|
||||
analog->period = 60 * 60 * 1000; /* default to 1Hour = 60min*60sec*1000ms*/
|
||||
lv_obj_add_flag(lv_obj_get_parent(obj), LV_OBJ_FLAG_OVERFLOW_VISIBLE);
|
||||
|
||||
/* hands pivot is place to 0, 0 */
|
||||
lv_obj_remove_style_all(obj);
|
||||
lv_obj_set_size(obj, 0, 0);
|
||||
|
||||
analog->timer = lv_timer_create(timer_cb, UNIT_ONE_MINUTE, obj);
|
||||
lv_timer_pause(analog->timer);
|
||||
|
||||
LV_TRACE_OBJ_CREATE("finished");
|
||||
}
|
||||
|
||||
static void lv_analog_time_destructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
lv_analog_time_t* analog = (lv_analog_time_t*)obj;
|
||||
lv_timer_del(analog->timer);
|
||||
}
|
||||
|
||||
static lv_obj_t* create_hand(lv_obj_t* obj, const char* img)
|
||||
{
|
||||
lv_obj_t* hand;
|
||||
hand = lv_pointer_create(obj);
|
||||
lv_img_set_src(hand, img);
|
||||
lv_point_t pivot;
|
||||
lv_img_get_pivot(hand, &pivot);
|
||||
|
||||
/* we position the hand using image's center */
|
||||
lv_obj_set_pos(hand, -pivot.x, -pivot.y);
|
||||
return hand;
|
||||
}
|
||||
|
||||
static void update_time(lv_obj_t* obj)
|
||||
{
|
||||
int value;
|
||||
struct timespec ts;
|
||||
struct tm* time;
|
||||
int ret;
|
||||
|
||||
ret = clock_gettime(CLOCK_REALTIME, &ts);
|
||||
if (ret != 0) {
|
||||
LV_LOG_ERROR("get real time failed");
|
||||
return;
|
||||
}
|
||||
|
||||
time = localtime(&ts.tv_sec);
|
||||
if (time == NULL) {
|
||||
LV_LOG_ERROR("get local time failed");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_analog_time_t* analog = (lv_analog_time_t*)obj;
|
||||
|
||||
value = time->tm_sec * 1000;
|
||||
if (analog->period < UNIT_ONE_SECOND) {
|
||||
/* sub-second update mode */
|
||||
value += ts.tv_nsec / 1000000; /* add ms part */
|
||||
}
|
||||
|
||||
if (analog->second)
|
||||
lv_pointer_set_value(analog->second, value);
|
||||
|
||||
if (analog->minute)
|
||||
lv_pointer_set_value(analog->minute, time->tm_min * 60 + time->tm_sec);
|
||||
|
||||
if (analog->hour)
|
||||
lv_pointer_set_value(analog->hour, time->tm_hour * 60 + time->tm_min);
|
||||
}
|
||||
|
||||
static void timer_cb(lv_timer_t* t)
|
||||
{
|
||||
/* timeup */
|
||||
update_time(t->user_data);
|
||||
}
|
||||
|
||||
/* examples */
|
||||
#if 0
|
||||
|
||||
void lv_analog_time_example(void)
|
||||
{
|
||||
lv_obj_t* scr = lv_scr_act();
|
||||
lv_obj_t* analog = lv_analog_time_create(scr);
|
||||
lv_obj_center(analog);
|
||||
lv_analog_time_set_hands(analog, "/data/hand-second.png", "/data/hand-second.png", "/data/hand-second.png");
|
||||
lv_analog_time_set_period(analog, 60);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,64 @@
|
||||
#ifndef LV_WIDGETS_ANALOG_TIME_H_
|
||||
#define LV_WIDGETS_ANALOG_TIME_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#if LV_USE_ANALOG_TIME
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_obj_t obj;
|
||||
lv_obj_t* hour;
|
||||
lv_obj_t* minute;
|
||||
lv_obj_t* second;
|
||||
uint32_t period;
|
||||
lv_timer_t* timer;
|
||||
} lv_analog_time_t;
|
||||
|
||||
extern const lv_obj_class_t lv_analog_time_class;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
lv_obj_t* lv_analog_time_create(lv_obj_t* parent);
|
||||
|
||||
/**
|
||||
* Set images for hands of hour, minute and second.
|
||||
* If specified hands image is NULL, then it's deleted.
|
||||
*
|
||||
* @note for simplicity, image pivot is set to image center.
|
||||
*/
|
||||
void lv_analog_time_set_hands(lv_obj_t* obj, const void* hour,
|
||||
const void* minute, const void* second);
|
||||
|
||||
void lv_analog_time_pause(lv_obj_t* obj);
|
||||
void lv_analog_time_resume(lv_obj_t* obj);
|
||||
void lv_analog_time_set_period(lv_obj_t* obj, uint32_t period);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_WIDGETS_ANALOG_TIME_H_ */
|
||||
@@ -0,0 +1,138 @@
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
#include "lv_pointer.h"
|
||||
|
||||
#if LV_USE_POINTER
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
#define MY_CLASS &lv_pointer_class
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* STATIC PROTOTYPES
|
||||
**********************/
|
||||
static void lv_pointer_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj);
|
||||
static void angle_update(lv_obj_t* obj);
|
||||
|
||||
/**********************
|
||||
* STATIC VARIABLES
|
||||
**********************/
|
||||
|
||||
const lv_obj_class_t lv_pointer_class = {
|
||||
.constructor_cb = lv_pointer_constructor,
|
||||
.instance_size = sizeof(lv_pointer_t),
|
||||
.base_class = &lv_img_class,
|
||||
};
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
/**********************
|
||||
* GLOBAL FUNCTIONS
|
||||
**********************/
|
||||
|
||||
lv_obj_t* lv_pointer_create(lv_obj_t* parent)
|
||||
{
|
||||
lv_obj_t* obj = lv_obj_class_create_obj(MY_CLASS, parent);
|
||||
lv_obj_class_init_obj(obj);
|
||||
|
||||
/* pointer can rotate out of parent's area. */
|
||||
lv_obj_add_flag(parent, LV_OBJ_FLAG_OVERFLOW_VISIBLE);
|
||||
return obj;
|
||||
}
|
||||
|
||||
void lv_pointer_set_value(lv_obj_t* obj, int value)
|
||||
{
|
||||
lv_pointer_t* pointer = (lv_pointer_t*)obj;
|
||||
if (pointer->value == value) {
|
||||
return;
|
||||
}
|
||||
|
||||
pointer->value = value;
|
||||
angle_update(obj);
|
||||
}
|
||||
|
||||
void lv_pointer_set_range(lv_obj_t* obj, int value_start, int value_range,
|
||||
int angle_start, int angle_range)
|
||||
{
|
||||
lv_pointer_t* pointer = (lv_pointer_t*)obj;
|
||||
pointer->value_start = value_start;
|
||||
pointer->value_range = value_range;
|
||||
pointer->angle_start = angle_start;
|
||||
pointer->angle_range = angle_range;
|
||||
|
||||
/* update angle */
|
||||
angle_update(obj);
|
||||
}
|
||||
|
||||
/**********************
|
||||
* STATIC FUNCTIONS
|
||||
**********************/
|
||||
|
||||
static void lv_pointer_constructor(const lv_obj_class_t* class_p,
|
||||
lv_obj_t* obj)
|
||||
{
|
||||
LV_UNUSED(class_p);
|
||||
LV_TRACE_OBJ_CREATE("begin");
|
||||
lv_pointer_t* pointer = (lv_pointer_t*)obj;
|
||||
|
||||
/* set default range parameters */
|
||||
pointer->angle_start = 0;
|
||||
pointer->angle_range = 360 * 10;
|
||||
pointer->value_start = 0;
|
||||
pointer->value_range = 100;
|
||||
LV_TRACE_OBJ_CREATE("finished");
|
||||
}
|
||||
|
||||
static void angle_update(lv_obj_t* obj)
|
||||
{
|
||||
lv_pointer_t* pointer = (lv_pointer_t*)obj;
|
||||
int angle = 0;
|
||||
int value = pointer->value;
|
||||
int value_start = pointer->value_start;
|
||||
int value_range = pointer->value_range;
|
||||
int angle_start = pointer->angle_start;
|
||||
int angle_range = pointer->angle_range;
|
||||
|
||||
if (value_range != 0) {
|
||||
/* Check value overflow, overwrite angle if so. */
|
||||
int delta = value - value_start;
|
||||
angle = angle_start;
|
||||
angle += (delta * angle_range) / value_range;
|
||||
|
||||
/* check overflow */
|
||||
if (value_range > 0) {
|
||||
if (delta > value_range)
|
||||
angle = angle_start + angle_range;
|
||||
else if (value < value_start)
|
||||
angle = angle_start;
|
||||
} else { /* case of value_range < 0 */
|
||||
if (delta < value_range)
|
||||
angle = angle_start + angle_range;
|
||||
else if (value > value_start)
|
||||
angle = angle_start;
|
||||
}
|
||||
|
||||
while (angle >= 3600)
|
||||
angle -= 3600;
|
||||
while (angle < 0)
|
||||
angle += 3600;
|
||||
}
|
||||
|
||||
if (angle == lv_img_get_angle(obj)) {
|
||||
/* not changed */
|
||||
return;
|
||||
}
|
||||
|
||||
lv_img_set_angle(obj, angle);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef LV_WIDGETS_POINTER_H_
|
||||
#define LV_WIDGETS_POINTER_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*********************
|
||||
* INCLUDES
|
||||
*********************/
|
||||
|
||||
#include <lvgl.h>
|
||||
|
||||
#if LV_USE_POINTER
|
||||
|
||||
/*********************
|
||||
* DEFINES
|
||||
*********************/
|
||||
|
||||
/**********************
|
||||
* TYPEDEFS
|
||||
**********************/
|
||||
|
||||
typedef struct {
|
||||
lv_img_t obj;
|
||||
int value;
|
||||
int value_start;
|
||||
int value_range;
|
||||
int angle_start;
|
||||
int angle_range;
|
||||
} lv_pointer_t;
|
||||
|
||||
extern const lv_obj_class_t lv_pointer_class;
|
||||
|
||||
/**********************
|
||||
* GLOBAL PROTOTYPES
|
||||
**********************/
|
||||
|
||||
lv_obj_t* lv_pointer_create(lv_obj_t* parent);
|
||||
|
||||
/**
|
||||
* Set range parameters for pointer
|
||||
* @param value_start the value mapped to angle_start
|
||||
* @param value_range the value range, could be negative
|
||||
* @param angle_start the angle will be set then value equals to value_start
|
||||
* @param angle_range the angle range, could be negative
|
||||
*/
|
||||
void lv_pointer_set_range(lv_obj_t* obj, int value_start, int value_range,
|
||||
int angle_start, int angle_range);
|
||||
|
||||
/**
|
||||
* Set current value pointer points to
|
||||
* @param value If value is out of range, then angle is also clampped to limits
|
||||
*/
|
||||
void lv_pointer_set_value(lv_obj_t* obj, int value);
|
||||
|
||||
/**********************
|
||||
* MACROS
|
||||
**********************/
|
||||
|
||||
#endif /* */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* LV_WIDGETS_POINTER_H_ */
|
||||
@@ -0,0 +1,101 @@
|
||||
#include <lauxlib.h>
|
||||
#include <lua.h>
|
||||
|
||||
#include <lvgl.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <luavgl.h>
|
||||
|
||||
#include "lv_pointer.h"
|
||||
|
||||
static int luavgl_pointer_create(lua_State *L)
|
||||
{
|
||||
return luavgl_obj_create_helper(L, lv_pointer_create);
|
||||
}
|
||||
|
||||
static void _lv_pointer_set_range(void *obj, lua_State *L)
|
||||
{
|
||||
if (!lua_istable(L, -1)) {
|
||||
luaL_argerror(L, -1, "expect date table.");
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t value_start, value_range, angle_start, angle_range;
|
||||
lua_getfield(L, -1, "valueStart");
|
||||
value_start = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "valueRange");
|
||||
value_range = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "angleStart");
|
||||
angle_start = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "angleRange");
|
||||
angle_range = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lv_pointer_set_range(obj, value_start, value_range, angle_start,
|
||||
angle_range);
|
||||
}
|
||||
|
||||
/* clang-format off */
|
||||
static const luavgl_value_setter_t pointer_property_table[] = {
|
||||
{"range", SETTER_TYPE_STACK, {.setter_stack = _lv_pointer_set_range}},
|
||||
{"value", SETTER_TYPE_INT, {.setter = (setter_int_t)lv_pointer_set_value}},
|
||||
};
|
||||
|
||||
/* clang-format on */
|
||||
|
||||
static int luavgl_pointer_set_property_kv(lua_State *L, void *data)
|
||||
{
|
||||
lv_obj_t *obj = data;
|
||||
int ret = luavgl_set_property(L, obj, pointer_property_table);
|
||||
|
||||
if (ret == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* a base obj property? */
|
||||
ret = luavgl_img_set_property_kv(L, obj);
|
||||
if (ret != 0) {
|
||||
printf("unkown property for pointer: %s\n", lua_tostring(L, -2));
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int luavgl_pointer_set(lua_State *L)
|
||||
{
|
||||
lv_obj_t *obj = luavgl_to_obj(L, 1);
|
||||
|
||||
if (!lua_istable(L, -1)) {
|
||||
luaL_error(L, "expect a table on 2nd para.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
luavgl_iterate(L, -1, luavgl_pointer_set_property_kv, obj);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const luaL_Reg luavgl_pointer_methods[] = {
|
||||
{"set", luavgl_pointer_set},
|
||||
|
||||
{NULL, NULL },
|
||||
};
|
||||
|
||||
void luavgl_pointer_init(lua_State *L)
|
||||
{
|
||||
luavgl_obj_newmetatable(L, &lv_pointer_class, "lv_pointer",
|
||||
luavgl_pointer_methods);
|
||||
lua_pop(L, 1);
|
||||
|
||||
luaL_getmetatable(L, "widgets");
|
||||
lua_getfield(L, -1, "__index");
|
||||
lua_pushcfunction(L, luavgl_pointer_create);
|
||||
lua_setfield(L, -2, "Pointer");
|
||||
lua_pop(L, 2);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "widgets.h"
|
||||
|
||||
void luavgl_widgets_init(lua_State *L)
|
||||
{
|
||||
luavgl_extension_init(L);
|
||||
luavgl_pointer_init(L);
|
||||
luavgl_analog_time_init(L);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#ifndef WIDGETS_WIDGETS_H_
|
||||
#define WIDGETS_WIDGETS_H_
|
||||
|
||||
#include <lua.h>
|
||||
|
||||
void luavgl_extension_init(lua_State *L);
|
||||
void luavgl_pointer_init(lua_State *L);
|
||||
void luavgl_analog_time_init(lua_State *L);
|
||||
|
||||
void luavgl_widgets_init(lua_State *L);
|
||||
|
||||
#endif /* WIDGETS_WIDGETS_H_ */
|
||||
@@ -0,0 +1,104 @@
|
||||
---@meta
|
||||
|
||||
lvgl = require "lvgl"
|
||||
---
|
||||
--- Create Extension widget on parent
|
||||
--- @param parent? Object | nil
|
||||
--- @param property? ObjectStyle
|
||||
--- @return Extension
|
||||
function lvgl.Extension(parent, property)
|
||||
end
|
||||
|
||||
--- Create Extension widget on obj
|
||||
--- @param property? ObjectStyle
|
||||
--- @return Extension
|
||||
function obj:Extension(property)
|
||||
end
|
||||
|
||||
---
|
||||
--- Extension widget
|
||||
---@class Extension:Object
|
||||
---
|
||||
local extension = {}
|
||||
|
||||
--- set method
|
||||
--- @param p ObjectStyle
|
||||
--- @return nil
|
||||
function extension:set(p)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
--- Create Pointer widget
|
||||
--- @param parent? Object | nil
|
||||
--- @param property? ObjectStyle
|
||||
--- @return Pointer
|
||||
function lvgl.Pointer(parent, property)
|
||||
end
|
||||
|
||||
--- Create Extension widget on obj
|
||||
--- @param property? ObjectStyle
|
||||
--- @return Extension
|
||||
function obj:Pointer(property)
|
||||
end
|
||||
|
||||
---
|
||||
--- Pointer widget
|
||||
---@class Pointer:Object
|
||||
---
|
||||
local pointer = {}
|
||||
|
||||
--- set method
|
||||
--- @param p ObjectStyle
|
||||
--- @return nil
|
||||
function pointer:set(p)
|
||||
end
|
||||
|
||||
|
||||
---
|
||||
--- Create AnalogTime widget on parent
|
||||
--- @param parent? Object | nil
|
||||
--- @param property? AnalogTimeStyle
|
||||
--- @return AnalogTime
|
||||
function lvgl.AnalogTime(parent, property)
|
||||
end
|
||||
|
||||
--- Create AnalogTime widget on obj
|
||||
--- @param property? AnalogTimeStyle
|
||||
--- @return AnalogTime
|
||||
function obj:AnalogTime(property)
|
||||
end
|
||||
|
||||
---
|
||||
--- Extension widget
|
||||
---@class AnalogTime:Object
|
||||
---
|
||||
local analogTime = {}
|
||||
|
||||
--- set method
|
||||
--- @param p AnalogTimeStyle
|
||||
--- @return nil
|
||||
function analogTime:set(p)
|
||||
end
|
||||
|
||||
--- Pause the hand refresh timer
|
||||
function analogTime:pause()
|
||||
end
|
||||
|
||||
--- Resume the hand refresh timer
|
||||
function analogTime:resume()
|
||||
end
|
||||
|
||||
--- Analog time hands parameter
|
||||
--- @class AnalogTimeHands
|
||||
--- @field hour string Image source path for hour hand
|
||||
--- @field minute string minute hand
|
||||
--- @field second string second hand
|
||||
---
|
||||
|
||||
|
||||
--- Analog time widget property
|
||||
--- @class AnalogTimeStyle :StyleProp
|
||||
--- @field hands AnalogTimeHands Hands images
|
||||
--- @field period integer Timer refresh period, default to 1s/1min depending on whether there's second/min hands
|
||||
---
|
||||
Reference in New Issue
Block a user