Skip to content

Commit

Permalink
fix(lua): Store and update the 'zone' rectangle for Lua widgets. (#3060)
Browse files Browse the repository at this point in the history
* Store 'zone' rectangle dat in Lua registry and update it when the screen layout changes or full screen mode changes. Allows Lua widgets to adjust to layout changes.

* Call widget 'update' function is layout has changed.
  • Loading branch information
philmoz authored Feb 20, 2023
1 parent c3516b5 commit 1df8fe8
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 9 deletions.
12 changes: 6 additions & 6 deletions radio/src/gui/colorlcd/widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,6 @@ void Widget::onCancel()

void Widget::update()
{
auto container = dynamic_cast<WidgetsContainer*>(parent);
if (container) {
container->updateZones();
}
}

void Widget::setFullscreen(bool enable)
Expand All @@ -113,7 +109,10 @@ void Widget::setFullscreen(bool enable)
if (!enable) {

// Reset all zones in container
Widget::update();
auto container = dynamic_cast<WidgetsContainer*>(parent);
if (container)
container->updateZones();

setWindowFlags(getWindowFlags() & ~OPAQUE);
lv_obj_set_style_bg_opa(lvobj, LV_OPA_0, LV_PART_MAIN);

Expand All @@ -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;

Expand Down
3 changes: 3 additions & 0 deletions radio/src/gui/colorlcd/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions radio/src/gui/colorlcd/widgets/widgets_container_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ class WidgetsContainerImpl : public WidgetsContainer
if (widgets[i]) {
auto zone = getZone(i);
widgets[i]->setRect(zone);
widgets[i]->updateZoneRect(zone);
}
}
}
Expand Down
51 changes: 50 additions & 1 deletion radio/src/lua/lua_widget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,18 @@ 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)
{
}

LuaWidget::~LuaWidget()
{
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef);
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef);
free(errorMessage);
}

Expand Down Expand Up @@ -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) {
Expand Down
7 changes: 6 additions & 1 deletion radio/src/lua/lua_widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class LuaWidget : public Widget, public LuaEventHandler
friend class LuaWidgetFactory;

int luaWidgetDataRef;
int zoneRectDataRef;
char* errorMessage;
bool refreshed = false;

Expand All @@ -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)
Expand Down
8 changes: 7 additions & 1 deletion radio/src/lua/lua_widget_factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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++) {
Expand All @@ -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;
}
Expand Down

0 comments on commit 1df8fe8

Please sign in to comment.