Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(lua) - Store and update the 'zone' rectangle for Lua widgets. #3060

Merged
merged 2 commits into from
Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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