fix(color): Lua widgets may not update when quick menu is open (#6967)

This commit is contained in:
philmoz
2026-01-10 12:29:59 +10:00
committed by GitHub
parent 82025f368b
commit 02e4f9b361
13 changed files with 69 additions and 84 deletions
@@ -23,6 +23,7 @@
#include "layout.h"
#include "etx_lv_theme.h"
#include "sdcard.h"
#include "view_main.h"
// timers_driver.h
uint32_t timersGetMsTick();
@@ -57,6 +58,8 @@ void MainWindow::run(bool trash)
{
auto start = timersGetMsTick();
ViewMain::refreshWidgets();
auto opaque = Layer::getFirstOpaque();
if (opaque) {
opaque->checkEvents();
-6
View File
@@ -133,12 +133,6 @@ void Page::onCancel()
void Page::onClicked() { Keyboard::hide(false); }
void Page::checkEvents()
{
ViewMain::instance()->runBackground();
NavWindow::checkEvents();
}
void Page::enableRefresh()
{
lv_obj_enable_style_refresh(true);
-1
View File
@@ -63,7 +63,6 @@ class Page : public NavWindow
Window* body = nullptr;
QuickMenu* quickMenu = nullptr;
void checkEvents() override;
bool bubbleEvents() override { return false; }
NavWindow* navWindow();
+9
View File
@@ -430,6 +430,15 @@ bool Window::isVisible()
return !_deleted && lvobj && !lv_obj_has_flag(lvobj, LV_OBJ_FLAG_HIDDEN);
}
bool Window::isOnScreen()
{
// Check window is at least partially visible
if (!isVisible()) return false;
lv_area_t a;
lv_obj_get_coords(lvobj, &a);
return a.x2 >= 0 && a.x1 < LCD_W && a.y2 >= 0 && a.y1 < LCD_H;
}
void Window::enable(bool enabled)
{
if (!_deleted && lvobj) {
+1
View File
@@ -187,6 +187,7 @@ class Window
virtual void show(bool visible = true);
void hide() { show(false); }
bool isVisible();
bool isOnScreen();
virtual void enable(bool enabled = true);
void disable() { enable(false); }
+18 -15
View File
@@ -76,6 +76,12 @@ static void tile_view_scroll_end(lv_event_t* e)
ViewMain* ViewMain::_instance = nullptr;
ViewMain* ViewMain::instance()
{
if (!_instance) _instance = new ViewMain();
return _instance;
}
ViewMain::ViewMain() :
NavWindow(MainWindow::instance(), MainWindow::instance()->getRect())
{
@@ -178,16 +184,6 @@ void ViewMain::previousMainView()
TopBar* ViewMain::getTopbar() { return topbar; }
void ViewMain::enableTopbar()
{
if (topbar) topbar->show();
}
void ViewMain::disableTopbar()
{
if (topbar) topbar->hide();
}
void ViewMain::updateTopbarVisibility()
{
if (!tile_view) return;
@@ -409,11 +405,18 @@ void ViewMain::hideTopBarEdgeTxButton()
topbar->setEdgeTxButtonVisible(0.0);
}
void ViewMain::runBackground()
void ViewMain::_refreshWidgets()
{
topbar->runBackground();
for (int i = 0; i < MAX_CUSTOM_SCREENS; i += 1) {
if (customScreens[i])
customScreens[i]->runBackground();
if (!_deleted) {
topbar->refreshWidgets(isVisible && hasTopbar());
for (int i = 0; i < MAX_CUSTOM_SCREENS; i += 1) {
if (customScreens[i])
customScreens[i]->refreshWidgets(isVisible);
}
}
}
void ViewMain::refreshWidgets()
{
if (_instance) _instance->_refreshWidgets();
}
+5 -18
View File
@@ -25,8 +25,6 @@
#include "window.h"
class QuickMenu;
class SetupWidgetsPage;
class SetupTopBarWidgetsPage;
class TopBar;
class ViewMain : public NavWindow
@@ -37,14 +35,7 @@ class ViewMain : public NavWindow
public:
~ViewMain() override;
static ViewMain* instance()
{
if (!_instance) _instance = new ViewMain();
return _instance;
}
static ViewMain* getInstance() { return _instance; }
static ViewMain* instance();
#if defined(DEBUG_WINDOWS)
std::string getName() const override { return "ViewMain"; }
@@ -52,8 +43,6 @@ class ViewMain : public NavWindow
void addMainView(WidgetsContainer* view, uint32_t viewId);
void enableTopbar();
void disableTopbar();
void updateTopbarVisibility();
bool enableWidgetSelect(bool enable);
@@ -76,7 +65,6 @@ class ViewMain : public NavWindow
bool onLongPress() override;
void show(bool visible = true) override;
bool viewIsVisible() const { return isVisible; }
void showTopBarEdgeTxButton();
void hideTopBarEdgeTxButton();
@@ -85,9 +73,10 @@ class ViewMain : public NavWindow
bool isAppMode();
bool isAppMode(unsigned view);
void runBackground();
void refreshWidgetSelectTimer();
static void refreshWidgets();
protected:
static ViewMain* _instance;
@@ -100,14 +89,12 @@ class ViewMain : public NavWindow
void deleteLater(bool detach = true, bool trash = true) override;
// Widget setup requires special permissions ;-)
friend class SetupWidgetsPage;
friend class SetupTopBarWidgetsPage;
// Set topbar visibility [0.0 -> 1.0]
void setTopbarVisible(float visible);
void setEdgeTxButtonVisible(float visible);
void _refreshWidgets();
static void ws_timer(lv_timer_t* t);
#if defined(HARDWARE_KEYS)
+3 -1
View File
@@ -108,8 +108,10 @@ class Widget : public ButtonBase
// Called when the widget options have changed
virtual void update();
// Called at regular time interval, even if the widget cannot be seen
// Called at regular time interval if the widget is hidden or off screen
virtual void background() {}
// Called at regular time interval if the widget is visible and on screen
virtual void foreground() {}
// Update widget 'zone' data (for Lua widgets)
virtual void updateZoneRect(rect_t rect, bool updateUI = true)
@@ -83,11 +83,16 @@ void WidgetsContainer::showWidgets(bool visible)
}
}
void WidgetsContainer::runBackground()
void WidgetsContainer::refreshWidgets(bool inForeground)
{
for (int i = 0; i < zoneCount; i++) {
if (widgets[i]) {
widgets[i]->background();
if (!_deleted) {
for (int i = 0; i < zoneCount; i++) {
if (widgets[i]) {
if ((inForeground && widgets[i]->isOnScreen()) || widgets[i]->isFullscreen())
widgets[i]->foreground();
else
widgets[i]->background();
}
}
}
}
@@ -41,7 +41,7 @@ class WidgetsContainer: public Window
void updateZones();
void showWidgets(bool visible = true);
void hideWidgets() { showWidgets(false); }
void runBackground();
void refreshWidgets(bool inForeground);
virtual bool isLayout() { return false; }
virtual bool isAppMode() const { return false; }
@@ -320,7 +320,6 @@ void PageGroupBase::checkEvents()
if (currentTab) {
currentTab->checkEvents();
}
ViewMain::instance()->runBackground();
}
void PageGroupBase::onClicked() { Keyboard::hide(false); }
+19 -35
View File
@@ -195,7 +195,6 @@ void LuaEventHandler::removeHandler(Window* w)
void LuaWidget::redraw_cb(lv_event_t* e)
{
lv_obj_t* target = lv_event_get_target(e);
if (lv_obj_has_flag(target, LV_OBJ_FLAG_HIDDEN)) return;
LuaWidget* widget = (LuaWidget*)lv_obj_get_user_data(target);
@@ -292,47 +291,35 @@ void LuaWidget::onCancel()
LuaScriptManager::onCancelEvent();
}
void LuaWidget::checkEvents()
void LuaWidget::foreground()
{
Widget::checkEvents();
if (closeFS) {
closeFS = false;
setFullscreen(false);
}
// refresh() has not been called
if (!refreshed)
background();
refreshed = false;
if (useLvglLayout()) {
if (!lv_obj_has_flag(lvobj, LV_OBJ_FLAG_HIDDEN)) {
lv_area_t a;
lv_obj_get_coords(lvobj, &a);
// Check widget is at least partially visible
if (a.x2 >= 0 && a.x1 < LCD_W) {
auto save = luaScriptManager;
PROTECT_LUA() {
luaScriptManager = this;
refresh(nullptr);
if (!errorMessage) {
if (!callRefs(lsWidgets)) {
setErrorMessage("function");
}
// Check widget is at least partially visible
if (isOnScreen()) {
if (useLvglLayout()) {
auto save = luaScriptManager;
PROTECT_LUA() {
luaScriptManager = this;
refresh(nullptr);
if (!errorMessage) {
if (!callRefs(lsWidgets)) {
setErrorMessage("function");
}
refreshInstructionsPercent = instructionsPercent;
} else {
setErrorMessage("function");
}
luaScriptManager = save;
UNPROTECT_LUA();
refreshInstructionsPercent = instructionsPercent;
} else {
setErrorMessage("function");
}
luaScriptManager = save;
UNPROTECT_LUA();
} else {
// Force call to redraw_cb()
invalidate();
}
} else {
// Force call to redraw_cb()
invalidate();
}
#if defined(DEBUG_WINDOWS)
@@ -537,9 +524,6 @@ void LuaWidget::refresh(BitmapBuffer* dc)
// Remove LCD
luaLcdAllowed = lla;
luaLcdBuffer = nullptr;
// mark as refreshed
refreshed = true;
}
void LuaWidget::background()
+1 -2
View File
@@ -122,6 +122,7 @@ class LuaWidget : public Widget, public LuaScriptManager
const char* getErrorMessage() const override;
void update() override;
void background() override;
void foreground() override;
void clear() override;
@@ -148,12 +149,10 @@ class LuaWidget : public Widget, public LuaScriptManager
int zoneRectDataRef;
int optionsDataRef;
char* errorMessage;
bool refreshed = false;
// Window interface
void onClicked() override;
void onCancel() override;
void checkEvents() override;
void onEvent(event_t event) override;
// Widget interface