Merge branch 'MHP30' of https://github.com/Ralim/IronOS into MHP30

This commit is contained in:
Ben V. Brown
2021-05-06 19:39:09 +10:00
4 changed files with 121 additions and 72 deletions

View File

@@ -15,7 +15,7 @@
"InputVoltageString": "V Eingang: ", "InputVoltageString": "V Eingang: ",
"WarningTipTempString": "Temperatur: ", "WarningTipTempString": "Temperatur: ",
"BadTipString": "Spitze Defekt", "BadTipString": "Spitze Defekt",
"SleepingSimpleString": "Zzz ", "SleepingSimpleString": "Zzzz",
"SleepingAdvancedString": "Ruhemodus...", "SleepingAdvancedString": "Ruhemodus...",
"WarningSimpleString": "HEISS!", "WarningSimpleString": "HEISS!",
"WarningAdvancedString": "! Achtung Heiß !", "WarningAdvancedString": "! Achtung Heiß !",
@@ -34,12 +34,12 @@
"zurückgesetzt!" "zurückgesetzt!"
], ],
"NoAccelerometerMessage": [ "NoAccelerometerMessage": [
"Kein Bewegungssensor", "Bewegungssensor",
"erkannt!" "nicht erkannt!"
], ],
"NoPowerDeliveryMessage": [ "NoPowerDeliveryMessage": [
"Kein USB-PD IC", "USB-PD IC",
"erkannt!" "nicht erkannt!"
], ],
"LockingKeysString": "GESPERRT", "LockingKeysString": "GESPERRT",
"UnlockingKeysString": "ENTSPERRT", "UnlockingKeysString": "ENTSPERRT",
@@ -128,7 +128,7 @@
"ShutdownTimeout": { "ShutdownTimeout": {
"text2": [ "text2": [
"Abschalt-", "Abschalt-",
"zeit" "verzög."
], ],
"desc": "Dauer vor automatischer Abschaltung <M=Minuten>" "desc": "Dauer vor automatischer Abschaltung <M=Minuten>"
}, },
@@ -219,14 +219,14 @@
"QCMaxVoltage": { "QCMaxVoltage": {
"text2": [ "text2": [
"Spannungs-", "Spannungs-",
"grenze" "maximum"
], ],
"desc": "Maximal zulässige Spannung der verwendeten Spannungsversorgung <V=Volt>" "desc": "Maximal zulässige Spannung der verwendeten Spannungsversorgung <V=Volt>"
}, },
"PowerLimit": { "PowerLimit": {
"text2": [ "text2": [
"Leistungs-", "Leistungs-",
"grenze" "maximum"
], ],
"desc": "Maximale zulässige Leistungsaufnahme des Lötkolbens <W=Watt>" "desc": "Maximale zulässige Leistungsaufnahme des Lötkolbens <W=Watt>"
}, },
@@ -260,8 +260,8 @@
}, },
"HallEffSensitivity": { "HallEffSensitivity": {
"text2": [ "text2": [
"Hall-Sonde", "Empfindlichkeit",
"Empfindlichkeit" "der Hall-Sonde"
], ],
"desc": "Empfindlichkeit der Hall-Sonde beim Erkennen des Ruhemodus <A=aus | N=niedrig | M=mittel | H=hoch>" "desc": "Empfindlichkeit der Hall-Sonde beim Erkennen des Ruhemodus <A=aus | N=niedrig | M=mittel | H=hoch>"
}, },
@@ -274,17 +274,17 @@
}, },
"MinVolCell": { "MinVolCell": {
"text2": [ "text2": [
"Minimum", "Minimale",
"Spannung" "Spannung"
], ],
"desc": "Minimal zulässige Spannung pro Zelle <Volt> <3S: 3,0V - 3,7V, 4/5/6S: 2,4V - 3,7V>" "desc": "Minimal zulässige Spannung pro Zelle <3S: 3,0V - 3,7V | 4/5/6S: 2,4V - 3,7V>"
}, },
"AnimLoop": { "AnimLoop": {
"text2": [ "text2": [
"Anim.", "Anim.",
"Schleife" "Schleife"
], ],
"desc": "Icon-Animationen im Stammmenü wiederholen" "desc": "Icon-Animationen im Hauptmenü wiederholen"
}, },
"AnimSpeed": { "AnimSpeed": {
"text2": [ "text2": [
@@ -295,21 +295,21 @@
}, },
"PowerPulseWait": { "PowerPulseWait": {
"text2": [ "text2": [
"Leistungsimpulse", "Impuls-",
"Wartezeit" "verzögerung"
], ],
"desc": "Dauer vor Abgabe von Wachhalteimpulsen (x 2,5s)" "desc": "Dauer vor Abgabe von Wachhalteimpulsen <x 2,5s>"
}, },
"PowerPulseDuration": { "PowerPulseDuration": {
"text2": [ "text2": [
"Leistungsimpulse", "Impuls-",
"Dauer" "dauer"
], ],
"desc": "Dauer des Wachhalteimpulses (x 250ms)" "desc": "Dauer des Wachhalteimpulses <x 0,25s>"
}, },
"LanguageSwitch": { "LanguageSwitch": {
"text2": [ "text2": [
"Language:", "Sprache:",
" DE Deutsch" " DE Deutsch"
], ],
"desc": "" "desc": ""

View File

@@ -218,7 +218,7 @@
"QCMaxVoltage": { "QCMaxVoltage": {
"text2": [ "text2": [
"Voltaggio", "Voltaggio",
"Quick Charge" "QC"
], ],
"desc": "Imposta il massimo voltaggio negoziabile con un alimentatore Quick Charge" "desc": "Imposta il massimo voltaggio negoziabile con un alimentatore Quick Charge"
}, },
@@ -269,14 +269,14 @@
"Blocco", "Blocco",
"tasti" "tasti"
], ],
"desc": "Blocca i tasti durante la modalità Saldatura; tieni premuto entrambi per bloccare o sbloccare [D: disattiva; T: blocca Turbo; C: blocco completo]" "desc": "Blocca i tasti durante la modalità Saldatura; tieni premuto entrambi per bloccare o sbloccare [D: disattiva; T: consenti Turbo; C: blocco completo]"
}, },
"MinVolCell": { "MinVolCell": {
"text2": [ "text2": [
"Tensione", "Tensione",
"min celle" "min celle"
], ],
"desc": "Modifica il valore di tensione minima \"di scaricamento\" per le celle di una batteria Li-Po [3S: 3,0-3,7 V; 4S/5S/6S: 2,4-3,7 V]" "desc": "Modifica la tensione di minima carica delle celle di una batteria Li-Po [3S: 3,0-3,7 V; 4S/5S/6S: 2,4-3,7 V]"
}, },
"AnimLoop": { "AnimLoop": {
"text2": [ "text2": [
@@ -308,7 +308,7 @@
}, },
"LanguageSwitch": { "LanguageSwitch": {
"text2": [ "text2": [
"Language:", "Lingua:",
" IT Italiano" " IT Italiano"
], ],
"desc": "" "desc": ""

View File

@@ -973,6 +973,8 @@ static bool settings_setHallEffect(void) {
} }
#endif #endif
// Indicates whether a menu transition is in progress, so that the menu icon
// animation is paused during the transition.
static bool animOpenState = false; static bool animOpenState = false;
static void displayMenu(size_t index) { static void displayMenu(size_t index) {
@@ -984,7 +986,6 @@ static void displayMenu(size_t index) {
// 2 pixel wide scrolling indicator // 2 pixel wide scrolling indicator
static TickType_t menuSwitchLoopTick = 0; static TickType_t menuSwitchLoopTick = 0;
static size_t menuCurrentIndex = sizeof(rootSettingsMenu) + 1; static size_t menuCurrentIndex = sizeof(rootSettingsMenu) + 1;
static size_t currentFrame = 0;
TickType_t step = TICKS_100MS * 5; TickType_t step = TICKS_100MS * 5;
switch (systemSettings.animationSpeed) { switch (systemSettings.animationSpeed) {
case settingOffSpeed_t::FAST: case settingOffSpeed_t::FAST:
@@ -996,17 +997,25 @@ static void displayMenu(size_t index) {
default: // SLOW or off - defaulted above default: // SLOW or off - defaulted above
break; break;
} }
if (!animOpenState) { size_t currentFrame;
if (!animOpenState && systemSettings.animationSpeed != settingOffSpeed_t::OFF) {
if (menuCurrentIndex != index) { if (menuCurrentIndex != index) {
menuCurrentIndex = index; menuCurrentIndex = index;
currentFrame = systemSettings.animationSpeed == settingOffSpeed_t::OFF ? 2 : 0;
menuSwitchLoopTick = xTaskGetTickCount(); menuSwitchLoopTick = xTaskGetTickCount();
} }
if (systemSettings.animationSpeed && (systemSettings.animationLoop || currentFrame != 2)) { currentFrame = ((xTaskGetTickCount() - menuSwitchLoopTick) / step);
currentFrame = ((xTaskGetTickCount() - menuSwitchLoopTick) / step) % 3; if (systemSettings.animationLoop) {
currentFrame %= 3;
} else if (currentFrame > 2) {
currentFrame = 2;
} }
OLED::drawArea(OLED_WIDTH - 16 - 2, 0, 16, 16, (&SettingsMenuIcons[index][(16 * 2) * currentFrame])); } else {
// We want the animation to restart after completing the transition.
menuCurrentIndex = sizeof(rootSettingsMenu) + 1;
// Always draw the last frame if icon animation is disabled.
currentFrame = systemSettings.animationSpeed == settingOffSpeed_t::OFF ? 2 : 0;
} }
OLED::drawArea(OLED_WIDTH - 16 - 2, 0, 16, 16, (&SettingsMenuIcons[index][(16 * 2) * currentFrame]));
} }
static bool settings_displayCalibrateVIN(void) { static bool settings_displayCalibrateVIN(void) {
@@ -1059,6 +1068,18 @@ static bool settings_enterAdvancedMenu(void) {
void gui_Menu(const menuitem *menu) { void gui_Menu(const menuitem *menu) {
// Draw the settings menu and provide iteration support etc // Draw the settings menu and provide iteration support etc
// This is used to detect whether a menu-exit transition should be played.
static bool wasInGuiMenu;
wasInGuiMenu = true;
enum class NavState {
Idle,
Entering,
ScrollingDown,
Exiting,
};
uint8_t currentScreen = 0; uint8_t currentScreen = 0;
TickType_t autoRepeatTimer = 0; TickType_t autoRepeatTimer = 0;
TickType_t autoRepeatAcceleration = 0; TickType_t autoRepeatAcceleration = 0;
@@ -1068,7 +1089,7 @@ void gui_Menu(const menuitem *menu) {
uint8_t scrollContentSize = 0; uint8_t scrollContentSize = 0;
bool scrollBlink = false; bool scrollBlink = false;
bool lastValue = false; bool lastValue = false;
bool scrollingDown = false; NavState navState = NavState::Entering;
ScrollMessage scrollMessage; ScrollMessage scrollMessage;
@@ -1076,42 +1097,58 @@ void gui_Menu(const menuitem *menu) {
scrollContentSize += 1; scrollContentSize += 1;
} }
// Animated menu opening.
if (menu[currentScreen].draw != nullptr) {
// This menu is drawn in a secondary framebuffer.
// Then we play a transition from the current primary
// framebuffer to the new buffer.
// The extra buffer is discarded at the end of the transition.
animOpenState = true;
OLED::useSecondaryFramebuffer(true);
OLED::setCursor(0, 0);
OLED::clearScreen();
menu[currentScreen].draw();
OLED::useSecondaryFramebuffer(false);
OLED::transitionSecondaryFramebuffer(true);
animOpenState = false;
}
while ((menu[currentScreen].draw != nullptr) && earlyExit == false) { while ((menu[currentScreen].draw != nullptr) && earlyExit == false) {
OLED::setCursor(0, 0);
if (scrollingDown) { // Handle menu transition:
if (navState != NavState::Idle) {
// Check if this menu item shall be skipped. If it shall be skipped,
// `draw()` returns true. Draw on the secondary framebuffer as we want
// to keep the primary framebuffer intact for the upcoming transition
// animation.
OLED::useSecondaryFramebuffer(true);
if (menu[currentScreen].draw()) {
currentScreen++;
OLED::useSecondaryFramebuffer(false);
continue;
}
animOpenState = true; animOpenState = true;
// The menu entering/exiting transition uses the secondary framebuffer,
// but the scroll down transition does not.
if (navState == NavState::ScrollingDown) {
OLED::useSecondaryFramebuffer(false);
}
OLED::setCursor(0, 0);
OLED::clearScreen();
menu[currentScreen].draw();
if (navState == NavState::ScrollingDown) {
// Play the scroll down animation.
OLED::maskScrollIndicatorOnOLED();
OLED::transitionScrollDown();
} else {
// The menu was drawn in a secondary framebuffer.
// Now we play a transition from the pre-drawn primary
// framebuffer to the new buffer.
// The extra buffer is discarded at the end of the transition.
OLED::useSecondaryFramebuffer(false);
OLED::transitionSecondaryFramebuffer(navState == NavState::Entering);
}
animOpenState = false;
navState = NavState::Idle;
} }
// If the user has hesitated for >=3 seconds, show the long text // If the user has hesitated for >=3 seconds, show the long text
// Otherwise "draw" the option // Otherwise "draw" the option
if ((xTaskGetTickCount() - lastButtonTime < (TICKS_SECOND * 3)) || menu[currentScreen].description == 0) { if ((xTaskGetTickCount() - lastButtonTime < (TICKS_SECOND * 3)) || menu[currentScreen].description == 0) {
lcdRefresh = true; lcdRefresh = true;
OLED::setCursor(0, 0);
OLED::clearScreen(); OLED::clearScreen();
if (menu[currentScreen].draw()) { menu[currentScreen].draw();
currentScreen++;
lcdRefresh = false;
}
uint8_t indicatorHeight = OLED_HEIGHT / scrollContentSize; uint8_t indicatorHeight = OLED_HEIGHT / scrollContentSize;
uint8_t position = OLED_HEIGHT * currentScreen / scrollContentSize; uint8_t position = OLED_HEIGHT * currentScreen / scrollContentSize;
if (lastValue) if (lastValue)
scrollBlink = !scrollBlink; scrollBlink = !scrollBlink;
if ((!lastValue || !scrollBlink) && !scrollingDown) if (!lastValue || !scrollBlink)
OLED::drawScrollIndicator(position, indicatorHeight); OLED::drawScrollIndicator(position, indicatorHeight);
} else { } else {
// Draw description // Draw description
@@ -1120,15 +1157,8 @@ void gui_Menu(const menuitem *menu) {
} }
if (lcdRefresh) { if (lcdRefresh) {
if (scrollingDown) { OLED::refresh(); // update the LCD
OLED::maskScrollIndicatorOnOLED(); osDelay(40);
OLED::transitionScrollDown();
scrollingDown = false;
animOpenState = false;
} else {
OLED::refresh(); // update the LCD
osDelay(40);
}
lcdRefresh = false; lcdRefresh = false;
} }
@@ -1139,6 +1169,16 @@ void gui_Menu(const menuitem *menu) {
lastButtonState = buttons; lastButtonState = buttons;
} }
auto callIncrementHandler = [&]() {
wasInGuiMenu = false;
bool res = menu[currentScreen].incrementHandler();
if (wasInGuiMenu) {
navState = NavState::Exiting;
}
wasInGuiMenu = true;
return res;
};
switch (buttons) { switch (buttons) {
case BUTTON_BOTH: case BUTTON_BOTH:
earlyExit = true; // will make us exit next loop earlyExit = true; // will make us exit next loop
@@ -1148,7 +1188,7 @@ void gui_Menu(const menuitem *menu) {
// increment // increment
if (scrollMessage.isReset()) { if (scrollMessage.isReset()) {
if (menu[currentScreen].incrementHandler != nullptr) { if (menu[currentScreen].incrementHandler != nullptr) {
lastValue = menu[currentScreen].incrementHandler(); lastValue = callIncrementHandler();
} else { } else {
earlyExit = true; earlyExit = true;
} }
@@ -1158,14 +1198,14 @@ void gui_Menu(const menuitem *menu) {
case BUTTON_B_SHORT: case BUTTON_B_SHORT:
if (scrollMessage.isReset()) { if (scrollMessage.isReset()) {
currentScreen++; currentScreen++;
scrollingDown = true; navState = NavState::ScrollingDown;
lastValue = false; lastValue = false;
} else } else
scrollMessage.reset(); scrollMessage.reset();
break; break;
case BUTTON_F_LONG: case BUTTON_F_LONG:
if (xTaskGetTickCount() + autoRepeatAcceleration > autoRepeatTimer + PRESS_ACCEL_INTERVAL_MAX) { if (xTaskGetTickCount() + autoRepeatAcceleration > autoRepeatTimer + PRESS_ACCEL_INTERVAL_MAX) {
if ((lastValue = menu[currentScreen].incrementHandler())) if ((lastValue = callIncrementHandler()))
autoRepeatTimer = 1000; autoRepeatTimer = 1000;
else else
autoRepeatTimer = 0; autoRepeatTimer = 0;
@@ -1180,7 +1220,7 @@ void gui_Menu(const menuitem *menu) {
case BUTTON_B_LONG: case BUTTON_B_LONG:
if (xTaskGetTickCount() - autoRepeatTimer + autoRepeatAcceleration > PRESS_ACCEL_INTERVAL_MAX) { if (xTaskGetTickCount() - autoRepeatTimer + autoRepeatAcceleration > PRESS_ACCEL_INTERVAL_MAX) {
currentScreen++; currentScreen++;
scrollingDown = true; navState = NavState::ScrollingDown;
autoRepeatTimer = xTaskGetTickCount(); autoRepeatTimer = xTaskGetTickCount();
scrollMessage.reset(); scrollMessage.reset();
@@ -1203,8 +1243,6 @@ void gui_Menu(const menuitem *menu) {
scrollMessage.reset(); scrollMessage.reset();
} }
} }
animOpenState = false;
} }
void enterSettingsMenu() { void enterSettingsMenu() {

View File

@@ -787,6 +787,7 @@ void startGUITask(void const *argument __unused) {
bool buttonLockout = false; bool buttonLockout = false;
bool tempOnDisplay = false; bool tempOnDisplay = false;
bool tipDisconnectedDisplay = false; bool tipDisconnectedDisplay = false;
bool showExitMenuTransition = false;
{ {
// Generate the flipped screen into ram for later use // Generate the flipped screen into ram for later use
// flipped is generated by flipping each row // flipped is generated by flipping each row
@@ -855,6 +856,10 @@ void startGUITask(void const *argument __unused) {
break; break;
case BUTTON_B_SHORT: case BUTTON_B_SHORT:
enterSettingsMenu(); // enter the settings menu enterSettingsMenu(); // enter the settings menu
{
OLED::useSecondaryFramebuffer(true);
showExitMenuTransition = true;
}
buttonLockout = true; buttonLockout = true;
break; break;
default: default:
@@ -960,7 +965,13 @@ void startGUITask(void const *argument __unused) {
} }
} }
OLED::refresh(); if (showExitMenuTransition) {
GUIDelay(); OLED::useSecondaryFramebuffer(false);
OLED::transitionSecondaryFramebuffer(false);
showExitMenuTransition = false;
} else {
OLED::refresh();
GUIDelay();
}
} }
} }