diff --git a/radio/src/gui/colorlcd/widget.cpp b/radio/src/gui/colorlcd/widget.cpp index 8f427d750db..80071327ba6 100644 --- a/radio/src/gui/colorlcd/widget.cpp +++ b/radio/src/gui/colorlcd/widget.cpp @@ -98,10 +98,6 @@ void Widget::onCancel() void Widget::update() { - auto container = dynamic_cast(parent); - if (container) { - container->updateZones(); - } } void Widget::setFullscreen(bool enable) @@ -113,7 +109,10 @@ void Widget::setFullscreen(bool enable) if (!enable) { // Reset all zones in container - Widget::update(); + auto container = dynamic_cast(parent); + if (container) + container->updateZones(); + setWindowFlags(getWindowFlags() & ~OPAQUE); lv_obj_set_style_bg_opa(lvobj, LV_OPA_0, LV_PART_MAIN); @@ -135,9 +134,10 @@ void Widget::setFullscreen(bool enable) // Enter Fullscreen Mode else { - // Set window opaque (inhibits redraw from windows bellow) + // Set window opaque (inhibits redraw from windows below) setWindowFlags(getWindowFlags() | OPAQUE); lv_obj_set_style_bg_opa(lvobj, LV_OPA_MAX, LV_PART_MAIN); + updateZoneRect(parent->getRect()); setRect(parent->getRect()); fullscreen = true; diff --git a/radio/src/gui/colorlcd/widget.h b/radio/src/gui/colorlcd/widget.h index 13866611e65..c31f63b1936 100644 --- a/radio/src/gui/colorlcd/widget.h +++ b/radio/src/gui/colorlcd/widget.h @@ -106,6 +106,9 @@ class Widget : public Button // Called at regular time interval, even if the widget cannot be seen virtual void background() {} + // Update widget 'zone' data (for Lua widgets) + virtual void updateZoneRect(rect_t rect) {} + protected: const WidgetFactory * factory; PersistentData * persistentData; diff --git a/radio/src/gui/colorlcd/widgets/widgets_container_impl.h b/radio/src/gui/colorlcd/widgets/widgets_container_impl.h index 32c4c0e61ac..03230044c1e 100644 --- a/radio/src/gui/colorlcd/widgets/widgets_container_impl.h +++ b/radio/src/gui/colorlcd/widgets/widgets_container_impl.h @@ -136,6 +136,7 @@ class WidgetsContainerImpl : public WidgetsContainer if (widgets[i]) { auto zone = getZone(i); widgets[i]->setRect(zone); + widgets[i]->updateZoneRect(zone); } } } diff --git a/radio/src/lua/lua_widget.cpp b/radio/src/lua/lua_widget.cpp index 9424ee8935f..13591282504 100644 --- a/radio/src/lua/lua_widget.cpp +++ b/radio/src/lua/lua_widget.cpp @@ -196,9 +196,10 @@ void LuaEventHandler::removeHandler(Window* w) LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect, WidgetPersistentData* persistentData, - int luaWidgetDataRef) : + int luaWidgetDataRef,int zoneRectDataRef) : Widget(factory, parent, rect, persistentData), luaWidgetDataRef(luaWidgetDataRef), + zoneRectDataRef(zoneRectDataRef), errorMessage(nullptr) { } @@ -206,6 +207,7 @@ LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent, LuaWidget::~LuaWidget() { luaL_unref(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef); + luaL_unref(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef); free(errorMessage); } @@ -288,6 +290,53 @@ void LuaWidget::update() } } +// Update table on top of Lua stack - set entry with name 'idx' to value 'val' +// Return true if value has changed +bool LuaWidget::updateTable(const char* idx, int val) +{ + bool update = false; + + // Check existing value (or invalid value) + lua_getfield(lsWidgets, -1, idx); + if (lua_isnumber(lsWidgets, -1)) { + int v = lua_tointeger(lsWidgets, -1); + update = (v != val); + } else { + // Force table update + update = true; + } + lua_pop(lsWidgets, 1); + + if (update) { + lua_pushinteger(lsWidgets, val); + lua_setfield(lsWidgets, -2, idx); + } + + return update; +} + +void LuaWidget::updateZoneRect(rect_t rect) +{ + if (lsWidgets) + { + // Update widget zone with current size and position + + lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef); + + bool changed = false; + + if (updateTable("w", rect.w)) changed = true; + if (updateTable("h", rect.h)) changed = true; + if (updateTable("xabs", rect.x)) changed = true; + if (updateTable("yabs", rect.y)) changed = true; + + lua_pop(lsWidgets, 1); + + if (changed) + update(); + } +} + void LuaWidget::onFullscreen(bool enable) { if (enable) { diff --git a/radio/src/lua/lua_widget.h b/radio/src/lua/lua_widget.h index b9786ff860a..e4e18972cc6 100644 --- a/radio/src/lua/lua_widget.h +++ b/radio/src/lua/lua_widget.h @@ -60,6 +60,7 @@ class LuaWidget : public Widget, public LuaEventHandler friend class LuaWidgetFactory; int luaWidgetDataRef; + int zoneRectDataRef; char* errorMessage; bool refreshed = false; @@ -73,9 +74,13 @@ class LuaWidget : public Widget, public LuaEventHandler void setErrorMessage(const char* funcName); + // Update 'zone' data + void updateZoneRect(rect_t rect) override; + bool updateTable(const char* idx, int val); + public: LuaWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect, - WidgetPersistentData* persistentData, int luaWidgetDataRef); + WidgetPersistentData* persistentData, int luaWidgetDataRef, int zoneRectDataRef); ~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 7ba4397c07f..4e7975ca2dd 100644 --- a/radio/src/lua/lua_widget_factory.cpp +++ b/radio/src/lua/lua_widget_factory.cpp @@ -70,6 +70,7 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect, luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS); lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, createFunction); + // Make 'zone' table for 'create' call lua_newtable(lsWidgets); l_pushtableint("x", 0); l_pushtableint("y", 0); @@ -78,6 +79,11 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect, l_pushtableint("xabs", rect.x); l_pushtableint("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); + lua_newtable(lsWidgets); int i = 0; for (const ZoneOption* option = options; option->name; option++, i++) { @@ -100,7 +106,7 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect, 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); + LuaWidget* lw = new LuaWidget(this, parent, rect, persistentData, widgetData, zoneRectDataRef); if (err) lw->setErrorMessage("create()"); return lw; }