fix(lua): Store and update the 'zone' rectangle for Lua widgets. (#3060)
* 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.
This commit is contained in:
@@ -98,10 +98,6 @@ void Widget::onCancel()
|
|||||||
|
|
||||||
void Widget::update()
|
void Widget::update()
|
||||||
{
|
{
|
||||||
auto container = dynamic_cast<WidgetsContainer*>(parent);
|
|
||||||
if (container) {
|
|
||||||
container->updateZones();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::setFullscreen(bool enable)
|
void Widget::setFullscreen(bool enable)
|
||||||
@@ -113,7 +109,10 @@ void Widget::setFullscreen(bool enable)
|
|||||||
if (!enable) {
|
if (!enable) {
|
||||||
|
|
||||||
// Reset all zones in container
|
// Reset all zones in container
|
||||||
Widget::update();
|
auto container = dynamic_cast<WidgetsContainer*>(parent);
|
||||||
|
if (container)
|
||||||
|
container->updateZones();
|
||||||
|
|
||||||
setWindowFlags(getWindowFlags() & ~OPAQUE);
|
setWindowFlags(getWindowFlags() & ~OPAQUE);
|
||||||
lv_obj_set_style_bg_opa(lvobj, LV_OPA_0, LV_PART_MAIN);
|
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
|
// Enter Fullscreen Mode
|
||||||
else {
|
else {
|
||||||
|
|
||||||
// Set window opaque (inhibits redraw from windows bellow)
|
// Set window opaque (inhibits redraw from windows below)
|
||||||
setWindowFlags(getWindowFlags() | OPAQUE);
|
setWindowFlags(getWindowFlags() | OPAQUE);
|
||||||
lv_obj_set_style_bg_opa(lvobj, LV_OPA_MAX, LV_PART_MAIN);
|
lv_obj_set_style_bg_opa(lvobj, LV_OPA_MAX, LV_PART_MAIN);
|
||||||
|
updateZoneRect(parent->getRect());
|
||||||
setRect(parent->getRect());
|
setRect(parent->getRect());
|
||||||
fullscreen = true;
|
fullscreen = true;
|
||||||
|
|
||||||
|
|||||||
@@ -106,6 +106,9 @@ class Widget : public Button
|
|||||||
// Called at regular time interval, even if the widget cannot be seen
|
// Called at regular time interval, even if the widget cannot be seen
|
||||||
virtual void background() {}
|
virtual void background() {}
|
||||||
|
|
||||||
|
// Update widget 'zone' data (for Lua widgets)
|
||||||
|
virtual void updateZoneRect(rect_t rect) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const WidgetFactory * factory;
|
const WidgetFactory * factory;
|
||||||
PersistentData * persistentData;
|
PersistentData * persistentData;
|
||||||
|
|||||||
@@ -136,6 +136,7 @@ class WidgetsContainerImpl : public WidgetsContainer
|
|||||||
if (widgets[i]) {
|
if (widgets[i]) {
|
||||||
auto zone = getZone(i);
|
auto zone = getZone(i);
|
||||||
widgets[i]->setRect(zone);
|
widgets[i]->setRect(zone);
|
||||||
|
widgets[i]->updateZoneRect(zone);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -196,9 +196,10 @@ void LuaEventHandler::removeHandler(Window* w)
|
|||||||
|
|
||||||
LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent,
|
LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent,
|
||||||
const rect_t& rect, WidgetPersistentData* persistentData,
|
const rect_t& rect, WidgetPersistentData* persistentData,
|
||||||
int luaWidgetDataRef) :
|
int luaWidgetDataRef,int zoneRectDataRef) :
|
||||||
Widget(factory, parent, rect, persistentData),
|
Widget(factory, parent, rect, persistentData),
|
||||||
luaWidgetDataRef(luaWidgetDataRef),
|
luaWidgetDataRef(luaWidgetDataRef),
|
||||||
|
zoneRectDataRef(zoneRectDataRef),
|
||||||
errorMessage(nullptr)
|
errorMessage(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -206,6 +207,7 @@ LuaWidget::LuaWidget(const WidgetFactory* factory, Window* parent,
|
|||||||
LuaWidget::~LuaWidget()
|
LuaWidget::~LuaWidget()
|
||||||
{
|
{
|
||||||
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef);
|
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, luaWidgetDataRef);
|
||||||
|
luaL_unref(lsWidgets, LUA_REGISTRYINDEX, zoneRectDataRef);
|
||||||
free(errorMessage);
|
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)
|
void LuaWidget::onFullscreen(bool enable)
|
||||||
{
|
{
|
||||||
if (enable) {
|
if (enable) {
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ class LuaWidget : public Widget, public LuaEventHandler
|
|||||||
friend class LuaWidgetFactory;
|
friend class LuaWidgetFactory;
|
||||||
|
|
||||||
int luaWidgetDataRef;
|
int luaWidgetDataRef;
|
||||||
|
int zoneRectDataRef;
|
||||||
char* errorMessage;
|
char* errorMessage;
|
||||||
bool refreshed = false;
|
bool refreshed = false;
|
||||||
|
|
||||||
@@ -73,9 +74,13 @@ class LuaWidget : public Widget, public LuaEventHandler
|
|||||||
|
|
||||||
void setErrorMessage(const char* funcName);
|
void setErrorMessage(const char* funcName);
|
||||||
|
|
||||||
|
// Update 'zone' data
|
||||||
|
void updateZoneRect(rect_t rect) override;
|
||||||
|
bool updateTable(const char* idx, int val);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LuaWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
LuaWidget(const WidgetFactory* factory, Window* parent, const rect_t& rect,
|
||||||
WidgetPersistentData* persistentData, int luaWidgetDataRef);
|
WidgetPersistentData* persistentData, int luaWidgetDataRef, int zoneRectDataRef);
|
||||||
~LuaWidget() override;
|
~LuaWidget() override;
|
||||||
|
|
||||||
#if defined(DEBUG_WINDOWS)
|
#if defined(DEBUG_WINDOWS)
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ Widget* LuaWidgetFactory::create(Window* parent, const rect_t& rect,
|
|||||||
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
|
luaSetInstructionsLimit(lsWidgets, MAX_INSTRUCTIONS);
|
||||||
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, createFunction);
|
lua_rawgeti(lsWidgets, LUA_REGISTRYINDEX, createFunction);
|
||||||
|
|
||||||
|
// Make 'zone' table for 'create' call
|
||||||
lua_newtable(lsWidgets);
|
lua_newtable(lsWidgets);
|
||||||
l_pushtableint("x", 0);
|
l_pushtableint("x", 0);
|
||||||
l_pushtableint("y", 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("xabs", rect.x);
|
||||||
l_pushtableint("yabs", rect.y);
|
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);
|
lua_newtable(lsWidgets);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
for (const ZoneOption* option = options; option->name; option++, i++) {
|
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);
|
bool err = lua_pcall(lsWidgets, 2, 1, 0);
|
||||||
int widgetData = err ? LUA_NOREF : luaL_ref(lsWidgets, LUA_REGISTRYINDEX);
|
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()");
|
if (err) lw->setErrorMessage("create()");
|
||||||
return lw;
|
return lw;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user