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:
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user