diff --git a/radio/src/gui/menu_model_limits.cpp b/radio/src/gui/menu_model_limits.cpp index 9e34f8244..f580dd643 100755 --- a/radio/src/gui/menu_model_limits.cpp +++ b/radio/src/gui/menu_model_limits.cpp @@ -264,7 +264,11 @@ void menuModelLimits(uint8_t event) lcd_outdezAtt(LIMITS_OFFSET_POS, y, ld->offset, attr|PREC1); #endif if (active) { - ld->offset = checkIncDec(event, ld->offset, -1000, 1000, EE_MODEL|NO_INCDEC_MARKS|DBLKEYS_1000); +#if defined(CPUARM) + ld->offset = checkIncDec(event, ld->offset, -1000, 1000, EE_MODEL, NULL, stops1000); +#else + ld->offset = checkIncDec(event, ld->offset, -1000, 1000, EE_MODEL|NO_INCDEC_MARKS); +#endif } else if (attr && event==EVT_KEY_LONG(KEY_MENU)) { copySticksToOffset(k); @@ -275,23 +279,31 @@ void menuModelLimits(uint8_t event) case ITEM_LIMITS_MIN: #if defined(PCBTARANIS) if (GV_IS_GV_VALUE(ld->min, -GV_RANGELARGE, GV_RANGELARGE) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { - ld->min = GVAR_MENU_ITEM(LIMITS_MIN_POS, y, ld->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, DBLKEYS_1000, event); + ld->min = GVAR_MENU_ITEM(LIMITS_MIN_POS, y, ld->min, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, 0, event); break; } #endif lcd_outdezAtt(LIMITS_MIN_POS, y, MIN_MAX_DISPLAY(ld->min-LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); - if (active) ld->min = LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->min-LIMITS_MIN_MAX_OFFSET, -limit, 0, EE_MODEL|DBLKEYS_1000); +#if defined(CPUARM) + if (active) ld->min = LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->min-LIMITS_MIN_MAX_OFFSET, -limit, 0, EE_MODEL, NULL, stops1000); +#else + if (active) ld->min = LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->min-LIMITS_MIN_MAX_OFFSET, -limit, 0, EE_MODEL); +#endif break; case ITEM_LIMITS_MAX: #if defined(PCBTARANIS) if (GV_IS_GV_VALUE(ld->max, -GV_RANGELARGE, GV_RANGELARGE) || (attr && event == EVT_KEY_LONG(KEY_ENTER))) { - ld->max = GVAR_MENU_ITEM(LIMITS_MAX_POS, y, ld->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, DBLKEYS_1000, event); + ld->max = GVAR_MENU_ITEM(LIMITS_MAX_POS, y, ld->max, -LIMIT_EXT_MAX, LIMIT_EXT_MAX, MIN_MAX_ATTR, 0, event); break; } #endif lcd_outdezAtt(LIMITS_MAX_POS, y, MIN_MAX_DISPLAY(ld->max+LIMITS_MIN_MAX_OFFSET), MIN_MAX_ATTR); - if (active) ld->max = -LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->max+LIMITS_MIN_MAX_OFFSET, 0, +limit, EE_MODEL|DBLKEYS_1000); +#if defined(CPUARM) + if (active) ld->max = -LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->max+LIMITS_MIN_MAX_OFFSET, 0, +limit, EE_MODEL, NULL, stops1000); +#else + if (active) ld->max = -LIMITS_MIN_MAX_OFFSET + checkIncDec(event, ld->max+LIMITS_MIN_MAX_OFFSET, 0, +limit, EE_MODEL); +#endif break; case ITEM_LIMITS_DIRECTION: diff --git a/radio/src/gui/menu_model_setup.cpp b/radio/src/gui/menu_model_setup.cpp index 6c1ecf81d..ecaf29b0f 100755 --- a/radio/src/gui/menu_model_setup.cpp +++ b/radio/src/gui/menu_model_setup.cpp @@ -176,7 +176,7 @@ void menuModelSetup(uint8_t event) #define FAILSAFE_ROWS(x) ((g_model.moduleData[x].rfProtocol==RF_PROTO_X16 || g_model.moduleData[x].rfProtocol==RF_PROTO_LR12) ? (g_model.moduleData[x].failsafeMode==FAILSAFE_CUSTOM ? (uint8_t)1 : (uint8_t)0) : HIDDEN_ROW) #define MODEL_SETUP_MAX_LINES (1+ITEM_MODEL_SETUP_MAX) #define POT_WARN_ITEMS() ((g_model.nPotsToWarn >> 6) ? (uint8_t)NUM_POTS : (uint8_t)0) - #define TIMER_ROWS 2, 0, CASE_PERSISTENT_TIMERS(0) 0, 0 + #define TIMER_ROWS 2|NAVIGATION_LINE_BY_LINE, 0, CASE_PERSISTENT_TIMERS(0) 0, 0 bool CURSOR_ON_CELL = (m_posHorz >= 0); MENU_TAB({ 0, 0, CASE_PCBTARANIS(0) TIMER_ROWS, TIMER_ROWS, TIMER_ROWS, 0, 1, 0, 0, CASE_PCBTARANIS(LABEL(Throttle)) 0, 0, 0, CASE_CPUARM(LABEL(PreflightCheck)) CASE_CPUARM(0) 0, uint8_t(NAVIGATION_LINE_BY_LINE|getSwitchWarningsAllowed()), ONE_2x2POS_DEFINED() ? TITLE_ROW : HIDDEN_ROW, POT_WARN_ITEMS(), NAVIGATION_LINE_BY_LINE|(NUM_STICKS+NUM_POTS+NUM_ROTARY_ENCODERS-1), 0, LABEL(InternalModule), 0, IF_INTERNAL_MODULE_ON(1), IF_INTERNAL_MODULE_ON(IS_D8_RX(0) ? (uint8_t)1 : (uint8_t)2), IF_INTERNAL_MODULE_ON(FAILSAFE_ROWS(INTERNAL_MODULE)), LABEL(ExternalModule), (IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)1 : (uint8_t)0, EXTERNAL_MODULE_CHANNELS_ROWS(), (IS_MODULE_XJT(EXTERNAL_MODULE) && IS_D8_RX(EXTERNAL_MODULE)) ? (uint8_t)1 : (IS_MODULE_PPM(EXTERNAL_MODULE) || IS_MODULE_XJT(EXTERNAL_MODULE) || IS_MODULE_DSM2(EXTERNAL_MODULE)) ? (uint8_t)2 : HIDDEN_ROW, IF_EXTERNAL_MODULE_XJT(FAILSAFE_ROWS(EXTERNAL_MODULE)), LABEL(Trainer), 0, TRAINER_CHANNELS_ROWS(), IF_TRAINER_ON(2)}); #elif defined(CPUARM) @@ -278,13 +278,22 @@ void menuModelSetup(uint8_t event) putsTimerMode(MODEL_SETUP_2ND_COLUMN, y, timer->mode, m_posHorz==0 ? attr : 0); putsTimer(MODEL_SETUP_2ND_COLUMN+5*FW-2+5*FWNUM+1, y, timer->start, m_posHorz==1 ? attr : 0, m_posHorz==2 ? attr : 0); #if defined(PCBTARANIS) - if (attr && m_posHorz < 0) lcd_filled_rect(MODEL_SETUP_2ND_COLUMN, y, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH, 8); + if (attr && m_posHorz < 0) lcd_filled_rect(MODEL_SETUP_2ND_COLUMN-1, y-1, LCD_W-MODEL_SETUP_2ND_COLUMN-MENUS_SCROLLBAR_WIDTH+1, FH+1); #endif if (attr && (editMode>0 || p1valdiff)) { div_t qr = div(timer->start, 60); switch (m_posHorz) { case 0: - CHECK_INCDEC_MODELVAR_CHECK(event, timer->mode, SWSRC_FIRST, TMRMODE_COUNT+SWSRC_LAST-1/*SWSRC_None removed*/, isSwitchAvailableInTimers); + { +#if defined(CPUARM) + int8_t timerMode = timer->mode; + if (timerMode < 0) timerMode -= TMRMODE_COUNT-1; + CHECK_INCDEC_MODELVAR_CHECK(event, timerMode, -TMRMODE_COUNT-SWSRC_LAST+1, TMRMODE_COUNT+SWSRC_LAST-1, isSwitchAvailableInTimers); + if (timerMode < 0) timerMode += TMRMODE_COUNT-1; + timer->mode = timerMode; +#else + CHECK_INCDEC_MODELVAR(event, timer->mode, SWSRC_FIRST, TMRMODE_COUNT+SWSRC_LAST-1/*SWSRC_None removed*/); +#endif #if defined(AUTOSWITCH) if (s_editMode>0) { int8_t val = timer->mode - (TMRMODE_COUNT-1); @@ -296,6 +305,7 @@ void menuModelSetup(uint8_t event) } #endif break; + } case 1: CHECK_INCDEC_MODELVAR_ZERO(event, qr.quot, 59); timer->start = qr.rem + qr.quot*60; diff --git a/radio/src/gui/menus.cpp b/radio/src/gui/menus.cpp index 68e7ade84..129aceea2 100644 --- a/radio/src/gui/menus.cpp +++ b/radio/src/gui/menus.cpp @@ -135,35 +135,39 @@ int8_t checkIncDecMovedSwitch(int8_t val) int8_t checkIncDec_Ret; #if defined(CPUARM) -int checkIncDec(uint8_t event, int val, int i_min, int i_max, uint8_t i_flags, IsValueAvailable isValueAvailable) -#else -int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) -#endif +const CheckIncDecStops &stops100 = (const CheckIncDecStops&) (const int[]) { 3, -100, 0, 100 }; +const CheckIncDecStops &stops1000 = (const CheckIncDecStops&) (const int[]) { 3, -1000, 0, 1000 }; + +int checkIncDec(unsigned int event, int val, int i_min, int i_max, unsigned int i_flags, IsValueAvailable isValueAvailable, const CheckIncDecStops &stops) { int newval = val; #if defined(DBLKEYS) - uint8_t in = KEYS_PRESSED(); + unsigned int in = KEYS_PRESSED(); if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) { bool dblkey = true; - if (DBLKEYS_PRESSED_RGT_LFT(in)) - newval = -val; + if (DBLKEYS_PRESSED_RGT_LFT(in)) { + if (!isValueAvailable || isValueAvailable(-val)) + newval = -val; + } else if (DBLKEYS_PRESSED_RGT_UP(in)) { - newval = (i_max > 100 ? 100 : i_max); -#if defined(CPUARM) - if (i_flags & DBLKEYS_1000) newval *= 10; -#endif + newval = (i_max > stops.max() ? stops.max() : i_max); + while (isValueAvailable && !isValueAvailable(newval) && newval>i_min) { + --newval; + } } else if (DBLKEYS_PRESSED_LFT_DWN(in)) { - newval = (i_min < -100 ? -100 : i_min); -#if defined(CPUARM) - if (i_flags & DBLKEYS_1000) newval *= 10; -#endif + newval = (i_min < stops.min() ? stops.min() : i_min); + while (isValueAvailable && !isValueAvailable(newval) && newval0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) { #endif -#if defined(CPUARM) + do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval += min(10, i_max-val); @@ -195,23 +199,22 @@ int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, ui newval++; } } while (isValueAvailable && !isValueAvailable(newval) && newval<=i_max); + if (newval > i_max) { newval = val; killEvents(event); AUDIO_WARNING2(); } - else -#else - newval++; -#endif - AUDIO_KEYPAD_UP(); + else { + AUDIO_KEYPAD_UP(); + } } #if defined(PCBTARANIS) else if (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN))) { #else else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) { #endif -#if defined(CPUARM) + do { if (IS_KEY_REPT(event) && (i_flags & INCDEC_REP10)) { newval -= min(10, val-i_min); @@ -220,15 +223,115 @@ int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, ui newval--; } } while (isValueAvailable && !isValueAvailable(newval) && newval>=i_min); + if (newval < i_min) { newval = val; killEvents(event); AUDIO_WARNING2(); } - else -#else - newval--; + else { + AUDIO_KEYPAD_DOWN(); + } + } + + if (!READ_ONLY() && i_min==0 && i_max==1 && (event==EVT_KEY_BREAK(KEY_ENTER) || IS_ROTARY_BREAK(event))) { + s_editMode = 0; + newval = !val; + } + +#if defined(NAVIGATION_POT1) + // change values based on P1 + newval -= p1valdiff; + p1valdiff = 0; #endif + +#if defined(AUTOSWITCH) + if (i_flags & INCDEC_SWITCH) { + newval = checkIncDecMovedSwitch(newval); + } +#endif + +#if defined(AUTOSOURCE) + if (i_flags & INCDEC_SOURCE) { + if (s_editMode>0) { + int source = GET_MOVED_SOURCE(i_min, i_max); + if (source) { + newval = source; + } +#if defined(AUTOSWITCH) + else { + unsigned int swtch = abs(getMovedSwitch()); + if (swtch) { + newval = switchToMix(swtch); + } + } +#endif + } + } +#endif + + if (newval > i_max || newval < i_min) { + newval = (newval > i_max ? i_max : i_min); + killEvents(event); + AUDIO_WARNING2(); + } + + if (newval != val) { + if (!(i_flags & NO_INCDEC_MARKS) && (newval != i_max) && (newval != i_min) && stops.contains(newval) && !IS_ROTARY_EVENT(event)) { + pauseEvents(event); // delay before auto-repeat continues + if (newval>val) // without AUDIO it's optimized, because the 2 sounds are the same + AUDIO_KEYPAD_UP(); + else + AUDIO_KEYPAD_DOWN(); + } + eeDirty(i_flags & (EE_GENERAL|EE_MODEL)); + checkIncDec_Ret = (newval > val ? 1 : -1); + } + else { + checkIncDec_Ret = 0; + } + return newval; +} +#else +int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, uint8_t i_flags) +{ + int16_t newval = val; + +#if defined(DBLKEYS) + uint8_t in = KEYS_PRESSED(); + if (!(i_flags & NO_DBLKEYS) && (EVT_KEY_MASK(event))) { + bool dblkey = true; + if (DBLKEYS_PRESSED_RGT_LFT(in)) + newval = -val; + else if (DBLKEYS_PRESSED_RGT_UP(in)) { + newval = (i_max > 100 ? 100 : i_max); + } + else if (DBLKEYS_PRESSED_LFT_DWN(in)) { + newval = (i_min < -100 ? -100 : i_min); + } + else if (DBLKEYS_PRESSED_UP_DWN(in)) { + newval = 0; + } + else { + dblkey = false; + } + + if (dblkey) { + killEvents(KEY_UP); + killEvents(KEY_DOWN); + killEvents(KEY_RIGHT); + killEvents(KEY_LEFT); + event = 0; + } + } +#endif + + if (event==EVT_KEY_FIRST(KEY_RIGHT) || event==EVT_KEY_REPT(KEY_RIGHT) || (s_editMode>0 && (IS_ROTARY_RIGHT(event) || event==EVT_KEY_FIRST(KEY_UP) || event==EVT_KEY_REPT(KEY_UP)))) { + newval++; + AUDIO_KEYPAD_UP(); + } + else if (event==EVT_KEY_FIRST(KEY_LEFT) || event==EVT_KEY_REPT(KEY_LEFT) || (s_editMode>0 && (IS_ROTARY_LEFT(event) || event==EVT_KEY_FIRST(KEY_DOWN) || event==EVT_KEY_REPT(KEY_DOWN)))) { + newval--; AUDIO_KEYPAD_DOWN(); } @@ -290,6 +393,7 @@ int16_t checkIncDec(uint8_t event, int16_t val, int16_t i_min, int16_t i_max, ui } return newval; } +#endif #if defined(CPUM64) int8_t checkIncDecModel(uint8_t event, int8_t i_val, int8_t i_min, int8_t i_max) @@ -1461,10 +1565,12 @@ bool isSourceAvailableInCustomSwitches(int source) { bool result = isSourceAvailable(source); +#if defined(FRSKY) if (result && source>=MIXSRC_FIRST_TELEM && source<=MIXSRC_LAST_TELEM) { div_t qr = div(source-MIXSRC_FIRST_TELEM, 3); result = isTelemetryFieldComparisonAvailable(qr.quot); } +#endif return result; } @@ -1604,10 +1710,16 @@ bool isSwitchAvailableInMixes(int swtch) bool isSwitchAvailableInTimers(int swtch) { if (swtch >= 0) { - if (swtch < TMRMODE_COUNT) { + if (swtch < TMRMODE_COUNT) return true; - } - swtch -= TMRMODE_COUNT-1; + else + swtch -= TMRMODE_COUNT-1; + } + else { + if (swtch > -TMRMODE_COUNT) + return false; + else + swtch += TMRMODE_COUNT-1; } return isSwitchAvailable(swtch, TimersContext); diff --git a/radio/src/gui/menus.h b/radio/src/gui/menus.h index f2b115a34..9f84472fd 100644 --- a/radio/src/gui/menus.h +++ b/radio/src/gui/menus.h @@ -185,7 +185,6 @@ extern int8_t s_editMode; // global editmode #define NO_INCDEC_MARKS 0x04 #define INCDEC_SWITCH 0x08 #define INCDEC_SOURCE 0x10 -#define DBLKEYS_1000 0x20 #define INCDEC_REP10 0x40 #define NO_DBLKEYS 0x80 @@ -195,9 +194,31 @@ extern int8_t s_editMode; // global editmode #if defined(CPUARM) typedef bool (*IsValueAvailable)(int); -int checkIncDec(uint8_t event, int val, int i_min, int i_max, uint8_t i_flags=0, IsValueAvailable isValueAvailable=NULL); +struct CheckIncDecStops { + const int count; + const int stops[]; + int min() const + { + return stops[0]; + } + int max() const + { + return stops[count-1]; + } + bool contains(int value) const + { + for (int i=0; i