feat(color): enhancements and fixes to the LVGL Lua API's (#6351)
This commit is contained in:
@@ -228,7 +228,7 @@ void Choice::openMenu()
|
||||
{
|
||||
setEditMode(true); // this needs to be done first before menu is created.
|
||||
|
||||
auto menu = new Menu();
|
||||
auto menu = new Menu(false, popupWidth);
|
||||
if (menuTitle) menu->setTitle(menuTitle);
|
||||
|
||||
fillMenu(menu);
|
||||
|
||||
@@ -54,10 +54,13 @@ class ChoiceBase : public FormField
|
||||
|
||||
const char* getTitle() const { return menuTitle; }
|
||||
|
||||
void setPopupWidth(coord_t w) { popupWidth = w; }
|
||||
|
||||
static LAYOUT_VAL_SCALED(ICON_W, 18)
|
||||
|
||||
protected:
|
||||
lv_obj_t *label;
|
||||
coord_t popupWidth = 0;
|
||||
int vmin = 0;
|
||||
int vmax = 0;
|
||||
const char *menuTitle = nullptr;
|
||||
|
||||
@@ -305,13 +305,15 @@ static lv_obj_t* menu_content_create(lv_obj_t* parent)
|
||||
class MenuWindowContent : public Window
|
||||
{
|
||||
public:
|
||||
explicit MenuWindowContent(Menu* parent) :
|
||||
explicit MenuWindowContent(Menu* parent, coord_t popupWidth) :
|
||||
Window(parent, rect_t{}, menu_content_create)
|
||||
{
|
||||
setWindowFlag(OPAQUE);
|
||||
|
||||
coord_t w = (popupWidth > MENUS_WIDTH) ? popupWidth : MENUS_WIDTH;
|
||||
|
||||
lv_obj_center(lvobj);
|
||||
setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO, MENUS_WIDTH, LV_SIZE_CONTENT);
|
||||
setFlexLayout(LV_FLEX_FLOW_COLUMN, PAD_ZERO, w, LV_SIZE_CONTENT);
|
||||
|
||||
header = new StaticText(this, {0, 0, LV_PCT(100), 0}, "",
|
||||
COLOR_THEME_PRIMARY2_INDEX);
|
||||
@@ -319,7 +321,7 @@ class MenuWindowContent : public Window
|
||||
header->padAll(PAD_SMALL);
|
||||
header->hide();
|
||||
|
||||
body = new MenuBody(this, rect_t{0, 0, MENUS_WIDTH, LV_SIZE_CONTENT});
|
||||
body = new MenuBody(this, rect_t{0, 0, w, LV_SIZE_CONTENT});
|
||||
lv_obj_set_style_max_height(body->getLvObj(), LCD_H * 0.8, LV_PART_MAIN);
|
||||
}
|
||||
|
||||
@@ -357,10 +359,10 @@ class MenuWindowContent : public Window
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
Menu::Menu(bool multiple) :
|
||||
Menu::Menu(bool multiple, coord_t popupWidth) :
|
||||
ModalWindow(true),
|
||||
multiple(multiple),
|
||||
content(new MenuWindowContent(this))
|
||||
content(new MenuWindowContent(this, popupWidth))
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ class Menu : public ModalWindow
|
||||
friend class MenuBody;
|
||||
|
||||
public:
|
||||
explicit Menu(bool multiple = false);
|
||||
explicit Menu(bool multiple = false, coord_t popupWidth = 0);
|
||||
|
||||
#if defined(DEBUG_WINDOWS)
|
||||
std::string getName() const override { return "Menu"; }
|
||||
|
||||
@@ -59,15 +59,20 @@ void Window::eventHandler(lv_event_t *e)
|
||||
|
||||
switch (code) {
|
||||
case LV_EVENT_SCROLL: {
|
||||
lv_coord_t scroll_x = lv_obj_get_scroll_x(target);
|
||||
lv_coord_t scroll_y = lv_obj_get_scroll_y(target);
|
||||
if (scrollHandler) scrollHandler(scroll_x, scroll_y);
|
||||
|
||||
// exclude pointer based scrolling (only focus scrolling)
|
||||
if (!lv_obj_is_scrolling(target)) {
|
||||
if (!lv_obj_is_scrolling(target) && !noForcedScroll) {
|
||||
lv_point_t *p = (lv_point_t *)lv_event_get_param(e);
|
||||
lv_coord_t scroll_bottom = lv_obj_get_scroll_bottom(target);
|
||||
|
||||
lv_coord_t scroll_y = lv_obj_get_scroll_y(target);
|
||||
TRACE("SCROLL[x=%d;y=%d;top=%d;bottom=%d]", p->x, p->y, scroll_y,
|
||||
scroll_bottom);
|
||||
|
||||
// Force scroll to top or bottom when near either edge.
|
||||
// Only applies when using rotary encoder or keys.
|
||||
if (scroll_y <= 45 && p->y > 0) {
|
||||
lv_obj_scroll_by(target, 0, scroll_y, LV_ANIM_OFF);
|
||||
} else if (scroll_bottom <= 16 && p->y < 0) {
|
||||
|
||||
@@ -75,6 +75,9 @@ class Window
|
||||
typedef std::function<void(bool)> FocusHandler;
|
||||
void setFocusHandler(FocusHandler h) { focusHandler = std::move(h); }
|
||||
|
||||
typedef std::function<void(coord_t, coord_t)> ScrollHandler;
|
||||
void setScrollHandler(ScrollHandler h) { scrollHandler = std::move(h); }
|
||||
|
||||
virtual void clear();
|
||||
virtual void deleteLater(bool detach = true, bool trash = true);
|
||||
|
||||
@@ -182,6 +185,8 @@ class Window
|
||||
virtual void enable(bool enabled = true);
|
||||
void disable() { enable(false); }
|
||||
|
||||
void disableForcedScroll() { noForcedScroll = true; }
|
||||
|
||||
protected:
|
||||
static std::list<Window *> trash;
|
||||
|
||||
@@ -194,12 +199,14 @@ class Window
|
||||
|
||||
WindowFlags windowFlags = 0;
|
||||
LcdFlags textFlags = 0;
|
||||
bool noForcedScroll = false;
|
||||
|
||||
bool _deleted = false;
|
||||
static bool _longPressed;
|
||||
|
||||
std::function<void()> closeHandler;
|
||||
std::function<void(bool)> focusHandler;
|
||||
CloseHandler closeHandler;
|
||||
FocusHandler focusHandler;
|
||||
std::function<void(coord_t, coord_t)> scrollHandler;
|
||||
|
||||
void deleteChildren();
|
||||
|
||||
|
||||
@@ -143,9 +143,9 @@ class WidgetFactory
|
||||
Widget::PersistentData* persistentData);
|
||||
|
||||
protected:
|
||||
const char* name;
|
||||
const char* displayName;
|
||||
const ZoneOption* options;
|
||||
const char* name = nullptr;
|
||||
const char* displayName = nullptr;
|
||||
const ZoneOption* options = nullptr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
|
||||
@@ -433,7 +433,6 @@ LROT_BEGIN(lvgl_base_mt, NULL, LROT_MASK_GC_INDEX)
|
||||
LROT_FUNCENTRY(set, luaLvglSet)
|
||||
LROT_FUNCENTRY(show, luaLvglShow)
|
||||
LROT_FUNCENTRY(hide, luaLvglHide)
|
||||
LROT_FUNCENTRY(getScrollPos, luaLvglGetScrollPos)
|
||||
LROT_END(lvgl_base_mt, NULL, LROT_MASK_GC_INDEX)
|
||||
|
||||
// Metatable for complex objects
|
||||
|
||||
@@ -41,15 +41,12 @@ static void clearRef(lua_State *L, int& ref)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void LvglParamFuncOrValue::parse(lua_State *L, ParamType typ)
|
||||
void LvglParamFuncOrValue::parse(lua_State *L)
|
||||
{
|
||||
if (lua_isfunction(L, -1)) {
|
||||
function = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
} else {
|
||||
if (typ == PTXT)
|
||||
txt = luaL_checkstring(L, -1);
|
||||
else
|
||||
value = luaL_checkunsigned(L, -1);
|
||||
value = luaL_checkunsigned(L, -1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,17 +60,6 @@ bool LvglParamFuncOrValue::changedColor(LcdFlags newFlags)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LvglParamFuncOrValue::changedText(const char* s)
|
||||
{
|
||||
txt = s;
|
||||
uint32_t h = hash(txt, strlen(txt));
|
||||
if (h != currVal) {
|
||||
currVal = h;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LvglParamFuncOrValue::changedValue(uint32_t v)
|
||||
{
|
||||
value = v;
|
||||
@@ -89,6 +75,31 @@ void LvglParamFuncOrValue::clearRef(lua_State *L)
|
||||
::clearRef(L, function);
|
||||
}
|
||||
|
||||
void LvglParamFuncOrString::parse(lua_State *L)
|
||||
{
|
||||
if (lua_isfunction(L, -1)) {
|
||||
function = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
} else {
|
||||
txt = luaL_checkstring(L, -1);
|
||||
}
|
||||
}
|
||||
|
||||
bool LvglParamFuncOrString::changedText(const char* s)
|
||||
{
|
||||
txt = s;
|
||||
uint32_t h = hash(chars(), txt.size());
|
||||
if (h != txtHash) {
|
||||
txtHash = h;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void LvglParamFuncOrString::clearRef(lua_State *L)
|
||||
{
|
||||
::clearRef(L, function);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
bool LvglGetSetParams::parseGetSetParam(lua_State *L, const char *key)
|
||||
@@ -113,7 +124,7 @@ void LvglGetSetParams::clearGetSetRefs(lua_State *L)
|
||||
bool LvglTextParams::parseTextParam(lua_State *L, const char *key)
|
||||
{
|
||||
if (!strcmp(key, "text")) {
|
||||
txt.parse(L, LvglParamFuncOrValue::PTXT);
|
||||
txt.parse(L);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(key, "font")) {
|
||||
@@ -189,6 +200,27 @@ bool LvglValuesParam::parseValuesParam(lua_State *L, const char *key)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LvglScrollableParams::parseScrollableParam(lua_State *L, const char *key)
|
||||
{
|
||||
if (!strcmp(key, "scrollBar")) {
|
||||
showScrollBar = lua_toboolean(L, -1);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(key, "scrollDir")) {
|
||||
scrollDir = (lv_dir_t)luaL_checkunsigned(L, -1);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(key, "scrollTo")) {
|
||||
scrollToFunction = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
return true;
|
||||
}
|
||||
if (!strcmp(key, "scrolled")) {
|
||||
scrolledFunction = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
static int pcallcont (lua_State *L, int status, lua_KContext extra) {
|
||||
@@ -214,6 +246,17 @@ static bool pcallFuncWithInt(lua_State *L, int funcRef, int nretval, int val)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pcallFuncWith2Int(lua_State *L, int funcRef, int nretval, int val1, int val2)
|
||||
{
|
||||
if (funcRef != LUA_REFNIL) {
|
||||
lua_rawgeti(L, LUA_REGISTRYINDEX, funcRef);
|
||||
lua_pushinteger(L, val1);
|
||||
lua_pushinteger(L, val2);
|
||||
return lua_pcallk(L, 2, nretval, 0, 0, pcallcont) == LUA_OK;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool pcallFuncWithString(lua_State *L, int funcRef, int nretval, const char* val)
|
||||
{
|
||||
if (funcRef != LUA_REFNIL) {
|
||||
@@ -696,7 +739,7 @@ void LvglWidgetLabel::clearRefs(lua_State *L)
|
||||
void LvglWidgetLabel::setText(const char *s)
|
||||
{
|
||||
if (lvobj && txt.changedText(s))
|
||||
lv_label_set_text(lvobj, txt.txt);
|
||||
lv_label_set_text(lvobj, txt.chars());
|
||||
}
|
||||
|
||||
void LvglWidgetLabel::setColor(LcdFlags newColor)
|
||||
@@ -731,7 +774,7 @@ void LvglWidgetLabel::build(lua_State *L)
|
||||
lvobj = lv_label_create(lvglManager->getCurrentParent()->getLvObj());
|
||||
setPos(x, y);
|
||||
setSize(w, h);
|
||||
setText(txt.txt);
|
||||
setText(txt.chars());
|
||||
setColor(color.flags);
|
||||
setOpacity(opacity.value);
|
||||
setFont(font.flags);
|
||||
@@ -869,7 +912,7 @@ uint32_t LvglWidgetLine::getPts(lua_State* L)
|
||||
}
|
||||
for (size_t i = 0; i < ptCnt; i += 1)
|
||||
getPt(L, i);
|
||||
return hash(pts, sizeof(ptCnt * sizeof(lv_point_t)));
|
||||
return hash(pts, ptCnt * sizeof(lv_point_t));
|
||||
} else {
|
||||
ptCnt = 0;
|
||||
return -1;
|
||||
@@ -1332,11 +1375,8 @@ void LvglWidgetObject::clearRefs(lua_State *L)
|
||||
|
||||
void LvglWidgetBox::parseParam(lua_State *L, const char *key)
|
||||
{
|
||||
if (!strcmp(key, "scrollDir")) {
|
||||
scrollDir = (lv_dir_t)luaL_checkunsigned(L, -1);
|
||||
} else {
|
||||
LvglWidgetObject::parseParam(L, key);
|
||||
}
|
||||
if (parseScrollableParam(L, key)) return;
|
||||
LvglWidgetObject::parseParam(L, key);
|
||||
}
|
||||
|
||||
coord_t LvglWidgetBox::getScrollX()
|
||||
@@ -1349,16 +1389,34 @@ coord_t LvglWidgetBox::getScrollY()
|
||||
return lv_obj_get_scroll_y(window->getLvObj());
|
||||
}
|
||||
|
||||
bool LvglWidgetBox::callRefs(lua_State *L)
|
||||
{
|
||||
if (!pcallUpdate2Int(L, scrollToFunction,
|
||||
[=](int x, int y) { if (x != getScrollX() || y != getScrollY()) lv_obj_scroll_to(window->getLvObj(), x, y, LV_ANIM_OFF); })) {
|
||||
return false;
|
||||
}
|
||||
return LvglWidgetObject::callRefs(L);
|
||||
}
|
||||
|
||||
void LvglWidgetBox::clearRefs(lua_State *L)
|
||||
{
|
||||
clearRef(L, scrollToFunction);
|
||||
LvglWidgetObject::clearRefs(L);
|
||||
}
|
||||
|
||||
void LvglWidgetBox::build(lua_State *L)
|
||||
{
|
||||
window =
|
||||
new Window(lvglManager->getCurrentParent(), {x, y, w, h}, lv_obj_create);
|
||||
window->disableForcedScroll();
|
||||
window->setScrollHandler([=](coord_t x, coord_t y) { pcallFuncWith2Int(L, scrolledFunction, 0, x, y); });
|
||||
lv_obj_add_flag(window->getLvObj(), LV_OBJ_FLAG_EVENT_BUBBLE);
|
||||
if (luaScriptManager->isWidget()) {
|
||||
lv_obj_clear_flag(window->getLvObj(), LV_OBJ_FLAG_CLICKABLE);
|
||||
} else {
|
||||
lv_obj_set_scroll_dir(window->getLvObj(), scrollDir);
|
||||
etx_scrollbar(window->getLvObj());
|
||||
if (showScrollBar)
|
||||
etx_scrollbar(window->getLvObj());
|
||||
}
|
||||
if (setFlex())
|
||||
lv_obj_set_flex_align(window->getLvObj(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_SPACE_AROUND);
|
||||
@@ -1637,7 +1695,7 @@ void LvglWidgetArc::build(lua_State *L)
|
||||
void LvglWidgetImage::parseParam(lua_State *L, const char *key)
|
||||
{
|
||||
if (!strcmp(key, "file")) {
|
||||
filename.parse(L, LvglParamFuncOrValue::PTXT);
|
||||
filename.parse(L);
|
||||
} else if (!strcmp(key, "fill")) {
|
||||
fillFrame = lua_toboolean(L, -1);
|
||||
} else {
|
||||
@@ -1652,7 +1710,7 @@ bool LvglWidgetImage::callRefs(lua_State *L)
|
||||
if (pcallFunc(L, filename.function, 1)) {
|
||||
const char *s = luaL_checkstring(L, -1);
|
||||
if (filename.changedText(s)) {
|
||||
((StaticImage*)window)->setSource(filename.txt);
|
||||
((StaticImage*)window)->setSource(filename.chars());
|
||||
}
|
||||
lua_settop(L, t);
|
||||
} else {
|
||||
@@ -1671,7 +1729,7 @@ void LvglWidgetImage::clearRefs(lua_State *L)
|
||||
void LvglWidgetImage::build(lua_State *L)
|
||||
{
|
||||
window = new StaticImage(lvglManager->getCurrentParent(), {x, y, w, h},
|
||||
filename.txt, fillFrame);
|
||||
filename.chars(), fillFrame);
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -1805,7 +1863,7 @@ void LvglWidgetTextButton::build(lua_State *L)
|
||||
{
|
||||
if (h == LV_SIZE_CONTENT) h = 0;
|
||||
auto btn =
|
||||
new TextButton(lvglManager->getCurrentParent(), {x, y, w, h}, txt.txt, [=]() {
|
||||
new TextButton(lvglManager->getCurrentParent(), {x, y, w, h}, txt.chars(), [=]() {
|
||||
return pcallGetOptIntVal(L, pressFunction, 0);
|
||||
});
|
||||
if (longPressFunction != LUA_REFNIL) {
|
||||
@@ -1842,7 +1900,7 @@ void LvglWidgetMomentaryButton::build(lua_State *L)
|
||||
{
|
||||
if (h == LV_SIZE_CONTENT) h = 0;
|
||||
window =
|
||||
new MomentaryButton(lvglManager->getCurrentParent(), {x, y, w, h}, txt.txt,
|
||||
new MomentaryButton(lvglManager->getCurrentParent(), {x, y, w, h}, txt.chars(),
|
||||
[=]() {
|
||||
pcallSimpleFunc(L, pressFunction);
|
||||
},
|
||||
@@ -2028,7 +2086,8 @@ class WidgetPage : public NavWindow, public LuaEventHandler
|
||||
{
|
||||
public:
|
||||
WidgetPage(Window *parent, std::function<void()> backAction,
|
||||
std::string title, std::string subtitle, std::string iconFile, lv_dir_t scrollDir) :
|
||||
std::string title, std::string subtitle, std::string iconFile,
|
||||
lv_dir_t scrollDir, bool showScrollBar) :
|
||||
NavWindow(parent, {0, 0, LCD_W, LCD_H}), backAction(std::move(backAction))
|
||||
{
|
||||
if (iconFile.empty())
|
||||
@@ -2047,7 +2106,8 @@ class WidgetPage : public NavWindow, public LuaEventHandler
|
||||
lv_obj_set_style_max_height(body->getLvObj(), LCD_H - EdgeTxStyles::MENU_HEADER_HEIGHT,
|
||||
LV_PART_MAIN);
|
||||
lv_obj_set_scroll_dir(body->getLvObj(), scrollDir);
|
||||
etx_scrollbar(body->getLvObj());
|
||||
if (showScrollBar)
|
||||
etx_scrollbar(body->getLvObj());
|
||||
|
||||
#if defined(HARDWARE_TOUCH)
|
||||
addBackButton();
|
||||
@@ -2079,14 +2139,13 @@ class WidgetPage : public NavWindow, public LuaEventHandler
|
||||
void LvglWidgetPage::parseParam(lua_State *L, const char *key)
|
||||
{
|
||||
if (parseTitleParam(L, key)) return;
|
||||
if (parseScrollableParam(L, key)) return;
|
||||
if (!strcmp(key, "back")) {
|
||||
backActionFunction = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
} else if (!strcmp(key, "subtitle")) {
|
||||
subtitle = luaL_checkstring(L, -1);
|
||||
} else if (!strcmp(key, "icon")) {
|
||||
iconFile = luaL_checkstring(L, -1);
|
||||
} else if (!strcmp(key, "scrollDir")) {
|
||||
scrollDir = (lv_dir_t)luaL_checkunsigned(L, -1);
|
||||
} else {
|
||||
LvglWidgetObject::parseParam(L, key);
|
||||
}
|
||||
@@ -2102,6 +2161,15 @@ coord_t LvglWidgetPage::getScrollY()
|
||||
return lv_obj_get_scroll_y(window->getLvObj());
|
||||
}
|
||||
|
||||
bool LvglWidgetPage::callRefs(lua_State *L)
|
||||
{
|
||||
if (!pcallUpdate2Int(L, scrollToFunction,
|
||||
[=](int x, int y) { if (x != getScrollX() || y != getScrollY()) lv_obj_scroll_to(window->getLvObj(), x, y, LV_ANIM_OFF); })) {
|
||||
return false;
|
||||
}
|
||||
return LvglWidgetObject::callRefs(L);
|
||||
}
|
||||
|
||||
void LvglWidgetPage::clearRefs(lua_State *L)
|
||||
{
|
||||
clearRef(L, backActionFunction);
|
||||
@@ -2112,9 +2180,11 @@ void LvglWidgetPage::build(lua_State *L)
|
||||
{
|
||||
auto page = new WidgetPage(
|
||||
lvglManager->getCurrentParent(),
|
||||
[=]() { pcallSimpleFunc(L, backActionFunction); }, title, subtitle, iconFile, scrollDir);
|
||||
[=]() { pcallSimpleFunc(L, backActionFunction); }, title, subtitle, iconFile, scrollDir, showScrollBar);
|
||||
|
||||
window = page->getBody();
|
||||
window->disableForcedScroll();
|
||||
window->setScrollHandler([=](coord_t x, coord_t y) { pcallFuncWith2Int(L, scrolledFunction, 0, x, y); });
|
||||
if (setFlex())
|
||||
lv_obj_set_flex_align(window->getLvObj(), LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_START, LV_FLEX_ALIGN_SPACE_AROUND);
|
||||
}
|
||||
@@ -2221,7 +2291,7 @@ void LvglWidgetMessageDialog::parseParam(lua_State *L, const char *key)
|
||||
|
||||
void LvglWidgetMessageDialog::build(lua_State *L)
|
||||
{
|
||||
window = new MessageDialog(title.c_str(), message.c_str(), details);
|
||||
window = new MessageDialog(title.c_str(), message.c_str(), details.c_str());
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@@ -2247,6 +2317,8 @@ void LvglWidgetChoice::parseParam(lua_State *L, const char *key)
|
||||
if (parseValuesParam(L, key)) return;
|
||||
if (!strcmp(key, "filter")) {
|
||||
filterFunction = luaL_ref(L, LUA_REGISTRYINDEX);
|
||||
} else if (!strcmp(key, "popupWidth")) {
|
||||
popupWidth = luaL_checkinteger(L, -1);
|
||||
} else {
|
||||
LvglWidgetPicker::parseParam(L, key);
|
||||
}
|
||||
@@ -2266,6 +2338,8 @@ void LvglWidgetChoice::build(lua_State *L)
|
||||
[=]() { return pcallGetIntVal(L, getFunction) - 1; },
|
||||
[=](int val) { pcallSetIntVal(L, setFunction, val + 1); }, title.c_str());
|
||||
|
||||
c->setPopupWidth(popupWidth);
|
||||
|
||||
if (filterFunction != LUA_REFNIL)
|
||||
c->setAvailableHandler([=](int n) {
|
||||
bool rv = true;
|
||||
@@ -2451,7 +2525,7 @@ void LvglWidgetFilePicker::build(lua_State *L)
|
||||
if (h == LV_SIZE_CONTENT) h = 0;
|
||||
auto c = new FileChoice(
|
||||
lvglManager->getCurrentParent(), {x, y, w, h},
|
||||
folder, extension, maxLen,
|
||||
folder.c_str(), extension.c_str(), maxLen,
|
||||
[=]() { return pcallGetStringVal(L, getFunction); },
|
||||
[=](std::string val) { pcallSetStringVal(L, setFunction, val.c_str()); },
|
||||
hideExtension, title.c_str());
|
||||
|
||||
@@ -32,30 +32,39 @@ class LvglDialog;
|
||||
struct LvglParamFuncOrValue
|
||||
{
|
||||
public:
|
||||
enum ParamType {
|
||||
PVALUE,
|
||||
PTXT,
|
||||
};
|
||||
|
||||
int function;
|
||||
union {
|
||||
LcdFlags flags;
|
||||
coord_t coord;
|
||||
const char* txt;
|
||||
uint32_t value;
|
||||
};
|
||||
|
||||
uint32_t currVal = -1;
|
||||
|
||||
void parse(lua_State *L, ParamType typ = PVALUE);
|
||||
void parse(lua_State *L);
|
||||
void forceUpdate() { currVal = -1; }
|
||||
bool changedColor(LcdFlags newFlags);
|
||||
bool changedFont(LcdFlags newFlags) { return changedColor(newFlags);}
|
||||
bool changedText(const char* s);
|
||||
bool changedValue(uint32_t v);
|
||||
void clearRef(lua_State *L);
|
||||
};
|
||||
|
||||
struct LvglParamFuncOrString
|
||||
{
|
||||
public:
|
||||
int function;
|
||||
std::string txt;
|
||||
uint32_t txtHash = -1;
|
||||
|
||||
void parse(lua_State *L);
|
||||
void forceUpdate() { txtHash = -1; }
|
||||
bool changedText(const char* s);
|
||||
const char* chars() const { return txt.c_str(); }
|
||||
void clearRef(lua_State *L);
|
||||
|
||||
private:
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LvglGetSetParams
|
||||
@@ -77,7 +86,7 @@ class LvglTextParams
|
||||
LvglTextParams() {}
|
||||
|
||||
protected:
|
||||
LvglParamFuncOrValue txt = { .function = LUA_REFNIL, .txt = ""};
|
||||
LvglParamFuncOrString txt = { .function = LUA_REFNIL, .txt = ""};
|
||||
LvglParamFuncOrValue font = { .function = LUA_REFNIL, .flags = FONT(STD)};
|
||||
|
||||
bool parseTextParam(lua_State *L, const char *key);
|
||||
@@ -151,6 +160,20 @@ class LvglValuesParam
|
||||
bool parseValuesParam(lua_State *L, const char *key);
|
||||
};
|
||||
|
||||
class LvglScrollableParams
|
||||
{
|
||||
public:
|
||||
LvglScrollableParams() {}
|
||||
|
||||
protected:
|
||||
bool showScrollBar = true;
|
||||
lv_dir_t scrollDir = LV_DIR_ALL;
|
||||
int scrollToFunction = LUA_REFNIL;
|
||||
int scrolledFunction = LUA_REFNIL;
|
||||
|
||||
bool parseScrollableParam(lua_State *L, const char *key);
|
||||
};
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LvglWidgetObjectBase
|
||||
@@ -265,7 +288,7 @@ class LvglWidgetLabel : public LvglSimpleWidgetObject, public LvglTextParams
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override
|
||||
{
|
||||
setText(txt.txt);
|
||||
setText(txt.chars());
|
||||
setFont(font.flags);
|
||||
setAlign(align.flags);
|
||||
LvglSimpleWidgetObject::refresh();
|
||||
@@ -414,7 +437,7 @@ class LvglWidgetObject : public LvglWidgetObjectBase
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LvglWidgetBox : public LvglWidgetObject
|
||||
class LvglWidgetBox : public LvglWidgetObject, public LvglScrollableParams
|
||||
{
|
||||
public:
|
||||
LvglWidgetBox() : LvglWidgetObject() {}
|
||||
@@ -422,9 +445,10 @@ class LvglWidgetBox : public LvglWidgetObject
|
||||
coord_t getScrollX() override;
|
||||
coord_t getScrollY() override;
|
||||
|
||||
protected:
|
||||
lv_dir_t scrollDir = LV_DIR_ALL;
|
||||
bool callRefs(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
};
|
||||
@@ -562,7 +586,7 @@ class LvglWidgetImage : public LvglWidgetObject
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
protected:
|
||||
LvglParamFuncOrValue filename = { .function = LUA_REFNIL, .txt = ""};
|
||||
LvglParamFuncOrString filename = { .function = LUA_REFNIL, .txt = ""};
|
||||
bool fillFrame = false;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
@@ -612,7 +636,7 @@ class LvglWidgetTextButtonBase : public LvglWidgetObject, public LvglTextParams
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
void refresh() override
|
||||
{
|
||||
setText(txt.txt);
|
||||
setText(txt.chars());
|
||||
setFont(font.flags);
|
||||
setTextColor(textColor.flags);
|
||||
LvglWidgetObject::refresh();
|
||||
@@ -751,11 +775,12 @@ class LvglWidgetVerticalSlider : public LvglWidgetSliderBase
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
class LvglWidgetPage : public LvglWidgetObject, public LvglTitleParam
|
||||
class LvglWidgetPage : public LvglWidgetObject, public LvglTitleParam, public LvglScrollableParams
|
||||
{
|
||||
public:
|
||||
LvglWidgetPage() : LvglWidgetObject() {}
|
||||
|
||||
bool callRefs(lua_State *L) override;
|
||||
void clearRefs(lua_State *L) override;
|
||||
|
||||
coord_t getScrollX() override;
|
||||
@@ -764,7 +789,6 @@ class LvglWidgetPage : public LvglWidgetObject, public LvglTitleParam
|
||||
protected:
|
||||
std::string subtitle;
|
||||
std::string iconFile;
|
||||
lv_dir_t scrollDir = LV_DIR_ALL;
|
||||
|
||||
int backActionFunction = LUA_REFNIL;
|
||||
|
||||
@@ -816,7 +840,7 @@ class LvglWidgetMessageDialog : public LvglWidgetObject, public LvglTitleParam,
|
||||
LvglWidgetMessageDialog() : LvglWidgetObject(LVGL_SIMPLEMETATABLE) {}
|
||||
|
||||
protected:
|
||||
const char *details = nullptr;
|
||||
std::string details;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
@@ -846,6 +870,7 @@ class LvglWidgetChoice : public LvglWidgetPicker, public LvglTitleParam, public
|
||||
|
||||
protected:
|
||||
int filterFunction = LUA_REFNIL;
|
||||
coord_t popupWidth = 0;
|
||||
|
||||
void build(lua_State *L) override;
|
||||
void parseParam(lua_State *L, const char *key) override;
|
||||
@@ -943,8 +968,8 @@ class LvglWidgetFilePicker : public LvglWidgetPicker, public LvglTitleParam
|
||||
LvglWidgetFilePicker() : LvglWidgetPicker() {}
|
||||
|
||||
protected:
|
||||
const char* folder = nullptr;
|
||||
const char* extension = nullptr;
|
||||
std::string folder;
|
||||
std::string extension;
|
||||
int maxLen = 255;
|
||||
bool hideExtension = false;
|
||||
|
||||
|
||||
@@ -49,9 +49,8 @@ LuaWidgetFactory::LuaWidgetFactory(const char* name, ZoneOption* widgetOptions,
|
||||
LuaWidgetFactory::~LuaWidgetFactory() {
|
||||
unregisterWidget(this);
|
||||
|
||||
if (displayName) {
|
||||
delete displayName;
|
||||
}
|
||||
if (name) delete name;
|
||||
if (displayName) delete displayName;
|
||||
|
||||
auto option = getDefaultOptions();
|
||||
while (option && option->name != nullptr) {
|
||||
@@ -277,6 +276,7 @@ ZoneOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
for (lua_pushnil(lsWidgets); lua_next(lsWidgets, -2); lua_pop(lsWidgets, 1)) {
|
||||
count++;
|
||||
}
|
||||
lua_pop(lsWidgets, 1);
|
||||
|
||||
// TRACE("we have %d options", count);
|
||||
if (count > MAX_WIDGET_OPTIONS) {
|
||||
@@ -337,6 +337,7 @@ ZoneOption* LuaWidgetFactory::parseOptionDefinitions(int reference)
|
||||
}
|
||||
option++;
|
||||
}
|
||||
lua_pop(lsWidgets, 1);
|
||||
option->name = NULL; // sentinel
|
||||
}
|
||||
else
|
||||
|
||||
@@ -146,7 +146,7 @@ void luaLoadWidgetCallback(const char* filename)
|
||||
if (name && createFunction) {
|
||||
ZoneOption * options = LuaWidgetFactory::parseOptionDefinitions(optionDefinitionsReference);
|
||||
if (options) {
|
||||
new LuaWidgetFactory(name, options, optionDefinitionsReference,
|
||||
new LuaWidgetFactory(strdup(name), options, optionDefinitionsReference,
|
||||
createFunction, updateFunction, refreshFunction, backgroundFunction,
|
||||
translateFunction, lvglLayout, filename);
|
||||
TRACE("Loaded Lua widget %s", name);
|
||||
@@ -167,6 +167,7 @@ static void luaLoadFile(const char * filename, std::function<void()> callback)
|
||||
if (luaLoadScriptFileToState(lsWidgets, filename, LUA_SCRIPT_LOAD_MODE) == SCRIPT_OK) {
|
||||
if (lua_pcall(lsWidgets, 0, 1, 0) == LUA_OK && lua_istable(lsWidgets, -1)) {
|
||||
callback();
|
||||
lua_pop(lsWidgets, 1);
|
||||
}
|
||||
else {
|
||||
TRACE("luaLoadFile(%s): Error parsing script: %s", filename, lua_tostring(lsWidgets, -1));
|
||||
|
||||
Reference in New Issue
Block a user