feat: Add 'repeat' option to 'Lua Script' special function (#3338)

* Add support for the '1x' repeat option for 'Play Script' special functions.

* Add Companion and B&W radio support.

* Fix B&W radio logic and layout.

* Add translation hooks.
This commit is contained in:
philmoz
2023-04-10 11:00:50 +10:00
committed by GitHub
parent 6138f29da6
commit 227780d784
11 changed files with 123 additions and 52 deletions
@@ -394,6 +394,19 @@ AbstractStaticItemModel * CustomFunctionData::repeatItemModel()
return mdl;
}
// static
AbstractStaticItemModel * CustomFunctionData::repeatLuaItemModel()
{
AbstractStaticItemModel * mdl = new AbstractStaticItemModel();
mdl->setName("customfunctiondata.repeatLua");
mdl->appendToItemList(tr("On"), 0);
mdl->appendToItemList(tr("1x"), 1);
mdl->loadItemList();
return mdl;
}
// static
AbstractStaticItemModel * CustomFunctionData::playSoundItemModel()
{
@@ -136,6 +136,7 @@ class CustomFunctionData {
static QStringList gvarAdjustModeStringList();
static QString gvarAdjustModeToString(const int value);
static AbstractStaticItemModel * repeatItemModel();
static AbstractStaticItemModel * repeatLuaItemModel();
static AbstractStaticItemModel * playSoundItemModel();
static AbstractStaticItemModel * harpicItemModel();
static AbstractStaticItemModel * gvarAdjustModeItemModel();
@@ -37,7 +37,8 @@ static bool fnHasRepeat(AssignFunc fn)
|| (fn == FuncPlayValue)
|| (fn == FuncPlayHaptic)
|| (fn == FuncPlaySound)
|| (fn == FuncSetScreen);
|| (fn == FuncSetScreen)
|| (fn == FuncPlayScript);
}
static const YamlLookupTable customFnLut = {
@@ -225,7 +226,9 @@ Node convert<CustomFunctionData>::encode(const CustomFunctionData& rhs)
if (add_comma) {
def += ",";
}
if (rhs.repeatParam == 0) {
if (rhs.func == FuncPlayScript) {
def += ((rhs.repeatParam == 0) ? "On" : "1x");
} else if (rhs.repeatParam == 0) {
def += "1x";
} else if (rhs.repeatParam == -1) {
def += "!1x";
@@ -374,7 +377,9 @@ bool convert<CustomFunctionData>::decode(const Node& node,
} else if(fnHasRepeat(rhs.func)) {
std::string repeat;
getline(def, repeat);
if (repeat == "1x") {
if (rhs.func == FuncPlayScript) {
rhs.repeatParam = (repeat == "1x") ? 1 : 0;
} else if (repeat == "1x") {
rhs.repeatParam = 0;
} else if (repeat == "!1x") {
rhs.repeatParam = -1;
+12 -2
View File
@@ -39,6 +39,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
playSoundId = tabModelFactory->registerItemModel(CustomFunctionData::playSoundItemModel());
harpicId = tabModelFactory->registerItemModel(CustomFunctionData::harpicItemModel());
repeatId = tabModelFactory->registerItemModel(CustomFunctionData::repeatItemModel());
repeatLuaId = tabModelFactory->registerItemModel(CustomFunctionData::repeatLuaItemModel());
gvarAdjustModeId = tabModelFactory->registerItemModel(CustomFunctionData::gvarAdjustModeItemModel());
tabFilterFactory = new FilteredItemModelFactory();
@@ -193,7 +194,10 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model,
tableLayout->addLayout(i, 4, repeatLayout);
fswtchRepeat[i] = new QComboBox(this);
fswtchRepeat[i]->setProperty("index", i);
fswtchRepeat[i]->setModel(tabModelFactory->getItemModel(repeatId));
if (functions[i].func == FuncPlayScript)
fswtchRepeat[i]->setModel(tabModelFactory->getItemModel(repeatLuaId));
else
fswtchRepeat[i]->setModel(tabModelFactory->getItemModel(repeatId));
fswtchRepeat[i]->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed);
fswtchRepeat[i]->setSizeAdjustPolicy(QComboBox::AdjustToContents);
repeatLayout->addWidget(fswtchRepeat[i], i + 1);
@@ -324,6 +328,10 @@ void CustomFunctionsPanel::functionEdited()
functions[index].clear();
functions[index].swtch = swtch;
functions[index].func = (AssignFunc)fswtchFunc[index]->currentData().toInt();
if (functions[index].func == FuncPlayScript)
fswtchRepeat[index]->setModel(tabModelFactory->getItemModel(repeatLuaId));
else
fswtchRepeat[index]->setModel(tabModelFactory->getItemModel(repeatId));
refreshCustomFunction(index);
emit modified();
lock = false;
@@ -523,11 +531,13 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified)
}
}
else if (func == FuncPlayScript) {
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM;
widgetsMask |= CUSTOM_FUNCTION_FILE_PARAM | CUSTOM_FUNCTION_REPEAT;
if (modified) {
Helpers::getFileComboBoxValue(fswtchParamArmT[i], cfn.paramarm, 8);
cfn.repeatParam = fswtchRepeat[i]->currentData().toInt();
}
Helpers::populateFileComboBox(fswtchParamArmT[i], scriptsSet, cfn.paramarm);
fswtchRepeat[i]->setCurrentIndex(fswtchRepeat[i]->findData(cfn.repeatParam));
}
else {
if (modified)
@@ -87,6 +87,7 @@ class CustomFunctionsPanel : public GenericPanel
int playSoundId;
int harpicId;
int repeatId;
int repeatLuaId;
int gvarAdjustModeId;
QSet<QString> tracksSet;
@@ -307,7 +307,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
#if defined(SDCARD)
else if (func == FUNC_PLAY_TRACK || func == FUNC_BACKGND_MUSIC || func == FUNC_PLAY_SCRIPT) {
if (ZEXIST(cfn->play.name))
lcdDrawSizedText(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, cfn->play.name, sizeof(cfn->play.name), attr);
lcdDrawSizedText(MODEL_SPECIAL_FUNC_3RD_COLUMN-6, y, cfn->play.name, sizeof(cfn->play.name), attr);
else
lcdDrawTextAtIndex(MODEL_SPECIAL_FUNC_3RD_COLUMN, y, STR_VCSWFUNC, 0, attr);
if (active && event==EVT_KEY_BREAK(KEY_ENTER)) {
@@ -438,16 +438,22 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags);
}
else if (HAS_REPEAT_PARAM(func)) {
if (CFN_PLAY_REPEAT(cfn) == 0) {
lcdDrawChar(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF+3, y, '-', attr);
}
else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) {
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF+1, y, "!-", attr);
if (func == FUNC_PLAY_SCRIPT) {
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF-3, y, (CFN_PLAY_REPEAT(cfn) == 0) ? "On" : "1x", attr);
if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn), 0, 1, eeFlags);
}
else {
lcdDrawNumber(MODEL_SPECIAL_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, RIGHT | attr);
if (CFN_PLAY_REPEAT(cfn) == 0) {
lcdDrawChar(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF+3, y, '-', attr);
}
else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) {
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF+1, y, "!-", attr);
}
else {
lcdDrawNumber(MODEL_SPECIAL_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, RIGHT | attr);
}
if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags);
}
if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags);
}
else if (attr) {
REPEAT_LAST_CURSOR_MOVE();
@@ -416,18 +416,24 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF
if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags);
}
else if (HAS_REPEAT_PARAM(func)) {
if (CFN_PLAY_REPEAT(cfn) == 0) {
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN+2, y, "1x", attr);
}
else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) {
lcdDrawChar(MODEL_SPECIAL_FUNC_4TH_COLUMN-1, y, '!', attr);
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN+2, y, "1x", attr);
if (func == FUNC_PLAY_SCRIPT) {
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN+2, y, (CFN_PLAY_REPEAT(cfn) == 0) ? "On" : "1x", attr);
if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn), 0, 1, eeFlags);
}
else {
lcdDrawNumber(MODEL_SPECIAL_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, attr|RIGHT);
lcdDrawChar(MODEL_SPECIAL_FUNC_4TH_COLUMN+2+FW, y, 's', attr);
if (CFN_PLAY_REPEAT(cfn) == 0) {
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN+2, y, "1x", attr);
}
else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) {
lcdDrawChar(MODEL_SPECIAL_FUNC_4TH_COLUMN-1, y, '!', attr);
lcdDrawText(MODEL_SPECIAL_FUNC_4TH_COLUMN+2, y, "1x", attr);
}
else {
lcdDrawNumber(MODEL_SPECIAL_FUNC_4TH_COLUMN+2+FW, y, CFN_PLAY_REPEAT(cfn)*CFN_PLAY_REPEAT_MUL, attr|RIGHT);
lcdDrawChar(MODEL_SPECIAL_FUNC_4TH_COLUMN+2+FW, y, 's', attr);
}
if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags);
}
if (active) CFN_PLAY_REPEAT(cfn) = checkIncDec(event, CFN_PLAY_REPEAT(cfn)==CFN_PLAY_REPEAT_NOSTART?-1:CFN_PLAY_REPEAT(cfn), -1, 60/CFN_PLAY_REPEAT_MUL, eeFlags);
}
else if (attr) {
REPEAT_LAST_CURSOR_MOVE();
+31 -19
View File
@@ -331,20 +331,28 @@ class SpecialFunctionEditPage : public Page
line = specialFunctionOneWindow->newLine(&grid);
new StaticText(line, rect_t{}, STR_REPEAT,
0, COLOR_THEME_PRIMARY1);
auto repeat = new NumberEdit(
line, rect_t{}, -1,
60 / CFN_PLAY_REPEAT_MUL, GET_DEFAULT((int8_t)CFN_PLAY_REPEAT(cfn)),
SET_DEFAULT(CFN_PLAY_REPEAT(cfn)));
repeat->setDisplayHandler(
[](int32_t value) {
if (value == 0)
return std::string("1x");
else if (value == (int8_t)CFN_PLAY_REPEAT_NOSTART)
return std::string("!1x");
else {
return formatNumberAsString(value * CFN_PLAY_REPEAT_MUL, 0, 0, nullptr, "s");
}
});
if (func == FUNC_PLAY_SCRIPT) {
auto repeat = new Choice(line, rect_t{}, 0, 1,
GET_DEFAULT((int8_t)CFN_PLAY_REPEAT(cfn)),
SET_DEFAULT(CFN_PLAY_REPEAT(cfn)));
repeat->setTextHandler([](int32_t value) {
// 0 == repeat at 50ms interval for backward compatibility
return (value == 0) ? std::string("On") : std::string("1x");
});
} else {
auto repeat = new NumberEdit(line, rect_t{}, 0, 60 / CFN_PLAY_REPEAT_MUL,
GET_DEFAULT((int8_t)CFN_PLAY_REPEAT(cfn)),
SET_DEFAULT(CFN_PLAY_REPEAT(cfn)));
repeat->setDisplayHandler([](int32_t value) {
if (value == 0)
return std::string("1x");
else if (value == (int8_t)CFN_PLAY_REPEAT_NOSTART)
return std::string("!1x");
else {
return formatNumberAsString(value * CFN_PLAY_REPEAT_MUL, 0, 0, nullptr, "s");
}
});
}
}
}
@@ -653,11 +661,15 @@ class SpecialFunctionButton : public Button
lv_obj_clear_state(sfEnable, LV_STATE_CHECKED);
lv_obj_clear_flag(sfEnable, LV_OBJ_FLAG_HIDDEN);
} else if (HAS_REPEAT_PARAM(func)) {
sprintf(s, "(%s)",
(CFN_PLAY_REPEAT(cfn) == 0) ? "1x" :
(CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) ? "!1x" :
formatNumberAsString(CFN_PLAY_REPEAT(cfn) * CFN_PLAY_REPEAT_MUL, 0, 0, nullptr, "s").c_str()
);
if (func == FUNC_PLAY_SCRIPT) {
sprintf(s, "(%s)", (CFN_PLAY_REPEAT(cfn) == 0) ? "On" : "1x");
} else {
sprintf(s, "(%s)",
(CFN_PLAY_REPEAT(cfn) == 0) ? "1x" :
(CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) ? "!1x" :
formatNumberAsString(CFN_PLAY_REPEAT(cfn) * CFN_PLAY_REPEAT_MUL, 0, 0, nullptr, "s").c_str()
);
}
}
lv_label_set_text(sfRepeat, s);
+17 -7
View File
@@ -1083,15 +1083,25 @@ static bool resumeLua(bool init, bool allowLcdUsage)
} else
#endif
if (ref <= SCRIPT_GFUNC_LAST) {
uint8_t idx;
CustomFunctionData * fn;
if (ref <= SCRIPT_FUNC_LAST)
fn = &g_model.customFn[ref - SCRIPT_FUNC_FIRST];
else
fn = &g_eeGeneral.customFn[ref - SCRIPT_GFUNC_FIRST];
if (getSwitch(fn -> swtch)) {
CustomFunctionsContext * functionsContext;
if (ref <= SCRIPT_FUNC_LAST) {
idx = ref - SCRIPT_FUNC_FIRST;
fn = &g_model.customFn[idx];
functionsContext = &modelFunctionsContext;
} else {
idx = ref - SCRIPT_GFUNC_FIRST;
fn = &g_eeGeneral.customFn[idx];
functionsContext = &globalFunctionsContext;
}
tmr10ms_t tmr10ms = get_tmr10ms();
if (getSwitch(fn->swtch) && (functionsContext->lastFunctionTime[idx] == 0 || CFN_PLAY_REPEAT(fn) == 0)) {
lua_rawgeti(lsScripts, LUA_REGISTRYINDEX, sid.run);
functionsContext->lastFunctionTime[idx] = tmr10ms;
}
else {
if (sid.background == LUA_NOREF) continue;
+2 -2
View File
@@ -61,9 +61,9 @@
#define HAS_ENABLE_PARAM(func) ((func) < FUNC_FIRST_WITHOUT_ENABLE || (func == FUNC_BACKLIGHT))
#if defined(COLORLCD)
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func) || func == FUNC_SET_SCREEN)
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func) || func == FUNC_PLAY_SCRIPT || func == FUNC_SET_SCREEN)
#else
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func) )
#define HAS_REPEAT_PARAM(func) (IS_PLAY_FUNC(func) || IS_HAPTIC_FUNC(func) || func == FUNC_PLAY_SCRIPT)
#endif
#define CFN_EMPTY(p) (!(p)->swtch)
@@ -1477,7 +1477,12 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs,
}
}
} else if (HAS_REPEAT_PARAM(func)) {
if (val_len == 2
if (func == FUNC_PLAY_SCRIPT) {
if (val_len == 2 && val[0] == '1' && val[1] == 'x')
CFN_PLAY_REPEAT(cfn) = 1;
else
CFN_PLAY_REPEAT(cfn) = 0;
} else if (val_len == 2
&& val[0] == '1'
&& val[1] == 'x') {
CFN_PLAY_REPEAT(cfn) = 0;
@@ -1629,7 +1634,9 @@ static bool w_customFn(void* user, uint8_t* data, uint32_t bitoffs,
// ","
if (!wf(opaque,",",1)) return false;
}
if (CFN_PLAY_REPEAT(cfn) == 0) {
if (func == FUNC_PLAY_SCRIPT) {
if (!wf(opaque,(CFN_PLAY_REPEAT(cfn) == 0) ? "On" : "1x",2)) return false;
} else if (CFN_PLAY_REPEAT(cfn) == 0) {
// "1x"
if (!wf(opaque,"1x",2)) return false;
} else if (CFN_PLAY_REPEAT(cfn) == CFN_PLAY_REPEAT_NOSTART) {