diff --git a/source/Core/Threads/GUIRendering.md b/source/Core/Threads/GUIRendering.md index ec65038e..cd67187c 100644 --- a/source/Core/Threads/GUIRendering.md +++ b/source/Core/Threads/GUIRendering.md @@ -7,6 +7,17 @@ This is due to a few aims: 2. Allows external events to change the state 3. Means state can be read/write over BLE or other external control interfaces +## Transitions + +When changing the view to a new view it can be preferable to transition using an animation. +The tooling provides for left, right and down animations at this point. +The use of these gives a notion of "direction" when navigating the menu. + +``` + + +``` + ## TODO notes On settings menu exit: diff --git a/source/Core/Threads/GUIThread.cpp b/source/Core/Threads/GUIThread.cpp index 33cc81bf..ff44690f 100644 --- a/source/Core/Threads/GUIThread.cpp +++ b/source/Core/Threads/GUIThread.cpp @@ -43,7 +43,7 @@ void guiRenderLoop(void) { OLED::clearScreen(); // Clear ready for render pass // Read button state ButtonState buttons = getButtonState(); - // Enforce screen on if buttons pressed + // Enforce screen on if buttons pressed, movement, hot tip etc if (buttons != BUTTON_NONE) { OLED::setDisplayState(OLED::DisplayState::ON); } else { @@ -112,15 +112,34 @@ void guiRenderLoop(void) { case OperatingMode::ThermalRunaway: break; }; - // Render done, draw it out - OLED::refresh(); // Update state holders if (newMode != currentOperatingMode) { context.viewEnterTime = xTaskGetTickCount(); context.previousMode = currentOperatingMode; memset(&context.scratch_state, 0, sizeof(context.scratch_state)); currentOperatingMode = newMode; + // If the transition marker is set, we need to make the next draw occur to the secondary buffer so we have something to transition to + if (context.transitionMode != TransitionAnimation::None) { + OLED::refresh(); + OLED::useSecondaryFramebuffer(true); + return; // Exit early to avoid refresh with new framebuffer + } + } else if (context.transitionMode != TransitionAnimation::None) { + // We haven't changed mode but transition is set, so we are at the other side of a transition + // We now want to transition from old contents (main buffer) to new contents (secondary buffer) + switch (context.transitionMode) { + case TransitionAnimation::Down: + break; + case TransitionAnimation::Left: + break; + case TransitionAnimation::Right: + break; + } + OLED::useSecondaryFramebuffer(false); + context.transitionMode = TransitionAnimation::None; // Clear transition flag } + // Render done, draw it out + OLED::refresh(); } OperatingMode handle_post_init_state() { diff --git a/source/Core/Threads/OperatingModes/OperatingModes.h b/source/Core/Threads/OperatingModes/OperatingModes.h index fb42251f..736be866 100644 --- a/source/Core/Threads/OperatingModes/OperatingModes.h +++ b/source/Core/Threads/OperatingModes/OperatingModes.h @@ -41,10 +41,14 @@ enum class OperatingMode { ThermalRunaway, // Thermal Runaway warning state. }; +enum class TransitionAnimation { None = 0, Right, Left, Down }; + // Generic context struct used for gui functions to be able to retain state struct guiContext { - TickType_t viewEnterTime; // Set to ticks when this view state was first entered - OperatingMode previousMode; + TickType_t viewEnterTime; // Set to ticks when this view state was first entered + OperatingMode previousMode; + TransitionAnimation transitionMode; + // Below is scratch state, this is retained over re-draws but blown away on state change struct scratch { uint16_t state1; // 16 bit state scratch uint16_t state2; // 16 bit state scratch @@ -61,6 +65,7 @@ OperatingMode gui_SolderingSleepingMode(const ButtonState buttons, guiContext *c OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt); // Main mode for hot pointy tool OperatingMode gui_solderingTempAdjust(const ButtonState buttons, guiContext *cxt); // For adjusting the setpoint temperature of the iron OperatingMode drawHomeScreen(const ButtonState buttons, guiContext *cxt); // IDLE / Home screen +OperatingMode gui_SettingsMenu(const ButtonState buttons, guiContext *cxt); // OperatingMode gui_solderingProfileMode(const ButtonState buttons, guiContext *cxt); // Profile mode for hot likely-not-so-pointy tool OperatingMode performCJCC(const ButtonState buttons, guiContext *cxt); // Used to calibrate the Cold Junction offset diff --git a/source/Core/Threads/OperatingModes/SettingsMenu.cpp b/source/Core/Threads/OperatingModes/SettingsMenu.cpp new file mode 100644 index 00000000..0513bd90 --- /dev/null +++ b/source/Core/Threads/OperatingModes/SettingsMenu.cpp @@ -0,0 +1,8 @@ +#include "OperatingModes.h" +OperatingMode gui_SettingsMenu(const ButtonState buttons, guiContext *cxt) { + // Render out the current settings menu + // State 1 -> Root menu + // State 2 -> Sub entry + + return OperatingMode::SettingsMenu; +} \ No newline at end of file