diff --git a/companion/src/firmwares/customfunctiondata.cpp b/companion/src/firmwares/customfunctiondata.cpp index d17feab3091..6110e97812d 100644 --- a/companion/src/firmwares/customfunctiondata.cpp +++ b/companion/src/firmwares/customfunctiondata.cpp @@ -229,16 +229,8 @@ QString CustomFunctionData::repeatToString(const int value, const bool abbrev) QString CustomFunctionData::enabledToString() const { - if ((func >= FuncOverrideCH1 && func <= FuncOverrideCHLast) || - (func >= FuncAdjustGV1 && func <= FuncAdjustGVLast) || - (func == FuncReset) || - (func >= FuncSetTimer1 && func <= FuncSetTimerLast) || - (func == FuncVolume) || - (func == FuncBacklight) || - (func <= FuncInstantTrim)) { - if (!enabled) { - return tr("DISABLED"); - } + if (!enabled) { + return tr("DISABLED"); } return ""; } diff --git a/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp b/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp index f5d637f7f80..64491429607 100644 --- a/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp +++ b/companion/src/firmwares/edgetx/yaml_customfunctiondata.cpp @@ -226,16 +226,16 @@ Node convert::encode(const CustomFunctionData& rhs) break; } - if (fnHasEnable(rhs.func)) { - if (add_comma) { - def += ","; - } - def += std::to_string((int)rhs.enabled); - } else if(fnHasRepeat(rhs.func)) { - if (add_comma) { - def += ","; - } - if (rhs.func == FuncPlayScript || rhs.func == FuncRGBLed) { + if (add_comma) { + def += ","; + } + + def += std::to_string((int)rhs.enabled); + + if(fnHasRepeat(rhs.func)) { + def += ","; + + if (rhs.func == FuncPlayScript || rhs.func == FuncRGBLed)) { def += ((rhs.repeatParam == 0) ? "On" : "1x"); } else if (rhs.repeatParam == 0) { def += "1x"; @@ -385,11 +385,14 @@ bool convert::decode(const Node& node, def.ignore(); } - if (fnHasEnable(rhs.func)) { - int en = 0; - def >> en; - rhs.enabled = en; - } else if(fnHasRepeat(rhs.func)) { + int en = 0; + def >> en; + rhs.enabled = en; + + if(fnHasRepeat(rhs.func)) { + if (def.peek() == ',') { + def.ignore(); + } std::string repeat; getline(def, repeat); if (rhs.func == FuncPlayScript || rhs.func == FuncRGBLed) { diff --git a/companion/src/modeledit/customfunctions.cpp b/companion/src/modeledit/customfunctions.cpp index 2c662e2a04f..559151b4050 100644 --- a/companion/src/modeledit/customfunctions.cpp +++ b/companion/src/modeledit/customfunctions.cpp @@ -112,7 +112,7 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, playIcon.addImage("stop.png", QIcon::Normal, QIcon::On); QStringList headerLabels; - headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << ""; + headerLabels << "#" << tr("Switch") << tr("Action") << tr("Parameters") << tr("Repeat") << tr("Enable") << ""; TableLayout * tableLayout = new TableLayout(this, fswCapability, headerLabels); for (int i = 0; i < fswCapability; i++) { @@ -215,11 +215,12 @@ CustomFunctionsPanel::CustomFunctionsPanel(QWidget * parent, ModelData * model, repeatLayout->addWidget(fswtchRepeat[i], i + 1); connect(fswtchRepeat[i], SIGNAL(currentIndexChanged(int)), this, SLOT(customFunctionEdited())); + QHBoxLayout *enableLayout = new QHBoxLayout(); + tableLayout->addLayout(i, 5, enableLayout); fswtchEnable[i] = new QCheckBox(this); fswtchEnable[i]->setProperty("index", i); - fswtchEnable[i]->setText(tr("ON")); fswtchEnable[i]->setFixedWidth(200); - repeatLayout->addWidget(fswtchEnable[i], i + 1); + enableLayout->addWidget(fswtchEnable[i], i + 1); connect(fswtchEnable[i], SIGNAL(stateChanged(int)), this, SLOT(customFunctionEdited())); } @@ -351,6 +352,7 @@ void CustomFunctionsPanel::functionEdited() functions[index].clear(); functions[index].swtch = swtch; functions[index].func = (AssignFunc)fswtchFunc[index]->currentData().toInt(); + functions[index].enabled = true; if (functions[index].func == FuncPlayScript || functions[index].func == FuncRGBLed) fswtchRepeat[index]->setModel(tabModelFactory->getItemModel(repeatLuaId)); else @@ -375,10 +377,11 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) else { fswtchSwtch[i]->setCurrentIndex(fswtchSwtch[i]->findData(cfn.swtch.toValue())); fswtchFunc[i]->setCurrentIndex(fswtchFunc[i]->findData(cfn.func)); + fswtchEnable[i]->setChecked(cfn.enabled); } if (!cfn.isEmpty()) { - widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC; + widgetsMask |= CUSTOM_FUNCTION_SHOW_FUNC | CUSTOM_FUNCTION_ENABLE; if (func >= FuncOverrideCH1 && func <= FuncOverrideCH32) { if (model) { @@ -391,7 +394,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) cfn.param = fswtchParam[i]->value(); } fswtchParam[i]->setValue(cfn.param); - widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM | CUSTOM_FUNCTION_ENABLE; + widgetsMask |= CUSTOM_FUNCTION_NUMERIC_PARAM; } } else if (func == FuncLogs) { @@ -409,7 +412,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) if (modified) cfn.adjustMode = fswtchGVmode[i]->currentData().toInt(); fswtchGVmode[i]->setCurrentIndex(fswtchGVmode[i]->findData(cfn.adjustMode)); - widgetsMask |= CUSTOM_FUNCTION_GV_MODE | CUSTOM_FUNCTION_ENABLE; + widgetsMask |= CUSTOM_FUNCTION_GV_MODE; if (cfn.adjustMode == FUNC_ADJUST_GVAR_CONSTANT || cfn.adjustMode == FUNC_ADJUST_GVAR_INCDEC) { if (modified) cfn.param = fswtchParam[i]->value() * model->gvarData[gvidx].multiplierSet(); @@ -440,7 +443,7 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) if (modified) cfn.param = fswtchParamT[i]->currentData().toInt(); populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; } else if (func >= FuncSetTimer1 && func <= FuncSetTimer3) { if (modified) @@ -448,16 +451,13 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) RawSourceRange range = RawSource(SOURCE_TYPE_SPECIAL, func - FuncSetTimer1 + 2).getRange(model, generalSettings); fswtchParamTime[i]->setTimeRange((int)range.min, (int)range.max); fswtchParamTime[i]->setTime(cfn.param); - widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM | CUSTOM_FUNCTION_ENABLE; - } - else if (func >= FuncSetFailsafe && func <= FuncBindExternalModule) { - widgetsMask |= CUSTOM_FUNCTION_ENABLE; + widgetsMask |= CUSTOM_FUNCTION_TIME_PARAM; } else if (func == FuncVolume || func == FuncBacklight) { if (modified) cfn.param = fswtchParamT[i]->currentData().toInt(); populateFuncParamCB(fswtchParamT[i], func, cfn.param); - widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM | CUSTOM_FUNCTION_ENABLE; + widgetsMask |= CUSTOM_FUNCTION_SOURCE_PARAM; } else if (func == FuncPlaySound || func == FuncPlayHaptic || func == FuncPlayValue || func == FuncPlayPrompt || func == FuncPlayBoth || func == FuncBackgroundMusic || func == FuncSetScreen) { if (func != FuncBackgroundMusic) { @@ -568,11 +568,12 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParam[i]->setDecimals(0); fswtchParam[i]->setSingleStep(1); fswtchParam[i]->setValue(cfn.param); - if (func <= FuncInstantTrim) { - widgetsMask |= CUSTOM_FUNCTION_ENABLE; - } + widgetsMask |= CUSTOM_FUNCTION_ENABLE; } } + else { + cfn.enabled = true; + } fswtchFunc[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SHOW_FUNC); fswtchParam[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_NUMERIC_PARAM); @@ -581,10 +582,6 @@ void CustomFunctionsPanel::refreshCustomFunction(int i, bool modified) fswtchParamT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_SOURCE_PARAM); fswtchParamArmT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_FILE_PARAM); fswtchEnable[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_ENABLE); - if (widgetsMask & CUSTOM_FUNCTION_ENABLE) - fswtchEnable[i]->setChecked(cfn.enabled); - else - fswtchEnable[i]->setChecked(false); fswtchRepeat[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_REPEAT); fswtchGVmode[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_GV_MODE); playBT[i]->setVisible(widgetsMask & CUSTOM_FUNCTION_PLAY); diff --git a/radio/src/datastructs_private.h b/radio/src/datastructs_private.h index 9660466fb55..a22cf911049 100644 --- a/radio/src/datastructs_private.h +++ b/radio/src/datastructs_private.h @@ -174,7 +174,8 @@ PACK(struct CustomFunctionData { NOBACKUP(CFN_SPARE_TYPE val2); }) clear); }) NAME(fp) SKIP; - uint8_t active SKIP; + uint8_t active : 1 SKIP; + int8_t repeat:7 SKIP; bool isEmpty() const { diff --git a/radio/src/gui/128x64/model_special_functions.cpp b/radio/src/gui/128x64/model_special_functions.cpp index 1030116f7b5..2f4a968ea61 100644 --- a/radio/src/gui/128x64/model_special_functions.cpp +++ b/radio/src/gui/128x64/model_special_functions.cpp @@ -21,14 +21,17 @@ #include "opentx.h" -#define MODEL_SPECIAL_FUNC_1ST_COLUMN (0) -#define MODEL_SPECIAL_FUNC_2ND_COLUMN (4*FW-1) -#define MODEL_SPECIAL_FUNC_3RD_COLUMN (15*FW-3) -#define MODEL_SPECIAL_FUNC_4TH_COLUMN (20*FW) +#define MODEL_SPECIAL_FUNC_1ST_COLUMN (0) +#define MODEL_SPECIAL_FUNC_2ND_COLUMN (4*FW-1) +#define MODEL_SPECIAL_FUNC_3RD_COLUMN (15*FW-3) #if defined(GRAPHICS) - #define MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF (20*FW) + #define MODEL_SPECIAL_FUNC_4TH_COLUMN (19 * FW - 3) + #define MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF (19 * FW - 3) + #define MODEL_SPECIAL_FUNC_5TH_COLUMN_ONOFF (20 * FW + 1) #else - #define MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF (18*FW+2) + #define MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF (17 * FW) + #define MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF (17 * FW) + #define MODEL_SPECIAL_FUNC_5TH_COLUMN_ONOFF (18 * FW + 3) #endif #if defined(SDCARD) @@ -186,12 +189,13 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF CustomFunctionData * cfn = &functions[k]; uint8_t func = CFN_FUNC(cfn); - for (uint8_t j=0; j<5; j++) { + for (uint8_t j=0; j<6; j++) { uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); uint8_t active = (attr && s_editMode > 0); switch (j) { case 0: if (sub==k && menuHorizontalPosition < 1 && CFN_SWITCH(cfn) == SWSRC_NONE) { + CFN_ACTIVE(cfn) = 1; drawSwitch(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | INVERS | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); if (active) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); } @@ -210,6 +214,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF if (active) { CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable); if (checkIncDec_Ret) CFN_RESET(cfn); + CFN_ACTIVE(cfn) = 1; // Enable if function is being changed } } else { @@ -439,11 +444,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF } case 4: - if (HAS_ENABLE_PARAM(func)) { - drawCheckBox(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr); - if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); - } - else if (HAS_REPEAT_PARAM(func)) { + if (HAS_REPEAT_PARAM(func)) { 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); @@ -465,6 +466,11 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF repeatLastCursorMove(event); } break; + + case 5: + drawCheckBox(MODEL_SPECIAL_FUNC_5TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr); + if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); + break; } } #if defined(NAVIGATION_X7) @@ -483,7 +489,7 @@ void menuModelSpecialFunctions(event_t event) menuHorizontalPosition = 0; } #endif - MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, HEADER_LINE+MAX_SPECIAL_FUNCTIONS, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); + MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, HEADER_LINE+MAX_SPECIAL_FUNCTIONS, { HEADER_LINE_COLUMNS NAVIGATION_LINE_BY_LINE|5/*repeated*/ }); menuSpecialFunctions(event, g_model.customFn, &modelFunctionsContext); diff --git a/radio/src/gui/212x64/model_special_functions.cpp b/radio/src/gui/212x64/model_special_functions.cpp index a803c053eb6..dc12e1ff894 100644 --- a/radio/src/gui/212x64/model_special_functions.cpp +++ b/radio/src/gui/212x64/model_special_functions.cpp @@ -24,7 +24,7 @@ #define MODEL_SPECIAL_FUNC_1ST_COLUMN (4*FW+2) #define MODEL_SPECIAL_FUNC_2ND_COLUMN (8*FW+2) #define MODEL_SPECIAL_FUNC_3RD_COLUMN (21*FW) -#define MODEL_SPECIAL_FUNC_4TH_COLUMN (33*FW-3) +#define MODEL_SPECIAL_FUNC_4TH_COLUMN (31*FW-3) #define MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF (34*FW-3) #define SD_LOGS_PERIOD_MIN 1 // 0.1s fastest period @@ -145,8 +145,9 @@ enum CustomFunctionsItems { ITEM_CUSTOM_FUNCTIONS_PARAM1, ITEM_CUSTOM_FUNCTIONS_PARAM2, ITEM_CUSTOM_FUNCTIONS_REPEAT, + ITEM_CUSTOM_FUNCTIONS_ENABLE, ITEM_CUSTOM_FUNCTIONS_COUNT, - ITEM_CUSTOM_FUNCTIONS_LAST = ITEM_CUSTOM_FUNCTIONS_COUNT-1 + ITEM_CUSTOM_FUNCTIONS_LAST = ITEM_CUSTOM_FUNCTIONS_COUNT - 1 }; void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomFunctionsContext * functionsContext) @@ -181,11 +182,12 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF CustomFunctionData * cfn = &functions[k]; uint8_t func = CFN_FUNC(cfn); - for (uint8_t j=0; j<5; j++) { + for (uint8_t j=0; j<6; j++) { uint8_t attr = ((sub==k && menuHorizontalPosition==j) ? ((s_editMode>0) ? BLINK|INVERS : INVERS) : 0); uint8_t active = (attr && s_editMode>0); switch (j) { case ITEM_CUSTOM_FUNCTIONS_SWITCH: + if(CFN_SWITCH(cfn) == SWSRC_NONE) CFN_ACTIVE(cfn) = 1; // Enable new function by default drawSwitch(MODEL_SPECIAL_FUNC_1ST_COLUMN, y, CFN_SWITCH(cfn), attr | ((functionsContext->activeSwitches & ((MASK_CFN_TYPE)1 << k)) ? BOLD : 0)); if (active || AUTOSWITCH_ENTER_LONG()) CHECK_INCDEC_SWITCH(event, CFN_SWITCH(cfn), SWSRC_FIRST, SWSRC_LAST, eeFlags, isSwitchAvailableInCustomFunctions); if (func == FUNC_OVERRIDE_CHANNEL && functions != g_model.customFn) { @@ -199,6 +201,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF if (active) { func = CFN_FUNC(cfn) = checkIncDec(event, CFN_FUNC(cfn), 0, FUNC_MAX-1, eeFlags, isAssignableFunctionAvailable); if (checkIncDec_Ret) CFN_RESET(cfn); + CFN_ACTIVE(cfn) = 1; // Enable if function is being changed } } else { @@ -411,11 +414,7 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF } case ITEM_CUSTOM_FUNCTIONS_REPEAT: - if (HAS_ENABLE_PARAM(func)) { - drawCheckBox(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), attr); - if (active) CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); - } - else if (HAS_REPEAT_PARAM(func)) { + if (HAS_REPEAT_PARAM(func)) { 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); @@ -439,6 +438,13 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF repeatLastCursorMove(event); } break; + + case ITEM_CUSTOM_FUNCTIONS_ENABLE: + drawCheckBox(MODEL_SPECIAL_FUNC_4TH_COLUMN_ONOFF, y, CFN_ACTIVE(cfn), + attr); + if (active) + CFN_ACTIVE(cfn) = checkIncDec(event, CFN_ACTIVE(cfn), 0, 1, eeFlags); + break; } } } @@ -446,6 +452,6 @@ void menuSpecialFunctions(event_t event, CustomFunctionData * functions, CustomF void menuModelSpecialFunctions(event_t event) { - MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|4/*repeated*/ }); + MENU(STR_MENUCUSTOMFUNC, menuTabModel, MENU_MODEL_SPECIAL_FUNCTIONS, MAX_SPECIAL_FUNCTIONS, { NAVIGATION_LINE_BY_LINE|5/*repeated*/ }); return menuSpecialFunctions(event, g_model.customFn, &modelFunctionsContext); } diff --git a/radio/src/gui/colorlcd/special_functions.cpp b/radio/src/gui/colorlcd/special_functions.cpp index 7cf76b2dbbe..5a98ae7ea0e 100644 --- a/radio/src/gui/colorlcd/special_functions.cpp +++ b/radio/src/gui/colorlcd/special_functions.cpp @@ -328,12 +328,8 @@ class SpecialFunctionEditPage : public Page } } - if (HAS_ENABLE_PARAM(func)) { - line = specialFunctionOneWindow->newLine(&grid); - new StaticText(line, rect_t{}, STR_ENABLE, 0, COLOR_THEME_PRIMARY1); - new ToggleSwitch(line, rect_t{}, - GET_SET_DEFAULT(CFN_ACTIVE(cfn))); - } else if (HAS_REPEAT_PARAM(func)) { // !1x 1x 1s 2s 3s ... + + if (HAS_REPEAT_PARAM(func)) { // !1x 1x 1s 2s 3s ... line = specialFunctionOneWindow->newLine(&grid); new StaticText(line, rect_t{}, STR_REPEAT, 0, COLOR_THEME_PRIMARY1); @@ -360,6 +356,11 @@ class SpecialFunctionEditPage : public Page }); } } + + line = specialFunctionOneWindow->newLine(&grid); + new StaticText(line, rect_t{}, STR_ENABLE, 0, COLOR_THEME_PRIMARY1); + new CheckBox(line, rect_t{}, GET_SET_DEFAULT(CFN_ACTIVE(cfn))); + } void buildBody(FormWindow *window) @@ -375,6 +376,10 @@ class SpecialFunctionEditPage : public Page CustomFunctionData *cfn = &functions[index]; + // Set new function to "enabled" by default + if (!CFN_SWITCH(cfn)) + CFN_ACTIVE(cfn) = true; + // Switch auto line = form->newLine(&grid); new StaticText(line, rect_t{}, STR_SF_SWITCH, 0, COLOR_THEME_PRIMARY1); @@ -411,6 +416,7 @@ class SpecialFunctionEditPage : public Page functionChoice->setSetValueHandler([=](int32_t newValue) { CFN_FUNC(cfn) = newValue; CFN_RESET(cfn); + CFN_ACTIVE(cfn) = 1; SET_DIRTY(); updateSpecialFunctionOneWindow(); }); @@ -515,10 +521,9 @@ class SpecialFunctionButton : public Button lv_obj_set_grid_cell(sfRepeat, LV_GRID_ALIGN_CENTER, FUNC_COL+1, 1, LV_GRID_ALIGN_CENTER, 0, NM_ROW_CNT); sfEnable = lv_obj_create(lvobj); - lv_obj_set_size(sfEnable, 22, 22); - lv_obj_add_flag(sfEnable, LV_OBJ_FLAG_HIDDEN); - lv_obj_set_style_border_width(sfEnable, 3, 0); - lv_obj_set_style_border_color(sfEnable, makeLvColor(COLOR_THEME_PRIMARY2), 0); + lv_obj_set_size(sfEnable, 16, 16); + lv_obj_set_style_border_width(sfEnable, 2, 0); + lv_obj_set_style_border_color(sfEnable, makeLvColor(COLOR_THEME_SECONDARY1), 0); lv_obj_set_style_border_opa(sfEnable, LV_OPA_100, 0); lv_obj_set_style_bg_color(sfEnable, makeLvColor(COLOR_THEME_ACTIVE), LV_STATE_CHECKED); lv_obj_set_style_bg_opa(sfEnable, LV_OPA_100, 0); @@ -665,16 +670,14 @@ class SpecialFunctionButton : public Button lv_label_set_text(sfFunc, s); - lv_obj_add_flag(sfEnable, LV_OBJ_FLAG_HIDDEN); s[0] = 0; - if (HAS_ENABLE_PARAM(func)) { - if (CFN_ACTIVE(cfn)) - lv_obj_add_state(sfEnable, LV_STATE_CHECKED); - else - lv_obj_clear_state(sfEnable, LV_STATE_CHECKED); - lv_obj_clear_flag(sfEnable, LV_OBJ_FLAG_HIDDEN); - } else if (HAS_REPEAT_PARAM(func)) { + if (CFN_ACTIVE(cfn)) + lv_obj_add_state(sfEnable, LV_STATE_CHECKED); + else + lv_obj_clear_state(sfEnable, LV_STATE_CHECKED); + + if (HAS_REPEAT_PARAM(func)) { if (func == FUNC_PLAY_SCRIPT) { sprintf(s, "(%s)", (CFN_PLAY_REPEAT(cfn) == 0) ? "On" : "1x"); } else { diff --git a/radio/src/myeeprom.h b/radio/src/myeeprom.h index f68d61e0e56..9cf5af92ec7 100644 --- a/radio/src/myeeprom.h +++ b/radio/src/myeeprom.h @@ -74,7 +74,7 @@ #define CFN_CH_INDEX(p) ((p)->all.param) #define CFN_GVAR_INDEX(p) ((p)->all.param) #define CFN_TIMER_INDEX(p) ((p)->all.param) -#define CFN_PLAY_REPEAT(p) ((p)->active) +#define CFN_PLAY_REPEAT(p) ((p)->repeat) #define CFN_PLAY_REPEAT_MUL 1 #define CFN_PLAY_REPEAT_NOSTART 0xFF #define CFN_GVAR_MODE(p) ((p)->all.mode) diff --git a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp index 4339040977c..0652798f6dd 100644 --- a/radio/src/storage/yaml/yaml_datastructs_funcs.cpp +++ b/radio/src/storage/yaml/yaml_datastructs_funcs.cpp @@ -1553,13 +1553,20 @@ static void r_customFn(void* user, uint8_t* data, uint32_t bitoffs, CFN_ACTIVE(cfn) = 1; } } - } else if (HAS_REPEAT_PARAM(func)) { - 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 + } else { + return; + } + + if (HAS_REPEAT_PARAM(func)) { + // eat_comma unconditionally + val += l_sep; + val_len -= l_sep; + if (val_len == 0 || val[0] != ',') + return; + val++; + val_len--; + + if (val_len == 2 && val[0] == '1' && val[1] == 'x') { CFN_PLAY_REPEAT(cfn) = 0; @@ -1696,36 +1703,34 @@ static bool w_customFn(void* user, uint8_t* data, uint32_t bitoffs, break; default: - add_comma = false; break; } - if (HAS_ENABLE_PARAM(func)) { if (add_comma) { // "," if (!wf(opaque,",",1)) return false; } + // "0/1" if (!wf(opaque,CFN_ACTIVE(cfn) ? "1":"0",1)) return false; - } else if (HAS_REPEAT_PARAM(func)) { - if (add_comma) { - // "," - if (!wf(opaque,",",1)) return false; - } - 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) { - // "!1x" - if (!wf(opaque,"!1x",3)) return false; - } else { - // repeat time in seconds - str = yaml_unsigned2str(CFN_PLAY_REPEAT(cfn) * CFN_PLAY_REPEAT_MUL); - if (!wf(opaque, str, strlen(str))) return false; - } + if (HAS_REPEAT_PARAM(func)) { + if (add_comma) { + // "," + if (!wf(opaque,",",1)) return false; + } + if (CFN_PLAY_REPEAT(cfn) == 0) { + // "1x" + if (!wf(opaque,"1x",2)) return false; + } else if (CFN_PLAY_REPEAT(cfn) == (int8_t)CFN_PLAY_REPEAT_NOSTART) { + // "!1x" + if (!wf(opaque,"!1x",3)) return false; + } else { + // repeat time in seconds + str = yaml_unsigned2str(CFN_PLAY_REPEAT(cfn) * CFN_PLAY_REPEAT_MUL); + if (!wf(opaque, str, strlen(str))) return false; + } } + if (!wf(opaque, "\"", 1)) return false; return true; } diff --git a/radio/src/thirdparty/libopenui/.clang-format b/radio/src/thirdparty/libopenui/.clang-format new file mode 100644 index 00000000000..913141780af --- /dev/null +++ b/radio/src/thirdparty/libopenui/.clang-format @@ -0,0 +1,6 @@ +--- +Language: Cpp +BasedOnStyle: Google +BreakBeforeBraces: Linux +BreakConstructorInitializers: AfterColon +... diff --git a/radio/src/thirdparty/libopenui/.gitignore b/radio/src/thirdparty/libopenui/.gitignore new file mode 100644 index 00000000000..e5d594669a5 --- /dev/null +++ b/radio/src/thirdparty/libopenui/.gitignore @@ -0,0 +1 @@ +src/thirdparty/stb/ diff --git a/radio/src/thirdparty/libopenui/.gitmodules b/radio/src/thirdparty/libopenui/.gitmodules new file mode 100644 index 00000000000..825bab72fb9 --- /dev/null +++ b/radio/src/thirdparty/libopenui/.gitmodules @@ -0,0 +1,7 @@ +[submodule "thirdparty/stb"] + path = thirdparty/stb + url = https://github.com/nothings/stb.git +[submodule "thirdparty/lvgl"] + path = thirdparty/lvgl + url = https://github.com/EdgeTX/lvgl.git + branch = release/v8.2 diff --git a/radio/src/thirdparty/libopenui/.idea/codeStyles/Project.xml b/radio/src/thirdparty/libopenui/.idea/codeStyles/Project.xml new file mode 100644 index 00000000000..efad3ce2786 --- /dev/null +++ b/radio/src/thirdparty/libopenui/.idea/codeStyles/Project.xml @@ -0,0 +1,32 @@ + + + + \ No newline at end of file diff --git a/radio/src/thirdparty/libopenui/.idea/codeStyles/codeStyleConfig.xml b/radio/src/thirdparty/libopenui/.idea/codeStyles/codeStyleConfig.xml new file mode 100644 index 00000000000..79ee123c2b2 --- /dev/null +++ b/radio/src/thirdparty/libopenui/.idea/codeStyles/codeStyleConfig.xml @@ -0,0 +1,5 @@ + + + + \ No newline at end of file