diff --git a/source/utils/config/CategoryRenderer.cpp b/source/utils/config/CategoryRenderer.cpp index 2aecd77..795dfe2 100644 --- a/source/utils/config/CategoryRenderer.cpp +++ b/source/utils/config/CategoryRenderer.cpp @@ -54,8 +54,9 @@ ConfigSubState CategoryRenderer::Update(Input &input, const WUPSConfigSimplePadD if (mSubCategoryRenderer) { auto subResult = mSubCategoryRenderer->Update(input, simpleInputData, complexInputData); if (subResult != SUB_STATE_RUNNING) { - mState = STATE_MAIN; - mFirstFrame = true; + mNeedsRedraw = true; + mState = STATE_MAIN; + mFirstFrame = true; return SUB_STATE_RUNNING; } return SUB_STATE_RUNNING; @@ -93,6 +94,7 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS } mCurrentOpen = mCursorPos; mState = STATE_SUB; + mNeedsRedraw = true; } } } @@ -115,6 +117,7 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS mItemRenderer[prevSelectedItem]->SetIsSelected(false); mItemRenderer[mCursorPos]->SetIsSelected(true); posJustChanged = true; + mNeedsRedraw = true; } if (!posJustChanged && !mFirstFrame) { @@ -135,9 +138,43 @@ ConfigSubState CategoryRenderer::UpdateStateMain(Input &input, const WUPSConfigS mIsItemMovementAllowed = mItemRenderer[mCursorPos]->IsMovementAllowed(); + for (uint32_t i = 0; i < mItemRenderer.size(); i++) { + bool isHighlighted = ((int) i == mCursorPos); + mItemRenderer[i]->Update(isHighlighted); + } + return SUB_STATE_RUNNING; } + +void CategoryRenderer::ResetNeedsRedraw() { + mNeedsRedraw = false; + if (mState == STATE_SUB && mSubCategoryRenderer) { + mSubCategoryRenderer->ResetNeedsRedraw(); + } + for (auto &item : mItemRenderer) { + item->ResetNeedsRedraw(); + } +} + + +bool CategoryRenderer::NeedsRedraw() const { + if (mNeedsRedraw) { + return true; + } + if (mState == STATE_SUB && mSubCategoryRenderer) { + if (mSubCategoryRenderer->NeedsRedraw()) { + return true; + } + } + for (const auto &item : mItemRenderer) { + if (item->NeedsRedraw()) { + return true; + } + } + return false; +} + void CategoryRenderer::Render() const { switch (mState) { case STATE_MAIN: @@ -218,4 +255,4 @@ void CategoryRenderer::RenderMainLayout() const { DrawUtils::setFontSize(18); const char *exitHint = "\ue001 Back"; DrawUtils::print(SCREEN_WIDTH / 2 + DrawUtils::getTextWidth(exitHint) / 2, SCREEN_HEIGHT - 10, exitHint, true); -} +} \ No newline at end of file diff --git a/source/utils/config/CategoryRenderer.h b/source/utils/config/CategoryRenderer.h index 55f4257..4048879 100644 --- a/source/utils/config/CategoryRenderer.h +++ b/source/utils/config/CategoryRenderer.h @@ -19,6 +19,10 @@ public: void Render() const; + [[nodiscard]] bool NeedsRedraw() const; + + void ResetNeedsRedraw(); + private: ConfigSubState UpdateStateMain(Input &input, const WUPSConfigSimplePadData &simpleInputData, const WUPSConfigComplexPadData &complexInputData); @@ -43,4 +47,5 @@ private: bool mIsItemMovementAllowed = true; bool mFirstFrame = true; bool mIsRoot = false; + bool mNeedsRedraw = true; }; diff --git a/source/utils/config/ConfigRenderer.cpp b/source/utils/config/ConfigRenderer.cpp index 963abdb..4b63a35 100644 --- a/source/utils/config/ConfigRenderer.cpp +++ b/source/utils/config/ConfigRenderer.cpp @@ -68,6 +68,8 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { if (mConfigs.empty()) { return SUB_STATE_ERROR; } + auto prevSelectedItem = mCursorPos; + auto totalElementSize = mConfigs.size(); if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) { mCursorPos++; @@ -101,9 +103,31 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) { } else if (mCursorPos >= mRenderOffset + MAX_BUTTONS_ON_SCREEN - 1) { mRenderOffset = mCursorPos - MAX_BUTTONS_ON_SCREEN + 1; } + + if (prevSelectedItem != mCursorPos) { + mNeedRedraw = true; + } + return SUB_STATE_RUNNING; } +bool ConfigRenderer::NeedsRedraw() const { + if (mNeedRedraw) { + return true; + } else if (mState == STATE_SUB && mCategoryRenderer) { + return mCategoryRenderer->NeedsRedraw(); + } + return false; +} + +void ConfigRenderer::ResetNeedsRedraw() { + mNeedRedraw = false; + if (mState == STATE_SUB && mCategoryRenderer) { + mCategoryRenderer->ResetNeedsRedraw(); + } +} + + void ConfigRenderer::Render() const { switch (mState) { case STATE_MAIN: @@ -128,7 +152,8 @@ ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadDat if (mCategoryRenderer) { auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData); if (subResult != SUB_STATE_RUNNING) { - mState = STATE_MAIN; + mNeedRedraw = true; + mState = STATE_MAIN; return SUB_STATE_RUNNING; } return SUB_STATE_RUNNING; diff --git a/source/utils/config/ConfigRenderer.h b/source/utils/config/ConfigRenderer.h index 2cba9e9..9309714 100644 --- a/source/utils/config/ConfigRenderer.h +++ b/source/utils/config/ConfigRenderer.h @@ -18,6 +18,10 @@ public: void Render() const; + [[nodiscard]] bool NeedsRedraw() const; + + void ResetNeedsRedraw(); + private: ConfigSubState UpdateStateMain(const Input &input); @@ -40,4 +44,6 @@ private: int32_t mCurrentOpen = -1; void CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector> &categories); void CallOnCloseCallback(const GeneralConfigInformation &info, const WUPSConfigAPIBackend::WUPSConfig &config); + + bool mNeedRedraw = true; }; diff --git a/source/utils/config/ConfigRendererItem.h b/source/utils/config/ConfigRendererItem.h index 6529b37..83e9c5d 100644 --- a/source/utils/config/ConfigRendererItem.h +++ b/source/utils/config/ConfigRendererItem.h @@ -12,11 +12,28 @@ public: assert(mItem); drawGenericBoxAndText(yOffset, mItem->getDisplayName(), isHighlighted); DrawUtils::setFontSize(24); - if (isHighlighted) { - DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, mItem->getCurrentValueSelectedDisplay().c_str(), true); - } else { - DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, mItem->getCurrentValueDisplay().c_str(), true); + DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, mCurItemText.c_str(), true); + } + + std::string GetValueToPrint(bool isHighlighted) { + return isHighlighted ? mItem->getCurrentValueSelectedDisplay() : mItem->getCurrentValueDisplay(); + } + + void Update(bool isHighlighted) override { + const auto newText = GetValueToPrint(isHighlighted); + + if (mCurItemText != newText) { + mNeedsDraw = true; } + mCurItemText = newText; + } + + void ResetNeedsRedraw() override { + mNeedsDraw = false; + } + + [[nodiscard]] bool NeedsRedraw() const override { + return mNeedsDraw; } void SetIsSelected(bool isSelected) override { @@ -40,4 +57,6 @@ public: private: const WUPSConfigAPIBackend::WUPSConfigItem *mItem; + std::string mCurItemText; + bool mNeedsDraw = true; }; \ No newline at end of file diff --git a/source/utils/config/ConfigRendererItemCategory.h b/source/utils/config/ConfigRendererItemCategory.h index 3726cf4..0c40182 100644 --- a/source/utils/config/ConfigRendererItemCategory.h +++ b/source/utils/config/ConfigRendererItemCategory.h @@ -12,6 +12,16 @@ public: drawGenericBoxAndText(yOffset, mCategory->getName(), isHighlighted); } + void Update(bool) override { + } + + [[nodiscard]] bool NeedsRedraw() const override { + return false; + } + + void ResetNeedsRedraw() override { + } + private: const WUPSConfigAPIBackend::WUPSConfigCategory *mCategory; }; \ No newline at end of file diff --git a/source/utils/config/ConfigRendererItemGeneric.h b/source/utils/config/ConfigRendererItemGeneric.h index 64e5d06..d3fcddf 100644 --- a/source/utils/config/ConfigRendererItemGeneric.h +++ b/source/utils/config/ConfigRendererItemGeneric.h @@ -20,6 +20,12 @@ public: virtual void Draw(uint32_t yOffset, bool isHighlighted) const = 0; + virtual void Update(bool) = 0; + + [[nodiscard]] virtual bool NeedsRedraw() const = 0; + + virtual void ResetNeedsRedraw() = 0; + virtual void SetIsSelected(bool) { } diff --git a/source/utils/config/ConfigUtils.cpp b/source/utils/config/ConfigUtils.cpp index 6824eb7..5b5dafe 100644 --- a/source/utils/config/ConfigUtils.cpp +++ b/source/utils/config/ConfigUtils.cpp @@ -174,7 +174,11 @@ void ConfigUtils::displayMenu() { if (subState != SUB_STATE_RUNNING) { break; } - renderer.Render(); + if (renderer.NeedsRedraw()) { + renderer.Render(); + } + renderer.ResetNeedsRedraw(); + auto diffTime = OSTicksToMicroseconds(OSGetTime() - startTime); if (diffTime < 16000) { OSSleepTicks(OSMicrosecondsToTicks(16000 - diffTime));