feat(color): allow all UI controls for widgets when full screen (#5808)

This commit is contained in:
philmoz
2025-02-04 11:46:12 +10:00
committed by GitHub
parent a755afb314
commit 80d831832f
27 changed files with 981 additions and 164 deletions
+95 -11
View File
@@ -30,9 +30,9 @@
LuaLvglManager *luaLvglManager = nullptr;
static int luaLvglObj(lua_State *L, std::function<LvglWidgetObject*()> create, bool standalone = false)
static int luaLvglObj(lua_State *L, std::function<LvglWidgetObject*()> create, bool fullscreenOnly = false)
{
if (luaLvglManager && (!standalone || !luaLvglManager->isWidget())) {
if (luaLvglManager && (!fullscreenOnly || luaLvglManager->isFullscreen())) {
auto obj = create();
obj->getParams(L, 1);
obj->build(L);
@@ -44,9 +44,9 @@ static int luaLvglObj(lua_State *L, std::function<LvglWidgetObject*()> create, b
return 1;
}
static int luaLvglObjEx(lua_State *L, std::function<LvglWidgetObjectBase*()> create, bool standalone = false)
static int luaLvglObjEx(lua_State *L, std::function<LvglWidgetObjectBase*()> create, bool fullscreenOnly = false)
{
if (luaLvglManager && (!standalone || !luaLvglManager->isWidget())) {
if (luaLvglManager && (!fullscreenOnly || luaLvglManager->isFullscreen())) {
LvglWidgetObjectBase* p = nullptr;
LvglWidgetObjectBase* prevParent = nullptr;
if (lua_gettop(L) == 2) {
@@ -132,6 +132,24 @@ static int luaLvglHide(lua_State *L)
return 0;
}
static int luaLvglEnable(lua_State *L)
{
auto p = LvglWidgetObjectBase::checkLvgl(L, 1);
if (p) {
p->enable();
}
return 0;
}
static int luaLvglDisable(lua_State *L)
{
auto p = LvglWidgetObjectBase::checkLvgl(L, 1);
if (p) {
p->disable();
}
return 0;
}
class LvglWidgetParams
{
public:
@@ -183,11 +201,11 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
obj = new LvglWidgetQRCode();
else if (strcasecmp(p.type, "box") == 0)
obj = new LvglWidgetBox();
else if (strcasecmp(p.type, "setting") == 0)
obj = new LvglWidgetSetting();
else if (!luaLvglManager->isWidget()) {
else if (luaLvglManager->isFullscreen()) {
if (strcasecmp(p.type, "button") == 0)
obj = new LvglWidgetTextButton();
if (strcasecmp(p.type, "momentaryButton") == 0)
obj = new LvglWidgetMomentaryButton();
else if (strcasecmp(p.type, "toggle") == 0)
obj = new LvglWidgetToggleSwitch();
else if (strcasecmp(p.type, "textEdit") == 0)
@@ -198,6 +216,8 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
obj = new LvglWidgetChoice();
else if (strcasecmp(p.type, "slider") == 0)
obj = new LvglWidgetSlider();
else if (strcasecmp(p.type, "verticalSlider") == 0)
obj = new LvglWidgetVerticalSlider();
else if (strcasecmp(p.type, "page") == 0)
obj = new LvglWidgetPage();
else if (strcasecmp(p.type, "font") == 0)
@@ -212,6 +232,8 @@ static void buildLvgl(lua_State *L, int srcIndex, int refIndex)
obj = new LvglWidgetSwitchPicker();
else if (strcasecmp(p.type, "source") == 0)
obj = new LvglWidgetSourcePicker();
else if (strcasecmp(p.type, "setting") == 0)
obj = new LvglWidgetSetting();
}
if (obj) {
obj->getParams(L, -1);
@@ -269,12 +291,43 @@ static int luaLvglIsAppMode(lua_State *L)
return 1;
}
static int luaLvglIsFullscreen(lua_State *L)
{
if (luaLvglManager) {
lua_pushboolean(L, luaLvglManager->isFullscreen());
} else {
lua_pushboolean(L, false);
}
return 1;
}
static int luaLvglExitFullscreen(lua_State *L)
{
if (luaLvglManager)
luaLvglManager->exitFullscreen();
return 0;
}
static int luaLvglGetContext(lua_State *L)
{
if (luaLvglManager && luaLvglManager->getContext() != LUA_REFNIL) {
// Push context tanle onto Lua stack (return object)
lua_rawgeti(L, LUA_REGISTRYINDEX, luaLvglManager->getContext());
} else {
lua_pushnil(L);
}
return 1;
}
// lvgl functions
LROT_BEGIN(lvgllib, NULL, 0)
LROT_FUNCENTRY(clear, luaLvglClear)
LROT_FUNCENTRY(build, luaLvglBuild)
LROT_FUNCENTRY(isAppMode, luaLvglIsAppMode)
// Objects - widgets and standalone
LROT_FUNCENTRY(isFullScreen, luaLvglIsFullscreen)
LROT_FUNCENTRY(exitFullScreen, luaLvglExitFullscreen)
LROT_FUNCENTRY(getContext, luaLvglGetContext)
// Objects - widgets and standalone scripts
LROT_FUNCENTRY(label, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetLabel(); }); })
LROT_FUNCENTRY(rectangle, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetRectangle(); }); })
LROT_FUNCENTRY(hline, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetHLine(); }); })
@@ -285,13 +338,15 @@ LROT_BEGIN(lvgllib, NULL, 0)
LROT_FUNCENTRY(arc, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetArc(); }); })
LROT_FUNCENTRY(image, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetImage(); }); })
LROT_FUNCENTRY(qrcode, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetQRCode(); }); })
// Objects - standalone scripts only
// Objects - standalone scripts and full screen widgets only
LROT_FUNCENTRY(button, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTextButton(); }, true); })
LROT_FUNCENTRY(momentaryButton, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetMomentaryButton(); }, true); })
LROT_FUNCENTRY(toggle, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetToggleSwitch(); }, true); })
LROT_FUNCENTRY(textEdit, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTextEdit(); }, true); })
LROT_FUNCENTRY(numberEdit, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetNumberEdit(); }, true); })
LROT_FUNCENTRY(choice, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetChoice(); }, true); })
LROT_FUNCENTRY(slider, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSlider(); }, true); })
LROT_FUNCENTRY(verticalSlider, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetVerticalSlider(); }, true); })
LROT_FUNCENTRY(font, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetFontPicker(); }, true); })
LROT_FUNCENTRY(align, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetAlignPicker(); }, true); })
LROT_FUNCENTRY(color, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetColorPicker(); }, true); })
@@ -310,12 +365,37 @@ LROT_BEGIN(lvgllib, NULL, 0)
LROT_FUNCENTRY(set, luaLvglSet)
LROT_FUNCENTRY(show, luaLvglShow)
LROT_FUNCENTRY(hide, luaLvglHide)
LROT_FUNCENTRY(enable, luaLvglEnable)
LROT_FUNCENTRY(disable, luaLvglDisable)
LROT_NUMENTRY(FLOW_ROW, LV_FLEX_FLOW_ROW)
LROT_NUMENTRY(FLOW_COLUMN, LV_FLEX_FLOW_COLUMN)
LROT_NUMENTRY(PAD_TINY, PAD_TINY)
LROT_NUMENTRY(PAD_SMALL, PAD_SMALL)
LROT_NUMENTRY(PAD_MEDIUM, PAD_MEDIUM)
LROT_NUMENTRY(PAD_LARGE, PAD_LARGE)
LROT_NUMENTRY(SRC_ALL, 0xFFFFFFFF)
LROT_NUMENTRY(SRC_INPUT, SRC_INPUT)
LROT_NUMENTRY(SRC_LUA, SRC_LUA)
LROT_NUMENTRY(SRC_STICK, SRC_STICK|SRC_TILT|SRC_SPACEMOUSE)
LROT_NUMENTRY(SRC_POT, SRC_POT)
LROT_NUMENTRY(SRC_OTHER, SRC_MINMAX|SRC_TX|SRC_TIMER)
LROT_NUMENTRY(SRC_HELI, SRC_HELI)
LROT_NUMENTRY(SRC_TRIM, SRC_TRIM)
LROT_NUMENTRY(SRC_SWITCH, SRC_SWITCH|SRC_FUNC_SWITCH)
LROT_NUMENTRY(SRC_LOGICAL_SWITCH, SRC_LOGICAL_SWITCH)
LROT_NUMENTRY(SRC_TRAINER, SRC_TRAINER)
LROT_NUMENTRY(SRC_CHANNEL, SRC_CHANNEL)
LROT_NUMENTRY(SRC_GVAR, SRC_GVAR)
LROT_NUMENTRY(SRC_TELEM, SRC_TELEM)
LROT_NUMENTRY(SRC_CLEAR, SRC_NONE)
LROT_NUMENTRY(SRC_INVERT, SRC_INVERT)
LROT_NUMENTRY(SW_ALL, 0xFFFFFFFF)
LROT_NUMENTRY(SW_SWITCH, SW_SWITCH)
LROT_NUMENTRY(SW_TRIM, SW_TRIM)
LROT_NUMENTRY(SW_LOGICAL_SWITCH, SW_LOGICAL_SWITCH)
LROT_NUMENTRY(SW_TELEM, SW_TELEM)
LROT_NUMENTRY(SW_OTHER, SW_OTHER)
LROT_NUMENTRY(SW_CLEAR, SW_NONE)
LROT_END(lvgllib, NULL, 0)
// Metatable for simple objects (line, arc, label)
@@ -334,7 +414,7 @@ LROT_BEGIN(lvgl_mt, NULL, LROT_MASK_GC_INDEX)
LROT_TABENTRY(__index, lvgl_mt)
LROT_FUNCENTRY(clear, luaLvglClear)
LROT_FUNCENTRY(build, luaLvglBuild)
// Objects - widgets and standalone
// Objects - widgets and standalone scripts
LROT_FUNCENTRY(label, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetLabel(); }); })
LROT_FUNCENTRY(rectangle, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetRectangle(); }); })
LROT_FUNCENTRY(hline, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetHLine(); }); })
@@ -345,13 +425,15 @@ LROT_BEGIN(lvgl_mt, NULL, LROT_MASK_GC_INDEX)
LROT_FUNCENTRY(arc, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetArc(); }); })
LROT_FUNCENTRY(image, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetImage(); }); })
LROT_FUNCENTRY(qrcode, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetQRCode(); }); })
// Objects - standalone scripts only
// Objects - standalone scripts and full screen widgets only
LROT_FUNCENTRY(button, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTextButton(); }, true); })
LROT_FUNCENTRY(momentaryButton, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetMomentaryButton(); }, true); })
LROT_FUNCENTRY(toggle, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetToggleSwitch(); }, true); })
LROT_FUNCENTRY(textEdit, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTextEdit(); }, true); })
LROT_FUNCENTRY(numberEdit, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetNumberEdit(); }, true); })
LROT_FUNCENTRY(choice, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetChoice(); }, true); })
LROT_FUNCENTRY(slider, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSlider(); }, true); })
LROT_FUNCENTRY(verticalSlider, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetVerticalSlider(); }, true); })
LROT_FUNCENTRY(font, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetFontPicker(); }, true); })
LROT_FUNCENTRY(align, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetAlignPicker(); }, true); })
LROT_FUNCENTRY(color, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetColorPicker(); }, true); })
@@ -362,6 +444,8 @@ LROT_BEGIN(lvgl_mt, NULL, LROT_MASK_GC_INDEX)
LROT_FUNCENTRY(set, luaLvglSet)
LROT_FUNCENTRY(show, luaLvglShow)
LROT_FUNCENTRY(hide, luaLvglHide)
LROT_FUNCENTRY(enable, luaLvglEnable)
LROT_FUNCENTRY(disable, luaLvglDisable)
LROT_END(lvgl_mt, NULL, LROT_MASK_GC_INDEX)
extern "C" {
+1 -1
View File
@@ -2199,7 +2199,7 @@ static int luaGetUsage(lua_State * L)
lua_pushinteger(L, instructionsPercent);
}
#else
lua_pushinteger(L, instructionsPercent);
lua_pushinteger(L, 100 * maxLuaDuration / LUA_TASK_PERIOD_TICKS);
#endif
return 1;
}
-5
View File
@@ -55,7 +55,6 @@ extern "C" {
#define LUA_WARNING_INFO_LEN 64
#endif
#define PERMANENT_SCRIPTS_MAX_INSTRUCTIONS 100
#define LUA_TASK_PERIOD_TICKS 5 // 50 ms
// #if defined(HARDWARE_TOUCH)
// #include "touch.h"
@@ -74,7 +73,6 @@ ScriptInputsOutputs scriptInputsOutputs[MAX_SCRIPTS];
uint16_t maxLuaInterval = 0;
uint16_t maxLuaDuration = 0;
uint8_t instructionsPercent = 0;
tmr10ms_t luaCycleStart;
char lua_warning_info[LUA_WARNING_INFO_LEN+1];
uint8_t errorState;
@@ -1283,9 +1281,6 @@ bool luaTask(bool allowLcdUsage)
// For preemption
luaCycleStart = get_tmr10ms();
// Trying to replace CPU usage measure
instructionsPercent = 100 * maxLuaDuration / LUA_TASK_PERIOD_TICKS;
switch (luaState) {
case INTERPRETER_RELOAD_PERMANENT_SCRIPTS:
init = true;
+1
View File
@@ -208,6 +208,7 @@ extern struct our_longjmp * global_lj;
extern uint16_t maxLuaInterval;
extern uint16_t maxLuaDuration;
extern uint8_t instructionsPercent;
#define LUA_TASK_PERIOD_TICKS 5 // 50 ms
struct LuaField {
uint16_t id;
+265 -27
View File
@@ -126,9 +126,12 @@ void LvglWidgetObjectBase::pcallSimpleFunc(lua_State *L, int funcRef)
if (funcRef != LUA_REFNIL) {
PROTECT_LUA()
{
auto save = luaLvglManager;
luaLvglManager = lvglManager;
if (!pcallFunc(L, funcRef, 0)) {
lvglManager->luaShowError();
}
luaLvglManager = save;
}
UNPROTECT_LUA();
}
@@ -137,39 +140,54 @@ void LvglWidgetObjectBase::pcallSimpleFunc(lua_State *L, int funcRef)
bool LvglWidgetObjectBase::pcallUpdateBool(lua_State *L, int getFuncRef,
std::function<void(bool)> update)
{
bool res = true;
if (getFuncRef != LUA_REFNIL) {
auto save = luaLvglManager;
luaLvglManager = lvglManager;
int t = lua_gettop(L);
if (pcallFunc(L, getFuncRef, 1)) {
bool val = lua_toboolean(L, -1);
bool val = false;
if (lua_isboolean(L, -1))
val = lua_toboolean(L, -1);
else
val = luaL_optinteger(L, -1, 0) != 0;
update(val);
lua_settop(L, t);
} else {
return false;
res = false;
}
lvglManager = save;
}
return true;
return res;
}
bool LvglWidgetObjectBase::pcallUpdate1Int(lua_State *L, int getFuncRef,
std::function<void(int)> update)
{
bool res = true;
if (getFuncRef != LUA_REFNIL) {
auto save = luaLvglManager;
luaLvglManager = lvglManager;
int t = lua_gettop(L);
if (pcallFunc(L, getFuncRef, 1)) {
int val = luaL_checkunsigned(L, -1);
update(val);
lua_settop(L, t);
} else {
return false;
res = false;
}
lvglManager = save;
}
return true;
return res;
}
bool LvglWidgetObjectBase::pcallUpdate2Int(lua_State *L, int getFuncRef,
std::function<void(int, int)> update)
{
bool res = true;
if (getFuncRef != LUA_REFNIL) {
auto save = luaLvglManager;
luaLvglManager = lvglManager;
int t = lua_gettop(L);
if (pcallFunc(L, getFuncRef, 2)) {
int v1 = luaL_checkunsigned(L, -2);
@@ -177,21 +195,27 @@ bool LvglWidgetObjectBase::pcallUpdate2Int(lua_State *L, int getFuncRef,
update(v1, v2);
lua_settop(L, t);
} else {
return false;
res = false;
}
lvglManager = save;
}
return true;
return res;
}
int LvglWidgetObjectBase::pcallGetIntVal(lua_State *L, int getFuncRef)
{
int val = 0;
if (getFuncRef != LUA_REFNIL) {
auto save = luaLvglManager;
luaLvglManager = lvglManager;
int t = lua_gettop(L);
PROTECT_LUA()
{
if (pcallFunc(L, getFuncRef, 1)) {
val = luaL_checkinteger(L, -1);
if (lua_isboolean(L, -1))
val = lua_toboolean(L, -1);
else
val = luaL_checkinteger(L, -1);
} else {
lvglManager->luaShowError();
}
@@ -202,6 +226,36 @@ int LvglWidgetObjectBase::pcallGetIntVal(lua_State *L, int getFuncRef)
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
}
return val;
}
int LvglWidgetObjectBase::pcallGetOptIntVal(lua_State *L, int getFuncRef, int defVal)
{
int val = 0;
if (getFuncRef != LUA_REFNIL) {
auto save = luaLvglManager;
luaLvglManager = lvglManager;
int t = lua_gettop(L);
PROTECT_LUA()
{
if (pcallFunc(L, getFuncRef, 1)) {
if (lua_isboolean(L, -1))
val = lua_toboolean(L, -1);
else
val = luaL_optinteger(L, -1, defVal);
} else {
lvglManager->luaShowError();
}
}
else
{
lvglManager->luaShowError();
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
}
return val;
}
@@ -209,6 +263,8 @@ int LvglWidgetObjectBase::pcallGetIntVal(lua_State *L, int getFuncRef)
void LvglWidgetObjectBase::pcallSetIntVal(lua_State *L, int setFuncRef, int val)
{
if (setFuncRef != LUA_REFNIL) {
auto save = luaLvglManager;
luaLvglManager = lvglManager;
int t = lua_gettop(L);
PROTECT_LUA()
{
@@ -222,6 +278,7 @@ void LvglWidgetObjectBase::pcallSetIntVal(lua_State *L, int setFuncRef, int val)
}
UNPROTECT_LUA();
lua_settop(L, t);
lvglManager = save;
}
}
@@ -461,7 +518,7 @@ void LvglWidgetLabel::setFont(LcdFlags font)
{
if (lvobj) {
this->font = font;
lv_obj_set_style_text_font(lvobj, getFont(font), LV_PART_MAIN);
etx_font(lvobj, FONT_INDEX(font));
}
}
@@ -940,6 +997,8 @@ void LvglWidgetObject::parseParam(lua_State *L, const char *key)
flexFlow = luaL_checkinteger(L, -1);
} else if (!strcmp(key, "flexPad")) {
flexPad = luaL_checkinteger(L, -1);
} else if (!strcmp(key, "active")) {
getActiveFunction = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
LvglWidgetObjectBase::parseParam(L, key);
}
@@ -971,12 +1030,32 @@ bool LvglWidgetObject::setFlex()
}
}
bool LvglWidgetObject::callRefs(lua_State *L)
{
if (!pcallUpdateBool(L, getActiveFunction,
[=](bool active) { if (active) enable(); else disable(); }))
return false;
return LvglWidgetObjectBase::callRefs(L);
}
void LvglWidgetObject::clearRefs(lua_State *L)
{
clearRef(L, getActiveFunction);
LvglWidgetObjectBase::clearRefs(L);
}
//-----------------------------------------------------------------------------
void LvglWidgetBox::build(lua_State* L)
{
window =
new Window(lvglManager->getCurrentParent(), {x, y, w, h}, lv_obj_create);
lv_obj_add_flag(window->getLvObj(), LV_OBJ_FLAG_EVENT_BUBBLE);
if (luaLvglManager->isWidget()) {
lv_obj_clear_flag(window->getLvObj(), LV_OBJ_FLAG_CLICKABLE);
} else {
etx_scrollbar(window->getLvObj());
}
if (setFlex())
lv_obj_set_flex_align(window->getLvObj(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_AROUND);
}
@@ -1266,10 +1345,16 @@ void LvglWidgetQRCode::build(lua_State *L)
//-----------------------------------------------------------------------------
void LvglWidgetTextButton::parseParam(lua_State *L, const char *key)
void LvglWidgetTextButtonBase::parseParam(lua_State *L, const char *key)
{
if (!strcmp(key, "text")) {
txt = luaL_checkstring(L, -1);
} else if (!strcmp(key, "font")) {
font = luaL_checkunsigned(L, -1);
} else if (!strcmp(key, "cornerRadius")) {
rounded = luaL_checkunsigned(L, -1);
} else if (!strcmp(key, "textColor")) {
textColor = luaL_checkunsigned(L, -1);
} else if (!strcmp(key, "press")) {
pressFunction = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
@@ -1277,13 +1362,13 @@ void LvglWidgetTextButton::parseParam(lua_State *L, const char *key)
}
}
void LvglWidgetTextButton::clearRefs(lua_State *L)
void LvglWidgetTextButtonBase::clearRefs(lua_State *L)
{
clearRef(L, pressFunction);
LvglWidgetObject::clearRefs(L);
}
void LvglWidgetTextButton::setText(const char *s)
void LvglWidgetTextButtonBase::setText(const char *s)
{
uint32_t h = hash(s, strlen(s));
if (h != textHash) {
@@ -1293,14 +1378,126 @@ void LvglWidgetTextButton::setText(const char *s)
}
}
void LvglWidgetTextButtonBase::setSize(coord_t w, coord_t h)
{
if (w == LV_SIZE_CONTENT || w == 0) w = lv_obj_get_width(window->getLvObj());
if (h == LV_SIZE_CONTENT || h == 0) h = lv_obj_get_height(window->getLvObj());
LvglWidgetObject::setSize(w, h);
}
void LvglWidgetTextButtonBase::setColor(LcdFlags newColor)
{
color = newColor;
if (color != currentColor) {
currentColor = color;
etx_bg_color_from_flags(window->getLvObj(), color);
}
if (textColor != currentTextColor) {
currentTextColor = textColor;
etx_txt_color_from_flags(window->getLvObj(), textColor);
}
}
void LvglWidgetTextButtonBase::setRounded()
{
if (rounded >= 0) {
lv_obj_remove_style(window->getLvObj(), (lv_style_t*)&styles->rounded, LV_PART_MAIN);
if (rounded > 0)
lv_obj_set_style_radius(window->getLvObj(), rounded, LV_PART_MAIN);
}
}
//-----------------------------------------------------------------------------
void LvglWidgetTextButton::parseParam(lua_State *L, const char *key)
{
if (!strcmp(key, "checked")) {
checked = lua_toboolean(L, -1);
} else if (!strcmp(key, "longpress")) {
longPressFunction = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
LvglWidgetTextButtonBase::parseParam(L, key);
}
}
void LvglWidgetTextButton::clearRefs(lua_State *L)
{
clearRef(L, longPressFunction);
LvglWidgetTextButtonBase::clearRefs(L);
}
void LvglWidgetTextButton::setFont(LcdFlags font)
{
if (window) {
this->font = font;
((TextButton*)window)->setFont(FONT_INDEX(font));
}
}
void LvglWidgetTextButton::setChecked(bool checked)
{
this->checked = checked;
((TextButton*)window)->check(checked);
}
void LvglWidgetTextButton::build(lua_State *L)
{
if (h == LV_SIZE_CONTENT) h = 0;
window =
auto btn =
new TextButton(lvglManager->getCurrentParent(), {x, y, w, h}, txt, [=]() {
pcallSimpleFunc(L, pressFunction);
return 0;
return pcallGetOptIntVal(L, pressFunction, 0);
});
if (longPressFunction != LUA_REFNIL) {
btn->setLongPressHandler([=]() {
return pcallGetOptIntVal(L, longPressFunction, 0);
});
}
window = btn;
setFont(font);
setChecked(checked);
setColor(color);
setRounded();
}
//-----------------------------------------------------------------------------
void LvglWidgetMomentaryButton::parseParam(lua_State *L, const char *key)
{
if (!strcmp(key, "release")) {
releaseFunction = luaL_ref(L, LUA_REGISTRYINDEX);
} else {
LvglWidgetTextButtonBase::parseParam(L, key);
}
}
void LvglWidgetMomentaryButton::setFont(LcdFlags font)
{
if (window) {
this->font = font;
((MomentaryButton*)window)->setFont(FONT_INDEX(font));
}
}
void LvglWidgetMomentaryButton::clearRefs(lua_State *L)
{
clearRef(L, releaseFunction);
LvglWidgetTextButtonBase::clearRefs(L);
}
void LvglWidgetMomentaryButton::build(lua_State *L)
{
if (h == LV_SIZE_CONTENT) h = 0;
window =
new MomentaryButton(lvglManager->getCurrentParent(), {x, y, w, h}, txt,
[=]() {
pcallSimpleFunc(L, pressFunction);
},
[=]() {
pcallSimpleFunc(L, releaseFunction);
});
setFont(font);
setColor(color);
setRounded();
}
//-----------------------------------------------------------------------------
@@ -1437,7 +1634,7 @@ void LvglWidgetNumberEdit::build(lua_State *L)
//-----------------------------------------------------------------------------
void LvglWidgetSlider::parseParam(lua_State *L, const char *key)
void LvglWidgetSliderBase::parseParam(lua_State *L, const char *key)
{
if (!strcmp(key, "get")) {
getValueFunction = luaL_ref(L, LUA_REGISTRYINDEX);
@@ -1452,20 +1649,44 @@ void LvglWidgetSlider::parseParam(lua_State *L, const char *key)
}
}
void LvglWidgetSlider::clearRefs(lua_State *L)
void LvglWidgetSliderBase::setColor(LcdFlags newColor)
{
color = newColor;
if (color != currentColor) {
currentColor = color;
((SliderBase*)window)->setColor(color);
}
}
void LvglWidgetSliderBase::clearRefs(lua_State *L)
{
clearRef(L, getValueFunction);
clearRef(L, setValueFunction);
LvglWidgetObject::clearRefs(L);
}
//-----------------------------------------------------------------------------
void LvglWidgetSlider::build(lua_State *L)
{
window = new Slider(
lvglManager->getCurrentParent(), w, vmin, vmax,
[=]() { return pcallGetIntVal(L, getValueFunction); },
[=](uint8_t val) { pcallSetIntVal(L, setValueFunction, val); });
[=](int val) { pcallSetIntVal(L, setValueFunction, val); });
window->setPos(x, y);
setColor(color);
}
//-----------------------------------------------------------------------------
void LvglWidgetVerticalSlider::build(lua_State *L)
{
window = new VerticalSlider(
lvglManager->getCurrentParent(), h, vmin, vmax,
[=]() { return pcallGetIntVal(L, getValueFunction); },
[=](int val) { pcallSetIntVal(L, setValueFunction, val); });
window->setPos(x, y);
setColor(color);
}
//-----------------------------------------------------------------------------
@@ -1514,7 +1735,8 @@ class WidgetPage : public NavWindow, public LuaEventHandler
void onEvent(event_t evt) override
{
LuaEventHandler::onEvent(evt);
LuaEventHandler::onLuaEvent(evt);
parent->onEvent(evt);
}
protected:
@@ -1733,6 +1955,7 @@ void LvglWidgetAlignPicker::build(lua_State *L)
void LvglWidgetColorPicker::build(lua_State *L)
{
if (w == LV_SIZE_CONTENT) w = 0;
if (h == LV_SIZE_CONTENT) h = 0;
window = new ColorPicker(
lvglManager->getCurrentParent(), {x, y, w, h},
@@ -1759,10 +1982,8 @@ void LvglWidgetTimerPicker::build(lua_State *L)
void LvglWidgetSwitchPicker::parseParam(lua_State *L, const char *key)
{
if (!strcmp(key, "min")) {
vmin = luaL_checkinteger(L, -1);
} else if (!strcmp(key, "max")) {
vmax = luaL_checkinteger(L, -1);
if (!strcmp(key, "filter")) {
filter = luaL_checkunsigned(L, -1);
} else {
LvglWidgetPicker::parseParam(L, key);
}
@@ -1771,24 +1992,41 @@ void LvglWidgetSwitchPicker::parseParam(lua_State *L, const char *key)
void LvglWidgetSwitchPicker::build(lua_State *L)
{
if (h == LV_SIZE_CONTENT) h = 0;
window = new SwitchChoice(
auto c = new SwitchChoice(
lvglManager->getCurrentParent(), {x, y, w, h},
vmin, vmax,
SWSRC_FIRST, SWSRC_LAST,
[=]() { return pcallGetIntVal(L, getFunction); },
[=](uint32_t val) { pcallSetIntVal(L, setFunction, val); });
c->setAvailableHandler([=](int value) {
return checkSwitchAvailable(value, filter);
});
window = c;
}
//-----------------------------------------------------------------------------
void LvglWidgetSourcePicker::parseParam(lua_State *L, const char *key)
{
if (!strcmp(key, "filter")) {
filter = luaL_checkunsigned(L, -1);
} else {
LvglWidgetPicker::parseParam(L, key);
}
}
void LvglWidgetSourcePicker::build(lua_State *L)
{
if (h == LV_SIZE_CONTENT) h = 0;
window = new SourceChoice(
auto c = new SourceChoice(
lvglManager->getCurrentParent(), {x, y, w, h},
0, MIXSRC_LAST_TELEM,
[=]() { return pcallGetIntVal(L, getFunction); },
[=](uint32_t val) { pcallSetIntVal(L, setFunction, val); },
true);
filter & SRC_INVERT);
c->setAvailableHandler([=](int value) {
return checkSourceAvailable(value, filter);
});
window = c;
}
//-----------------------------------------------------------------------------
+97 -8
View File
@@ -45,6 +45,8 @@ class LvglWidgetObjectBase
virtual void show() = 0;
virtual void hide() = 0;
virtual void enable() {};
virtual void disable() {};
virtual void setColor(LcdFlags newColor) {}
virtual void setOpacity(uint8_t newOpa) {}
@@ -91,6 +93,7 @@ class LvglWidgetObjectBase
bool pcallUpdate2Int(lua_State *L, int getFuncRef,
std::function<void(int, int)> update);
int pcallGetIntVal(lua_State *L, int getFuncRef);
int pcallGetOptIntVal(lua_State *L, int getFuncRef, int defVal);
void pcallSetIntVal(lua_State *L, int setFuncRef, int val);
};
@@ -258,16 +261,22 @@ class LvglWidgetObject : public LvglWidgetObjectBase
void show() override { window->show(); }
void hide() override { window->hide(); }
void enable() override { window->enable(); }
void disable() override { window->disable(); }
void setPos(coord_t x, coord_t y) override;
void setSize(coord_t w, coord_t h) override;
bool callRefs(lua_State *L) override;
void clearRefs(lua_State *L) override;
Window *getWindow() const override { return window; }
protected:
Window *window = nullptr;
int8_t flexFlow = -1;
int8_t flexPad = PAD_TINY;
int getActiveFunction = LUA_REFNIL;
void parseParam(lua_State *L, const char *key) override;
@@ -438,20 +447,29 @@ class LvglWidgetQRCode : public LvglWidgetObject
//-----------------------------------------------------------------------------
class LvglWidgetTextButton : public LvglWidgetObject
class LvglWidgetTextButtonBase : public LvglWidgetObject
{
public:
LvglWidgetTextButton() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
LvglWidgetTextButtonBase() : LvglWidgetObject(LVGL_SIMPLEMETATABLE)
{
color = -1; // ignore unless overridden
}
void setText(const char *s);
void setSize(coord_t w, coord_t h) override;
void setColor(LcdFlags newColor) override;
void setRounded();
void build(lua_State *L) override;
void clearRefs(lua_State *L) override;
protected:
uint32_t textHash = -1;
const char *txt = "";
LcdFlags font = FONT(STD);
coord_t rounded = -1;
LcdFlags textColor = -1;
LcdFlags currentTextColor = -1;
int pressFunction = LUA_REFNIL;
void parseParam(lua_State *L, const char *key) override;
@@ -459,6 +477,49 @@ class LvglWidgetTextButton : public LvglWidgetObject
//-----------------------------------------------------------------------------
class LvglWidgetTextButton : public LvglWidgetTextButtonBase
{
public:
LvglWidgetTextButton() : LvglWidgetTextButtonBase() {}
void setFont(LcdFlags font);
void setChecked(bool check);
void build(lua_State *L) override;
void clearRefs(lua_State *L) override;
protected:
bool checked = false;
int longPressFunction = LUA_REFNIL;
void parseParam(lua_State *L, const char *key) override;
void refresh() override
{
setChecked(checked);
LvglWidgetObject::refresh();
}
};
//-----------------------------------------------------------------------------
class LvglWidgetMomentaryButton : public LvglWidgetTextButtonBase
{
public:
LvglWidgetMomentaryButton() : LvglWidgetTextButtonBase() {}
void setFont(LcdFlags font);
void build(lua_State *L) override;
void clearRefs(lua_State *L) override;
protected:
int releaseFunction = LUA_REFNIL;
void parseParam(lua_State *L, const char *key) override;
};
//-----------------------------------------------------------------------------
class LvglWidgetToggleSwitch : public LvglWidgetObject
{
public:
@@ -516,12 +577,16 @@ class LvglWidgetNumberEdit : public LvglWidgetObject
//-----------------------------------------------------------------------------
class LvglWidgetSlider : public LvglWidgetObject
class LvglWidgetSliderBase : public LvglWidgetObject
{
public:
LvglWidgetSlider() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
LvglWidgetSliderBase() : LvglWidgetObject(LVGL_SIMPLEMETATABLE)
{
color = -1;
}
void setColor(LcdFlags newColor) override;
void build(lua_State *L) override;
void clearRefs(lua_State *L) override;
protected:
@@ -535,6 +600,26 @@ class LvglWidgetSlider : public LvglWidgetObject
//-----------------------------------------------------------------------------
class LvglWidgetSlider : public LvglWidgetSliderBase
{
public:
LvglWidgetSlider() : LvglWidgetSliderBase() {}
void build(lua_State *L) override;
};
//-----------------------------------------------------------------------------
class LvglWidgetVerticalSlider : public LvglWidgetSliderBase
{
public:
LvglWidgetVerticalSlider() : LvglWidgetSliderBase() {}
void build(lua_State *L) override;
};
//-----------------------------------------------------------------------------
class LvglWidgetPage : public LvglWidgetObject
{
public:
@@ -690,8 +775,7 @@ class LvglWidgetSwitchPicker : public LvglWidgetPicker
void build(lua_State *L) override;
protected:
int16_t vmin = SWSRC_FIRST;
int16_t vmax = SWSRC_LAST;
uint32_t filter = 0xFFFFFFFF;
void parseParam(lua_State *L, const char *key) override;
};
@@ -704,6 +788,11 @@ class LvglWidgetSourcePicker : public LvglWidgetPicker
LvglWidgetSourcePicker() : LvglWidgetPicker() {}
void build(lua_State *L) override;
protected:
uint32_t filter = 0xFFFFFFFF;
void parseParam(lua_State *L, const char *key) override;
};
//-----------------------------------------------------------------------------
+10 -8
View File
@@ -171,7 +171,7 @@ void LuaEventHandler::onCancel() {
luaPushEvent(EVT_KEY_BREAK(KEY_EXIT));
}
void LuaEventHandler::onEvent(event_t event)
void LuaEventHandler::onLuaEvent(event_t event)
{
luaPushEvent(event);
}
@@ -223,11 +223,13 @@ void LuaWidget::redraw_cb(lv_event_t* e)
LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent,
const rect_t& rect, WidgetPersistentData* persistentData,
int luaWidgetDataRef, int zoneRectDataRef, int optionsDataRef) :
int luaScriptContextRef, int zoneRectDataRef, int optionsDataRef) :
Widget(factory, parent, rect, persistentData),
zoneRectDataRef(zoneRectDataRef), optionsDataRef(optionsDataRef), luaWidgetDataRef(luaWidgetDataRef),
zoneRectDataRef(zoneRectDataRef), optionsDataRef(optionsDataRef),
errorMessage(nullptr)
{
this->luaScriptContextRef = luaScriptContextRef;
if (useLvglLayout()) {
update();
} else {
@@ -238,7 +240,7 @@ LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent,
LuaWidget::~LuaWidget()
{
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef);
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, luaScriptContextRef);
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef);
free(errorMessage);
}
@@ -318,7 +320,7 @@ void LuaWidget::update()
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaFactory()->updateFunction);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaScriptContextRef);
// Get options table and update values
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionsDataRef);
@@ -472,7 +474,7 @@ void LuaWidget::refresh(BitmapBuffer* dc)
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaFactory()->refreshFunction);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaScriptContextRef);
// Pass key event to fullscreen Lua widget
LuaEventData evt;
@@ -518,7 +520,7 @@ void LuaWidget::background()
if (luaFactory()->backgroundFunction) {
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaFactory()->backgroundFunction);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef);
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaScriptContextRef);
runningFS = this;
if (lua_pcall(lsWidgets, 1, 0, 0) != 0) {
setErrorMessage("background()");
@@ -530,7 +532,7 @@ void LuaWidget::background()
void LuaWidget::onEvent(event_t event)
{
if (fullscreen) {
LuaEventHandler::onEvent(event);
LuaEventHandler::onLuaEvent(event);
}
Widget::onEvent(event);
}
+20 -13
View File
@@ -48,24 +48,34 @@ class LuaLvglManager
void setTempParent(LvglWidgetObjectBase *p) { tempParent = p; }
LvglWidgetObjectBase* getTempParent() const { return tempParent; }
int getContext() const { return luaScriptContextRef; }
virtual Window* getCurrentParent() const = 0;
virtual void clear() = 0;
virtual bool useLvglLayout() const = 0;
virtual bool isAppMode() const = 0;
virtual bool isWidget() = 0;
virtual bool isFullscreen() = 0;
virtual void exitFullscreen() {}
virtual void luaShowError() = 0;
virtual bool isWidget() = 0;
uint8_t refreshInstructionsPercent;
protected:
int luaScriptContextRef = 0;
std::vector<int> lvglObjectRefs;
LvglWidgetObjectBase* tempParent = nullptr;
};
class LuaEventHandler
{
public:
LuaEventHandler() = default;
void setupHandler(Window* w);
void removeHandler(Window* w);
protected:
#if defined(HARDWARE_TOUCH)
// "tap" handling
static uint32_t downTime;
@@ -79,15 +89,9 @@ class LuaEventHandler
#endif
static void event_cb(lv_event_t* e);
protected:
void onClicked();
void onCancel();
void onEvent(event_t event);
public:
LuaEventHandler() = default;
void setupHandler(Window* w);
void removeHandler(Window* w);
void onLuaEvent(event_t event);
};
class LuaWidget : public Widget, public LuaEventHandler, public LuaLvglManager
@@ -96,7 +100,7 @@ class LuaWidget : public Widget, public LuaEventHandler, public LuaLvglManager
public:
LuaWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
WidgetPersistentData* persistentData, int luaWidgetDataRef, int zoneRectDataRef,
WidgetPersistentData* persistentData, int luaScriptContextRef, int zoneRectDataRef,
int optionsDataRef);
~LuaWidget() override;
@@ -119,19 +123,22 @@ class LuaWidget : public Widget, public LuaEventHandler, public LuaLvglManager
bool useLvglLayout() const override;
bool isAppMode() const override;
bool isWidget() override { return !inSettings; }
bool isFullscreen() override { return Widget::isFullscreen(); }
void exitFullscreen() override { closeFullscreen(); }
// Should rotary encoder events be enabled when full screen
bool enableFullScreenRE() const override { return !useLvglLayout(); }
void luaShowError() override {}
void pushOptionsTable();
bool isWidget() override { return !inSettings; }
protected:
bool inSettings = false;
lv_obj_t* errorLabel = nullptr;
int zoneRectDataRef;
int optionsDataRef;
int luaWidgetDataRef = 0;
char* errorMessage;
bool refreshed = false;
-1
View File
@@ -109,7 +109,6 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect,
return lw;
}
void LuaWidgetFactory::translateOptions(ZoneOption * options)
{
if (lsWidgets == 0) return;
+1
View File
@@ -38,6 +38,7 @@
#define LUA_WARNING_INFO_LEN 64
lua_State * lsWidgets = NULL;
uint8_t instructionsPercent = 0;
extern int custom_lua_atpanic(lua_State *L);