diff --git a/radio/src/lua/api_colorlcd_lvgl.cpp b/radio/src/lua/api_colorlcd_lvgl.cpp index ba365c248..f43870065 100644 --- a/radio/src/lua/api_colorlcd_lvgl.cpp +++ b/radio/src/lua/api_colorlcd_lvgl.cpp @@ -237,6 +237,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, "file") == 0) + obj = new LvglWidgetFilePicker(); else if (strcasecmp(p.type, "setting") == 0) obj = new LvglWidgetSetting(); } @@ -358,6 +360,7 @@ LROT_BEGIN(lvgllib, NULL, 0) LROT_FUNCENTRY(timer, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTimerPicker(); }, true); }) LROT_FUNCENTRY(switch, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSwitchPicker(); }, true); }) LROT_FUNCENTRY(source, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSourcePicker(); }, true); }) + LROT_FUNCENTRY(file, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetFilePicker(); }, true); }) // Containers LROT_FUNCENTRY(box, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetBox(); }); }) LROT_FUNCENTRY(setting, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSetting(); }, true); }) @@ -446,6 +449,7 @@ LROT_BEGIN(lvgl_mt, NULL, LROT_MASK_GC_INDEX) LROT_FUNCENTRY(timer, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTimerPicker(); }, true); }) LROT_FUNCENTRY(switch, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSwitchPicker(); }, true); }) LROT_FUNCENTRY(source, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSourcePicker(); }, true); }) + LROT_FUNCENTRY(file, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetFilePicker(); }, true); }) // Containers LROT_FUNCENTRY(box, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetBox(); }); }) LROT_FUNCENTRY(setting, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetSetting(); }, true); }) diff --git a/radio/src/lua/lua_lvgl_widget.cpp b/radio/src/lua/lua_lvgl_widget.cpp index 88571fcf9..b5d9a0fcb 100644 --- a/radio/src/lua/lua_lvgl_widget.cpp +++ b/radio/src/lua/lua_lvgl_widget.cpp @@ -28,6 +28,7 @@ #include "sourcechoice.h" #include "switchchoice.h" #include "toggleswitch.h" +#include "filechoice.h" //----------------------------------------------------------------------------- @@ -327,6 +328,54 @@ void LvglWidgetObjectBase::pcallSetIntVal(lua_State *L, int setFuncRef, int val) } } +const char* LvglWidgetObjectBase::pcallGetStringVal(lua_State *L, int getFuncRef) +{ + const char* val = nullptr; + if (getFuncRef != LUA_REFNIL) { + auto save = luaScriptManager; + luaScriptManager = lvglManager; + int t = lua_gettop(L); + PROTECT_LUA() + { + if (pcallFunc(L, getFuncRef, 1)) { + val = luaL_checkstring(L, -1); + } else { + lvglManager->luaShowError(); + } + } + else + { + lvglManager->luaShowError(); + } + UNPROTECT_LUA(); + lua_settop(L, t); + lvglManager = save; + } + return val; +} + +void LvglWidgetObjectBase::pcallSetStringVal(lua_State *L, int setFuncRef, const char* val) +{ + if (setFuncRef != LUA_REFNIL) { + auto save = luaScriptManager; + luaScriptManager = lvglManager; + int t = lua_gettop(L); + PROTECT_LUA() + { + if (!pcallFuncWithString(L, setFuncRef, 0, val)) { + lvglManager->luaShowError(); + } + } + else + { + lvglManager->luaShowError(); + } + UNPROTECT_LUA(); + lua_settop(L, t); + lvglManager = save; + } +} + void LvglWidgetObjectBase::parseParam(lua_State *L, const char *key) { if (!strcmp(key, "x")) { @@ -2231,3 +2280,34 @@ void LvglWidgetSourcePicker::build(lua_State *L) } //----------------------------------------------------------------------------- + +void LvglWidgetFilePicker::parseParam(lua_State *L, const char *key) +{ + if (!strcmp(key, "title")) { + title = luaL_checkstring(L, -1); + } else if (!strcmp(key, "folder")) { + folder = luaL_checkstring(L, -1); + } else if (!strcmp(key, "extension")) { + extension = luaL_checkstring(L, -1); + } else if (!strcmp(key, "maxLen")) { + maxLen = luaL_checkunsigned(L, -1); + } else if (!strcmp(key, "hideExtension")) { + hideExtension = lua_toboolean(L, -1); + } else { + LvglWidgetPicker::parseParam(L, key); + } +} + +void LvglWidgetFilePicker::build(lua_State *L) +{ + if (h == LV_SIZE_CONTENT) h = 0; + auto c = new FileChoice( + lvglManager->getCurrentParent(), {x, y, w, h}, + folder, extension, maxLen, + [=]() { return pcallGetStringVal(L, getFunction); }, + [=](std::string val) { pcallSetStringVal(L, setFunction, val.c_str()); }, + hideExtension, title); + window = c; +} + +//----------------------------------------------------------------------------- diff --git a/radio/src/lua/lua_lvgl_widget.h b/radio/src/lua/lua_lvgl_widget.h index 8a070ee21..f145d8b51 100644 --- a/radio/src/lua/lua_lvgl_widget.h +++ b/radio/src/lua/lua_lvgl_widget.h @@ -122,6 +122,8 @@ class LvglWidgetObjectBase 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); + const char* pcallGetStringVal(lua_State *L, int getFuncRef); + void pcallSetStringVal(lua_State *L, int setFuncRef, const char* val); }; //----------------------------------------------------------------------------- @@ -841,3 +843,21 @@ class LvglWidgetSourcePicker : public LvglWidgetPicker }; //----------------------------------------------------------------------------- + +class LvglWidgetFilePicker : public LvglWidgetPicker +{ + public: + LvglWidgetFilePicker() : LvglWidgetPicker() {} + + protected: + const char *title = nullptr; + const char* folder = nullptr; + const char* extension = nullptr; + int maxLen = 255; + bool hideExtension = false; + + void build(lua_State *L) override; + void parseParam(lua_State *L, const char *key) override; +}; + +//-----------------------------------------------------------------------------