From ecfa1e1b5b82be2d5d954de562513c2d114c0e6a Mon Sep 17 00:00:00 2001 From: philmoz Date: Wed, 11 Sep 2024 16:20:37 +1000 Subject: [PATCH] feat(color): add Slider & Choice widget option types (#5518) --- .../src/firmwares/customisation_data.cpp | 5 - companion/src/firmwares/customisation_data.h | 5 +- radio/src/gui/colorlcd/libui/dialog.cpp | 2 +- radio/src/gui/colorlcd/mainview/widget.cpp | 2 +- .../gui/colorlcd/mainview/widget_settings.cpp | 83 ++++++++------ .../gui/colorlcd/mainview/widget_settings.h | 4 +- .../gui/colorlcd/mainview/widgets_setup.cpp | 4 +- radio/src/gui/colorlcd/mainview/zone.h | 12 +- radio/src/lua/api_colorlcd_lvgl.cpp | 103 +++--------------- radio/src/lua/api_general.cpp | 14 ++- radio/src/lua/interface.cpp | 14 +++ radio/src/lua/lua_api.h | 2 + radio/src/lua/lua_event.cpp | 16 +-- radio/src/lua/lua_lvgl_widget.cpp | 2 +- radio/src/lua/lua_widget.cpp | 45 ++++---- radio/src/lua/lua_widget.h | 4 +- radio/src/lua/lua_widget_factory.cpp | 35 +++--- radio/src/lua/widgets.cpp | 47 +++----- radio/src/translations.cpp | 1 - radio/src/translations.h | 1 - radio/src/translations/cn.h | 1 - radio/src/translations/cz.h | 2 - radio/src/translations/da.h | 1 - radio/src/translations/de.h | 1 - radio/src/translations/en.h | 1 - radio/src/translations/es.h | 1 - radio/src/translations/fi.h | 2 - radio/src/translations/fr.h | 2 - radio/src/translations/he.h | 1 - radio/src/translations/it.h | 1 - radio/src/translations/jp.h | 1 - radio/src/translations/nl.h | 1 - radio/src/translations/pl.h | 1 - radio/src/translations/pt.h | 1 - radio/src/translations/ru.h | 1 - radio/src/translations/se.h | 2 - radio/src/translations/tw.h | 1 - radio/src/translations/ua.h | 1 - 38 files changed, 165 insertions(+), 258 deletions(-) diff --git a/companion/src/firmwares/customisation_data.cpp b/companion/src/firmwares/customisation_data.cpp index 2ecb27a1e..50e8a84c8 100644 --- a/companion/src/firmwares/customisation_data.cpp +++ b/companion/src/firmwares/customisation_data.cpp @@ -70,7 +70,6 @@ inline void setZoneOptionValue(ZoneOptionValue& zov, unsigned int value) inline ZoneOptionValueEnum zoneValueEnumFromType(ZoneOption::Type type) { switch(type) { - case ZoneOption::File: case ZoneOption::String: return ZOV_String; @@ -86,10 +85,6 @@ inline ZoneOptionValueEnum zoneValueEnumFromType(ZoneOption::Type type) case ZoneOption::Source: return ZOV_Source; - case ZoneOption::Timer: - case ZoneOption::Switch: - case ZoneOption::TextSize: - case ZoneOption::Align: default: return ZOV_Unsigned; } diff --git a/companion/src/firmwares/customisation_data.h b/companion/src/firmwares/customisation_data.h index c51a8adcc..911e01575 100644 --- a/companion/src/firmwares/customisation_data.h +++ b/companion/src/firmwares/customisation_data.h @@ -90,12 +90,13 @@ struct ZoneOption Source, Bool, String, - File, TextSize, Timer, Switch, Color, - Align + Align, + Slider, + Choice, }; const char * name; diff --git a/radio/src/gui/colorlcd/libui/dialog.cpp b/radio/src/gui/colorlcd/libui/dialog.cpp index f0925ae3d..b8123bd62 100644 --- a/radio/src/gui/colorlcd/libui/dialog.cpp +++ b/radio/src/gui/colorlcd/libui/dialog.cpp @@ -58,7 +58,7 @@ BaseDialog::BaseDialog(Window* parent, const char* title, form = new BaseDialogForm(content, width); if (maxHeight != LV_SIZE_CONTENT) - lv_obj_set_style_max_height(form->getLvObj(), maxHeight - 32, LV_PART_MAIN); + lv_obj_set_style_max_height(form->getLvObj(), maxHeight - EdgeTxStyles::UI_ELEMENT_HEIGHT, LV_PART_MAIN); } void BaseDialog::setTitle(const char* title) diff --git a/radio/src/gui/colorlcd/mainview/widget.cpp b/radio/src/gui/colorlcd/mainview/widget.cpp index 4012ea79d..41c6a60c7 100644 --- a/radio/src/gui/colorlcd/mainview/widget.cpp +++ b/radio/src/gui/colorlcd/mainview/widget.cpp @@ -69,7 +69,7 @@ void Widget::openMenu() } if (getOptions() && getOptions()->name) { menu->addLine(STR_WIDGET_SETTINGS, - [=]() { new WidgetSettings(this, this); }); + [=]() { new WidgetSettings(this); }); } } } diff --git a/radio/src/gui/colorlcd/mainview/widget_settings.cpp b/radio/src/gui/colorlcd/mainview/widget_settings.cpp index 360039029..0e978f501 100644 --- a/radio/src/gui/colorlcd/mainview/widget_settings.cpp +++ b/radio/src/gui/colorlcd/mainview/widget_settings.cpp @@ -42,7 +42,7 @@ static const lv_coord_t line_col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), static const lv_coord_t line_row_dsc[] = {LV_GRID_CONTENT, LV_GRID_TEMPLATE_LAST}; -WidgetSettings::WidgetSettings(Window* parent, Widget* w) : +WidgetSettings::WidgetSettings(Widget* w) : BaseDialog(ViewMain::instance(), w->getFactory()->getDisplayName(), true), widget(w) { FlexGridLayout grid(line_col_dsc, line_row_dsc); @@ -50,37 +50,38 @@ WidgetSettings::WidgetSettings(Window* parent, Widget* w) : form->padRow(PAD_ZERO); uint8_t optIdx = 0; - auto optPtr = widget->getOptions(); - while (optPtr && optPtr->name != nullptr) { + auto opt = widget->getOptions(); + while (opt && opt->name != nullptr) { auto line = form->newLine(grid); - auto option = *optPtr; new StaticText(line, rect_t{}, - option.displayName ? option.displayName : option.name); + opt->displayName ? opt->displayName : opt->name); - switch (option.type) { + auto optVal = widget->getOptionValue(optIdx); + + switch (opt->type) { case ZoneOption::Integer: (new NumberEdit( - line, rect_t{0, 0, 96, 0}, option.min.signedValue, - option.max.signedValue, + line, rect_t{0, 0, 96, 0}, opt->min.signedValue, + opt->max.signedValue, [=]() -> int { - return widget->getOptionValue(optIdx)->signedValue; + return optVal->signedValue; }, [=](int32_t newValue) { - widget->getOptionValue(optIdx)->signedValue = newValue; + optVal->signedValue = newValue; SET_DIRTY(); })) - ->setDefault(option.deflt.signedValue); + ->setDefault(opt->deflt.signedValue); break; case ZoneOption::Source: new SourceChoice( line, rect_t{}, 0, MIXSRC_LAST_TELEM, [=]() -> int16_t { - return (int16_t)widget->getOptionValue(optIdx)->unsignedValue; + return (int16_t)optVal->unsignedValue; }, [=](int16_t newValue) { - widget->getOptionValue(optIdx)->unsignedValue = + optVal->unsignedValue = (uint32_t)newValue; SET_DIRTY(); }); @@ -90,31 +91,28 @@ WidgetSettings::WidgetSettings(Window* parent, Widget* w) : new ToggleSwitch( line, rect_t{}, [=]() -> uint8_t { - return (uint8_t)widget->getOptionValue(optIdx)->boolValue; + return (uint8_t)optVal->boolValue; }, [=](int8_t newValue) { - widget->getOptionValue(optIdx)->boolValue = newValue; + optVal->boolValue = newValue; SET_DIRTY(); }); break; case ZoneOption::String: new ModelTextEdit(line, rect_t{0, 0, 96, 0}, - widget->getOptionValue(optIdx)->stringValue, - sizeof(widget->getOptionValue(optIdx)->stringValue)); - break; - - case ZoneOption::File: + optVal->stringValue, + sizeof(optVal->stringValue)); break; case ZoneOption::TextSize: new Choice( line, rect_t{}, STR_FONT_SIZES, 0, FONTS_COUNT - 1, [=]() -> int { // getValue - return (int)widget->getOptionValue(optIdx)->unsignedValue; + return (int)optVal->unsignedValue; }, [=](int newValue) { // setValue - widget->getOptionValue(optIdx)->unsignedValue = + optVal->unsignedValue = (uint32_t)newValue; SET_DIRTY(); }); @@ -124,10 +122,10 @@ WidgetSettings::WidgetSettings(Window* parent, Widget* w) : new Choice( line, rect_t{}, STR_ALIGN_OPTS, 0, ALIGN_COUNT - 1, [=]() -> int { // getValue - return (int)widget->getOptionValue(optIdx)->unsignedValue; + return (int)optVal->unsignedValue; }, [=](int newValue) { // setValue - widget->getOptionValue(optIdx)->unsignedValue = + optVal->unsignedValue = (uint32_t)newValue; SET_DIRTY(); }); @@ -138,10 +136,10 @@ WidgetSettings::WidgetSettings(Window* parent, Widget* w) : auto tmChoice = new Choice( line, rect_t{}, 0, TIMERS - 1, [=]() -> int { // getValue - return (int)widget->getOptionValue(optIdx)->unsignedValue; + return (int)optVal->unsignedValue; }, [=](int newValue) { // setValue - widget->getOptionValue(optIdx)->unsignedValue = + optVal->unsignedValue = (uint32_t)newValue; SET_DIRTY(); }); @@ -154,13 +152,13 @@ WidgetSettings::WidgetSettings(Window* parent, Widget* w) : case ZoneOption::Switch: new SwitchChoice( line, rect_t{}, - option.min.signedValue, // min - option.max.signedValue, // max + opt->min.signedValue, // min + opt->max.signedValue, // max [=]() -> int16_t { // getValue - return widget->getOptionValue(optIdx)->signedValue; + return optVal->signedValue; }, [=](int16_t newValue) { // setValue - widget->getOptionValue(optIdx)->signedValue = newValue; + optVal->signedValue = newValue; SET_DIRTY(); }); break; @@ -169,17 +167,36 @@ WidgetSettings::WidgetSettings(Window* parent, Widget* w) : new ColorPicker( line, rect_t{}, [=]() -> uint32_t { // getValue - return widget->getOptionValue(optIdx)->unsignedValue; + return optVal->unsignedValue; }, [=](uint32_t newValue) { // setValue - widget->getOptionValue(optIdx)->unsignedValue = newValue; + optVal->unsignedValue = newValue; + SET_DIRTY(); + }); + break; + + case ZoneOption::Slider: + new Slider( + line, SLIDER_W, opt->min.signedValue, opt->max.signedValue, + [=]() { return optVal->unsignedValue; }, + [=](uint32_t newValue) { + optVal->unsignedValue = newValue; + SET_DIRTY(); + }); + break; + + case ZoneOption::Choice: + new Choice(line, rect_t{}, opt->choiceValues, 0, opt->choiceValues.size() - 1, + [=]() { return optVal->unsignedValue - 1; }, + [=](uint32_t newValue) { + optVal->unsignedValue = newValue + 1; SET_DIRTY(); }); break; } optIdx++; - optPtr++; + opt++; } } diff --git a/radio/src/gui/colorlcd/mainview/widget_settings.h b/radio/src/gui/colorlcd/mainview/widget_settings.h index be43931ca..a10d96729 100644 --- a/radio/src/gui/colorlcd/mainview/widget_settings.h +++ b/radio/src/gui/colorlcd/mainview/widget_settings.h @@ -27,7 +27,9 @@ class WidgetSettings : public BaseDialog { public: - WidgetSettings(Window* parent, Widget* widget); + WidgetSettings(Widget* widget); + + static LAYOUT_VAL(SLIDER_W, 150, 120) protected: Widget* widget; diff --git a/radio/src/gui/colorlcd/mainview/widgets_setup.cpp b/radio/src/gui/colorlcd/mainview/widgets_setup.cpp index 6f8097a41..4d3f30d8b 100644 --- a/radio/src/gui/colorlcd/mainview/widgets_setup.cpp +++ b/radio/src/gui/colorlcd/mainview/widgets_setup.cpp @@ -43,7 +43,7 @@ SetupWidgetsPageSlot::SetupWidgetsPageSlot(Window* parent, const rect_t& rect, auto widget = container->getWidget(slotIndex); if (widget->getOptions() && widget->getOptions()->name) menu->addLine(STR_WIDGET_SETTINGS, - [=]() { new WidgetSettings(parent, widget); }); + [=]() { new WidgetSettings(widget); }); menu->addLine(STR_REMOVE_WIDGET, [=]() { container->removeWidget(slotIndex); }); } else { @@ -104,7 +104,7 @@ void SetupWidgetsPageSlot::addNewWidget(WidgetsContainer* container, container->createWidget(slotIndex, factory); auto widget = container->getWidget(slotIndex); if (widget->getOptions() && widget->getOptions()->name) - new WidgetSettings(parent, widget); + new WidgetSettings(widget); }); if (cur && strcmp(cur, factory->getDisplayName()) == 0) selected = index; diff --git a/radio/src/gui/colorlcd/mainview/zone.h b/radio/src/gui/colorlcd/mainview/zone.h index 789083fda..6bd2577eb 100644 --- a/radio/src/gui/colorlcd/mainview/zone.h +++ b/radio/src/gui/colorlcd/mainview/zone.h @@ -23,6 +23,7 @@ #include #include "storage/yaml/yaml_defs.h" +#include #define LEN_ZONE_OPTION_STRING 8 @@ -64,12 +65,13 @@ struct ZoneOption Source, Bool, String, - File, TextSize, Timer, Switch, Color, - Align + Align, + Slider, + Choice, }; const char * name; @@ -78,6 +80,7 @@ struct ZoneOption ZoneOptionValue min; ZoneOptionValue max; const char * displayName; + std::vector choiceValues; }; enum ZoneOptionAlign @@ -99,7 +102,6 @@ struct ZoneOptionValueTyped inline ZoneOptionValueEnum zoneValueEnumFromType(ZoneOption::Type type) { switch(type) { - case ZoneOption::File: case ZoneOption::String: return ZOV_String; @@ -115,10 +117,6 @@ inline ZoneOptionValueEnum zoneValueEnumFromType(ZoneOption::Type type) case ZoneOption::Color: return ZOV_Color; - case ZoneOption::Timer: - case ZoneOption::Switch: - case ZoneOption::TextSize: - case ZoneOption::Align: default: return ZOV_Unsigned; } diff --git a/radio/src/lua/api_colorlcd_lvgl.cpp b/radio/src/lua/api_colorlcd_lvgl.cpp index 6c1de047a..a4b4bebfa 100644 --- a/radio/src/lua/api_colorlcd_lvgl.cpp +++ b/radio/src/lua/api_colorlcd_lvgl.cpp @@ -71,76 +71,6 @@ static int luaLvglObjEx(lua_State *L, std::function create, return 1; } -static int luaLvglLabel(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetLabel(); }); -} - -static int luaLvglRectangle(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetRectangle(); }); -} - -static int luaLvglCircle(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetCircle(); }); -} - -static int luaLvglArc(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetArc(); }); -} - -static int luaLvglImage(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetImage(); }); -} - -static int luaLvglQRCode(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetQRCode(); }); -} - -// static int luaLvglMeter(lua_State *L) -// { -// return luaLvglObjEx(L, [=]() { return new LvglWidgetMeter(); }); -// } - -static int luaLvglButton(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetTextButton(); }, true); -} - -static int luaLvglToggle(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetToggleSwitch(); }, true); -} - -static int luaLvglTextEdit(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetTextEdit(); }, true); -} - -static int luaLvglNumberEdit(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetNumberEdit(); }, true); -} - -static int luaLvglChoice(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetChoice(); }, true); -} - -static int luaLvglSlider(lua_State *L) -{ - return luaLvglObjEx(L, [=]() { return new LvglWidgetSlider(); }, true); -} - -static int luaLvglPage(lua_State *L) -{ - return luaLvglObj(L, [=]() { return new LvglWidgetPage(); }, true); -} - static int luaLvglConfirm(lua_State *L) { auto obj = new LvglWidgetConfirmDialog(); @@ -316,22 +246,25 @@ LROT_FUNCENTRY(__gc, luaDestroyLvglWidget) LROT_TABENTRY(__index, lvgllib) LROT_FUNCENTRY(clear, luaLvglClear) LROT_FUNCENTRY(build, luaLvglBuild) -// Objects -LROT_FUNCENTRY(label, luaLvglLabel) -LROT_FUNCENTRY(rectangle, luaLvglRectangle) -LROT_FUNCENTRY(circle, luaLvglCircle) -LROT_FUNCENTRY(arc, luaLvglArc) -LROT_FUNCENTRY(image, luaLvglImage) -LROT_FUNCENTRY(qrcode, luaLvglQRCode) -// LROT_FUNCENTRY(meter, luaLvglMeter) -LROT_FUNCENTRY(button, luaLvglButton) -LROT_FUNCENTRY(toggle, luaLvglToggle) +// Objects - widgets and standalone +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(circle, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetCircle(); }); }) +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(); }); }) +// LROT_FUNCENTRY(meter, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetMeter(); }); }) +// Objects - standalone scripts only +LROT_FUNCENTRY(button, [](lua_State* L) { return luaLvglObjEx(L, []() { return new LvglWidgetTextButton(); }, 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); }) +// Containers +LROT_FUNCENTRY(page, [](lua_State* L) { return luaLvglObj(L, []() { return new LvglWidgetPage(); }, true); }) +// Dialogs LROT_FUNCENTRY(confirm, luaLvglConfirm) -LROT_FUNCENTRY(textEdit, luaLvglTextEdit) -LROT_FUNCENTRY(numberEdit, luaLvglNumberEdit) -LROT_FUNCENTRY(choice, luaLvglChoice) -LROT_FUNCENTRY(slider, luaLvglSlider) -LROT_FUNCENTRY(page, luaLvglPage) // Manipulation functions LROT_FUNCENTRY(set, luaLvglSet) LROT_FUNCENTRY(show, luaLvglShow) diff --git a/radio/src/lua/api_general.cpp b/radio/src/lua/api_general.cpp index 05d00f947..fec73833a 100644 --- a/radio/src/lua/api_general.cpp +++ b/radio/src/lua/api_general.cpp @@ -3018,26 +3018,24 @@ LROT_BEGIN(etxcst, NULL, 0) // Constants LROT_NUMENTRY( FULLSCALE, RESX ) #if defined(COLORLCD) + LROT_NUMENTRY( STDSIZE, FONT(STD) ) LROT_NUMENTRY( XXLSIZE, FONT(XXL) ) LROT_NUMENTRY( DBLSIZE, FONT(XL) ) LROT_NUMENTRY( MIDSIZE, FONT(L) ) LROT_NUMENTRY( SMLSIZE, FONT(XS) ) LROT_NUMENTRY( TINSIZE, FONT(XXS) ) + LROT_NUMENTRY( STDBOLD, FONT(BOLD) ) LROT_NUMENTRY( BLINK, BLINK ) LROT_NUMENTRY( INVERS, INVERS ) + LROT_NUMENTRY( VCENTER, VCENTERED ) #else LROT_NUMENTRY( XXLSIZE, XXLSIZE ) LROT_NUMENTRY( DBLSIZE, DBLSIZE ) LROT_NUMENTRY( MIDSIZE, MIDSIZE ) LROT_NUMENTRY( SMLSIZE, SMLSIZE ) + LROT_NUMENTRY( BOLD, BOLD ) LROT_NUMENTRY( BLINK, BLINK ) LROT_NUMENTRY( INVERS, INVERS ) -#endif -#if defined(COLORLCD) - LROT_NUMENTRY( BOLD, FONT(BOLD) ) - LROT_NUMENTRY( VCENTER, VCENTERED ) -#else - LROT_NUMENTRY( BOLD, BOLD ) #endif LROT_NUMENTRY( RIGHT, RIGHT ) LROT_NUMENTRY( LEFT, LEFT ) @@ -3113,6 +3111,10 @@ LROT_BEGIN(etxcst, NULL, 0) LROT_NUMENTRY( TEXT_SIZE, ZoneOption::TextSize ) LROT_NUMENTRY( ALIGNMENT, ZoneOption::Align ) LROT_NUMENTRY( SWITCH, ZoneOption::Switch ) + LROT_NUMENTRY( INTVAL, ZoneOption::Integer ) + LROT_NUMENTRY( SRCVAL, ZoneOption::Source ) + LROT_NUMENTRY( SLIDER, ZoneOption::Slider ) + LROT_NUMENTRY( CHOICE, ZoneOption::Choice ) LROT_NUMENTRY( MENU_HEADER_HEIGHT, COLOR2FLAGS(EdgeTxStyles::MENU_HEADER_HEIGHT) ) // Colors gui/colorlcd/colors.h diff --git a/radio/src/lua/interface.cpp b/radio/src/lua/interface.cpp index efd3ac63b..b75fe8532 100644 --- a/radio/src/lua/interface.cpp +++ b/radio/src/lua/interface.cpp @@ -1418,3 +1418,17 @@ bool isRadioScriptTool(const char * filename) const char * ext = getFileExtension(filename); return ext && !strcasecmp(ext, SCRIPT_EXT); } + +void l_pushtableint(lua_State* ls, const char * key, int value) +{ + lua_pushstring(ls, key); + lua_pushinteger(ls, value); + lua_settable(ls, -3); +} + +void l_pushtablebool(lua_State* ls, const char * key, bool value) +{ + lua_pushstring(ls, key); + lua_pushboolean(ls, value); + lua_settable(ls, -3); +} diff --git a/radio/src/lua/lua_api.h b/radio/src/lua/lua_api.h index 9796a411d..17d19dfc7 100644 --- a/radio/src/lua/lua_api.h +++ b/radio/src/lua/lua_api.h @@ -248,6 +248,8 @@ struct LuaMemTracer { void * tracer_alloc(void * ud, void * ptr, size_t osize, size_t nsize); +void l_pushtableint(lua_State* ls, const char * key, int value); +void l_pushtablebool(lua_State* ls, const char * key, bool value); #else // defined(LUA) diff --git a/radio/src/lua/lua_event.cpp b/radio/src/lua/lua_event.cpp index 3ac789dbd..31dfcbded 100644 --- a/radio/src/lua/lua_event.cpp +++ b/radio/src/lua/lua_event.cpp @@ -20,12 +20,12 @@ */ #include "lua_event.h" +#include "lua_api.h" #include "edgetx_helpers.h" #include "board_common.h" #include "timers_driver.h" #include "keys.h" - extern "C" { #include "lua.h" }; @@ -83,20 +83,6 @@ LuaEventData* luaGetEventSlot(event_t event) static tmr10ms_t _swipeTimeOut = 0; -static void l_pushtableint(lua_State* ls, const char * key, int value) -{ - lua_pushstring(ls, key); - lua_pushinteger(ls, value); - lua_settable(ls, -3); -} - -static void l_pushtablebool(lua_State* ls, const char * key, bool value) -{ - lua_pushstring(ls, key); - lua_pushboolean(ls, value); - lua_settable(ls, -3); -} - void luaPushTouchEventTable(lua_State* ls, LuaEventData* evt) { lua_newtable(ls); diff --git a/radio/src/lua/lua_lvgl_widget.cpp b/radio/src/lua/lua_lvgl_widget.cpp index 549299c07..bc4c27d9f 100644 --- a/radio/src/lua/lua_lvgl_widget.cpp +++ b/radio/src/lua/lua_lvgl_widget.cpp @@ -50,7 +50,7 @@ void LvglWidgetObjectBase::pcallSimpleFunc(lua_State *L, int funcRef) if (funcRef) { PROTECT_LUA() { - if (!pcallFunc(L, funcRef, 1)) { + if (!pcallFunc(L, funcRef, 0)) { lvglManager->luaShowError(); } } diff --git a/radio/src/lua/lua_widget.cpp b/radio/src/lua/lua_widget.cpp index 677194c17..6819ea469 100644 --- a/radio/src/lua/lua_widget.cpp +++ b/radio/src/lua/lua_widget.cpp @@ -219,9 +219,9 @@ 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 luaWidgetDataRef, int zoneRectDataRef, int optionsDataRef) : Widget(factory, parent, rect, persistentData), - zoneRectDataRef(zoneRectDataRef), + zoneRectDataRef(zoneRectDataRef), optionsDataRef(optionsDataRef), errorMessage(nullptr) { this->luaWidgetDataRef = luaWidgetDataRef; @@ -304,13 +304,6 @@ void LuaWidget::checkEvents() #endif } -static void l_pushtableint(const char* key, int value) -{ - lua_pushstring(lsWidgets, key); - lua_pushinteger(lsWidgets, value); - lua_settable(lsWidgets, -3); -} - void LuaWidget::update() { Widget::update(); @@ -321,24 +314,28 @@ void LuaWidget::update() lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaFactory()->updateFunction); lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef); - lua_newtable(lsWidgets); + // Get options table and update values + lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionsDataRef); int i = 0; for (const ZoneOption* option = getOptions(); option->name; option++, i++) { - if (option->type == ZoneOption::String) { - lua_pushstring(lsWidgets, option->name); - char str[LEN_ZONE_OPTION_STRING + 1] = { - 0}; // Zero-terminated string for Lua - strncpy(str, persistentData->options[i].value.stringValue, - LEN_ZONE_OPTION_STRING); - lua_pushstring(lsWidgets, &str[0]); - lua_settable(lsWidgets, -3); - } else if (option->type == ZoneOption::Color) { - int32_t value = persistentData->options[i].value.unsignedValue; - l_pushtableint(option->name, value); - } else { - int32_t value = persistentData->options[i].value.signedValue; - l_pushtableint(option->name, value); + auto optVal = getOptionValue(i); + switch (option->type) { + case ZoneOption::String: + { + char str[LEN_ZONE_OPTION_STRING + 1] = {0}; + strncpy(str, optVal->stringValue, LEN_ZONE_OPTION_STRING); + lua_pushstring(lsWidgets, str); + } + break; + case ZoneOption::Integer: + case ZoneOption::Switch: + lua_pushinteger(lsWidgets, optVal->signedValue); + break; + default: + lua_pushinteger(lsWidgets, optVal->unsignedValue); + break; } + lua_setfield(lsWidgets, -2, option->name); } if (useLvglLayout()) luaLvglManager = this; diff --git a/radio/src/lua/lua_widget.h b/radio/src/lua/lua_widget.h index 410e75abe..20210be80 100644 --- a/radio/src/lua/lua_widget.h +++ b/radio/src/lua/lua_widget.h @@ -93,6 +93,7 @@ class LuaWidget : public Widget, public LuaEventHandler, public LuaLvglManager friend class LuaWidgetFactory; int zoneRectDataRef; + int optionsDataRef; char* errorMessage; bool refreshed = false; @@ -112,7 +113,8 @@ 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 luaWidgetDataRef, int zoneRectDataRef, + int optionsDataRef); ~LuaWidget() override; #if defined(DEBUG_WINDOWS) diff --git a/radio/src/lua/lua_widget_factory.cpp b/radio/src/lua/lua_widget_factory.cpp index a1163a543..226915cbb 100644 --- a/radio/src/lua/lua_widget_factory.cpp +++ b/radio/src/lua/lua_widget_factory.cpp @@ -26,13 +26,6 @@ #define MAX_INSTRUCTIONS (20000/100) -static void l_pushtableint(const char * key, int value) -{ - lua_pushstring(lsWidgets, key); - lua_pushinteger(lsWidgets, value); - lua_settable(lsWidgets, -3); -} - LuaWidgetFactory::LuaWidgetFactory(const char* name, ZoneOption* widgetOptions, int createFunction) : WidgetFactory(name, widgetOptions), @@ -72,18 +65,19 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect, // Make 'zone' table for 'create' call lua_newtable(lsWidgets); - l_pushtableint("x", 0); - l_pushtableint("y", 0); - l_pushtableint("w", rect.w); - l_pushtableint("h", rect.h); - l_pushtableint("xabs", rect.x); - l_pushtableint("yabs", rect.y); + l_pushtableint(lsWidgets, "x", 0); + l_pushtableint(lsWidgets, "y", 0); + l_pushtableint(lsWidgets, "w", rect.w); + l_pushtableint(lsWidgets, "h", rect.h); + l_pushtableint(lsWidgets, "xabs", rect.x); + l_pushtableint(lsWidgets, "yabs", rect.y); // Store the zone data in registry for later updates int zoneRectDataRef = luaL_ref(lsWidgets, LUA_REGISTRYINDEX); // Push stored zone for 'create' call lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef); + // Create options table lua_newtable(lsWidgets); int i = 0; for (const ZoneOption* option = options; option->name; option++, i++) { @@ -95,18 +89,21 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect, LEN_ZONE_OPTION_STRING); lua_pushstring(lsWidgets, &str[0]); lua_settable(lsWidgets, -3); - } else if (option->type == ZoneOption::Color) { - int32_t value = persistentData->options[i].value.unsignedValue; - l_pushtableint(option->name, value); + } else if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch) { + l_pushtableint(lsWidgets, option->name, persistentData->options[i].value.signedValue); } else { - int32_t value = persistentData->options[i].value.signedValue; - l_pushtableint(option->name, value); + l_pushtableint(lsWidgets, option->name, persistentData->options[i].value.unsignedValue); } } + // Store the options data in registry for later updates + int optionsDataRef = luaL_ref(lsWidgets, LUA_REGISTRYINDEX); + // Push stored options for 'create' call + lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, optionsDataRef); + bool err = lua_pcall(lsWidgets, 2, 1, 0); int widgetData = err ? LUA_NOREF : luaL_ref(lsWidgets, LUA_REGISTRYINDEX); - LuaWidget* lw = new LuaWidget(this, parent, rect, persistentData, widgetData, zoneRectDataRef); + LuaWidget* lw = new LuaWidget(this, parent, rect, persistentData, widgetData, zoneRectDataRef, optionsDataRef); if (err) lw->setErrorMessage("create()"); return lw; } diff --git a/radio/src/lua/widgets.cpp b/radio/src/lua/widgets.cpp index aabe0bc85..b16c04cf5 100644 --- a/radio/src/lua/widgets.cpp +++ b/radio/src/lua/widgets.cpp @@ -114,7 +114,7 @@ ZoneOption *createOptionsArray(int reference, uint8_t maxOptions) // TRACE("limited to %d options", count); } - ZoneOption *options = (ZoneOption *)malloc(sizeof(ZoneOption) * (count + 1)); + ZoneOption *options = new ZoneOption[count + 1]; if (!options) { return NULL; } @@ -131,82 +131,67 @@ ZoneOption *createOptionsArray(int reference, uint8_t maxOptions) uint8_t field = 0; for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2) && field < 5; lua_pop(lsWidgets, 1), field++) { + luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number switch (field) { case 0: - luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number luaL_checktype(lsWidgets, -1, LUA_TSTRING); // value is string option->name = lua_tostring(lsWidgets, -1); option->displayName = nullptr; // TRACE("name = %s", option->name); break; case 1: - luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number option->type = (ZoneOption::Type)lua_tointeger(lsWidgets, -1); - // TRACE("type = %d", option->type); - if (option->type > ZoneOption::Color) { - // wrong type - option->type = ZoneOption::Integer; - } + option->deflt.unsignedValue = 0; if (option->type == ZoneOption::Integer) { // set some sensible defaults - option->deflt.signedValue = 0; option->min.signedValue = -100; option->max.signedValue = 100; } else if (option->type == ZoneOption::Switch) { // set some sensible defaults - option->deflt.signedValue = SWSRC_NONE; option->min.signedValue = SWSRC_FIRST; option->max.signedValue = SWSRC_LAST; } else if (option->type == ZoneOption::Timer) { - option->deflt.unsignedValue = 0; option->min.unsignedValue = 0; option->max.unsignedValue = MAX_TIMERS - 1; } else if (option->type == ZoneOption::TextSize) { - option->deflt.unsignedValue = FONT_STD_INDEX; option->min.unsignedValue = FONT_STD_INDEX; option->max.unsignedValue = FONTS_COUNT - 1; } else if (option->type == ZoneOption::String) { option->deflt.stringValue[0] = 0; + } else if (option->type == ZoneOption::Slider) { + option->min.unsignedValue = 0; + option->max.unsignedValue = 9; } break; case 2: - luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch) { luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number option->deflt.signedValue = lua_tointeger(lsWidgets, -1); - // TRACE("default signed = %d", option->deflt.signedValue); - } else if (option->type == ZoneOption::Source || - option->type == ZoneOption::TextSize || - option->type == ZoneOption::Timer || - option->type == ZoneOption::Align) { - luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number - option->deflt.unsignedValue = lua_tounsigned(lsWidgets, -1); - // TRACE("default unsigned = %u", option->deflt.unsignedValue); - } else if (option->type == ZoneOption::Color) { - luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number - option->deflt.unsignedValue = lua_tounsigned(lsWidgets, -1); - // TRACE("default unsigned = %u", option->deflt.unsignedValue); } else if (option->type == ZoneOption::Bool) { luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number option->deflt.boolValue = (lua_tounsigned(lsWidgets, -1) != 0); - // TRACE("default bool = %d", (int)(option->deflt.boolValue)); } else if (option->type == ZoneOption::String) { strncpy(option->deflt.stringValue, lua_tostring(lsWidgets, -1), LEN_ZONE_OPTION_STRING); - // TRACE("default string = %s", lua_tostring(lsWidgets, -1)); + } else { + luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number + option->deflt.unsignedValue = lua_tounsigned(lsWidgets, -1); } break; case 3: - if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch) { - luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number + if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch || option->type == ZoneOption::Slider) { luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number option->min.signedValue = lua_tointeger(lsWidgets, -1); + } else if (option->type == ZoneOption::Choice) { + luaL_checktype(lsWidgets, -1, LUA_TTABLE); // value is a table + for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) { + option->choiceValues.push_back(lua_tostring(lsWidgets, -1)); + } } break; case 4: - if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch) { - luaL_checktype(lsWidgets, -2, LUA_TNUMBER); // key is number + if (option->type == ZoneOption::Integer || option->type == ZoneOption::Switch || option->type == ZoneOption::Slider) { luaL_checktype(lsWidgets, -1, LUA_TNUMBER); // value is number option->max.signedValue = lua_tointeger(lsWidgets, -1); } diff --git a/radio/src/translations.cpp b/radio/src/translations.cpp index dd1eaa74c..9fe705c28 100644 --- a/radio/src/translations.cpp +++ b/radio/src/translations.cpp @@ -121,7 +121,6 @@ ISTR(MULTI_WBUS_MODE); ISTR(BLUETOOTH_MODES); #endif -ISTR(TEXT_SIZE); ISTR(SUBTRIMMODES); ISTR(PWR_OFF_DELAYS); #if defined(COLORLCD) diff --git a/radio/src/translations.h b/radio/src/translations.h index 25521dd6b..aa4ccbbc1 100644 --- a/radio/src/translations.h +++ b/radio/src/translations.h @@ -776,7 +776,6 @@ extern const char STR_SLIDERS[]; extern const char STR_FLIGHT_MODE[]; extern const char STR_INVALID_FILE[]; extern const char STR_TIMER_SOURCE[]; -extern const char* const STR_TEXT_SIZE[]; extern const char* const STR_SUBTRIMMODES[]; extern const char STR_SIZE[]; extern const char STR_SHADOW[]; diff --git a/radio/src/translations/cn.h b/radio/src/translations/cn.h index 1909d3e9c..522688b9a 100644 --- a/radio/src/translations/cn.h +++ b/radio/src/translations/cn.h @@ -214,7 +214,6 @@ #define TR_VFORMULAS "加","平均值","最小值","最大值","乘","总计值","单节电池","消耗量","距离" #define TR_VPREC "0.--","0.0-","0.00" #define TR_VCELLINDEX "最低值","1","2","3","4","5","6","7","8","最高值","差值" -#define TR_TEXT_SIZE "标准","小","较小","中等","双倍" #define TR_SUBTRIMMODES STR_CHAR_DELTA "(中点)", "=(整体)" #define TR_TIMER_DIR TR("Remain", "Show Remain"), TR("Elaps.", "Show Elapsed") #define TR_PPMUNIT "0.--","0.0","us" diff --git a/radio/src/translations/cz.h b/radio/src/translations/cz.h index bae6c1801..6495a15d4 100644 --- a/radio/src/translations/cz.h +++ b/radio/src/translations/cz.h @@ -92,8 +92,6 @@ #define TR_CSWEQUAL "a=x" #define TR_VCSWFUNC "---",TR_CSWEQUAL,"a" STR_CHAR_TILDE "x","a>x","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","ax","ax","|a|b","a