Initial support for disabling/enabling plugins in config menu

This commit is contained in:
Maschell
2024-08-04 16:42:24 +02:00
parent 98f182501c
commit 7802937943
15 changed files with 153 additions and 80 deletions

View File

@@ -19,4 +19,8 @@ const WUPSConfigAPIBackend::WUPSConfig &ConfigDisplayItem::getConfig() const {
bool ConfigDisplayItem::isActivePlugin() const {
return mIsActivePlugin;
}
void ConfigDisplayItem::toggleIsActivePlugin() {
mIsActivePlugin = !mIsActivePlugin;
}

View File

@@ -22,6 +22,8 @@ public:
[[nodiscard]] bool isActivePlugin() const;
void toggleIsActivePlugin();
private:
std::unique_ptr<WUPSConfigAPIBackend::WUPSConfig> mConfig;
GeneralConfigInformation mInfo;

View File

@@ -1,10 +1,16 @@
#include "ConfigRenderer.h"
#include "globals.h"
#include "plugin/PluginLoadWrapper.h"
#include "utils/DrawUtils.h"
#include "utils/logger.h"
#include "utils/utils.h"
#include <coreinit/title.h>
#include <sysapp/launch.h>
ConfigRenderer::ConfigRenderer(std::vector<ConfigDisplayItem> &&vec) : mConfigs(std::move(vec)) {
std::copy(mConfigs.begin(), mConfigs.end(),
std::back_inserter(mAllConfigs));
std::copy_if(mConfigs.begin(), mConfigs.end(),
std::back_inserter(mActiveConfigs),
[&](const auto &value) {
@@ -20,7 +26,8 @@ ConfigSubState ConfigRenderer::Update(Input &input, const WUPSConfigSimplePadDat
return UpdateStateMain(input);
case STATE_SUB: {
if (mCategoryRenderer) {
if (const auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData); subResult != SUB_STATE_RUNNING) {
auto subResult = mCategoryRenderer->Update(input, simpleInputData, complexInputData);
if (subResult != SUB_STATE_RUNNING) {
mNeedRedraw = true;
mState = STATE_MAIN;
return SUB_STATE_RUNNING;
@@ -55,8 +62,7 @@ void ConfigRenderer::Render() const {
bool ConfigRenderer::NeedsRedraw() const {
if (mNeedRedraw) {
return true;
}
if (mCategoryRenderer) {
} else if (mCategoryRenderer) {
return mCategoryRenderer->NeedsRedraw();
}
return false;
@@ -70,52 +76,60 @@ void ConfigRenderer::ResetNeedsRedraw() {
}
ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
if (mActiveConfigs.empty()) {
auto &configs = GetConfigList();
if (configs.empty()) {
mNeedRedraw = true;
return SUB_STATE_ERROR;
}
const auto prevSelectedItem = mCursorPos;
auto prevSelectedItem = mCursorPos;
const auto totalElementSize = mActiveConfigs.size();
auto totalElementSize = configs.size();
if (input.data.buttons_d & Input::eButtons::BUTTON_DOWN) {
mCursorPos++;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_LEFT) {
// Paging up
mCursorPos -= MAX_BUTTONS_ON_SCREEN - 1;
// Don't jump past the top
if (mCursorPos < 0)
mCursorPos = 0;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_RIGHT) {
// Paging down
mCursorPos += MAX_BUTTONS_ON_SCREEN - 1;
// Don't jump past the bottom
if (mCursorPos >= totalElementSize)
mCursorPos = totalElementSize - 1;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_UP) {
mCursorPos--;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_PLUS) {
if (mSetActivePluginsMode) {
if (mActivePluginsDirty) {
for (const auto &cur : mConfigs) {
gLoadOnNextLaunch.emplace_back(cur.getConfigInformation().pluginData, cur.isActivePlugin());
}
_SYSLaunchTitleWithStdArgsInNoSplash(OSGetTitleID(), nullptr);
}
mNeedRedraw = true;
mCategoryRenderer.reset();
return SUB_STATE_RETURN;
}
} else if (input.data.buttons_d & Input::eButtons::BUTTON_X) {
mSetActivePluginsMode = !mSetActivePluginsMode;
} else if (input.data.buttons_d & Input::eButtons::BUTTON_A) {
if (mCursorPos != mCurrentOpen) {
mCategoryRenderer.reset();
mCategoryRenderer = make_unique_nothrow<CategoryRenderer>(&(mActiveConfigs[mCursorPos].get().getConfigInformation()), &(mActiveConfigs[mCursorPos].get().getConfig()), true);
if (mSetActivePluginsMode) {
mActivePluginsDirty = true;
mNeedRedraw = true;
configs[mCursorPos].get().toggleIsActivePlugin();
return SUB_STATE_RUNNING;
} else {
if (mCursorPos != mCurrentOpen) {
mCategoryRenderer.reset();
mCategoryRenderer = make_unique_nothrow<CategoryRenderer>(&(configs[mCursorPos].get().getConfigInformation()), &(configs[mCursorPos].get().getConfig()), true);
}
mNeedRedraw = true;
mCurrentOpen = mCursorPos;
mState = STATE_SUB;
return SUB_STATE_RUNNING;
}
mNeedRedraw = true;
mCurrentOpen = mCursorPos;
mState = STATE_SUB;
return SUB_STATE_RUNNING;
} else if (input.data.buttons_d & (Input::eButtons::BUTTON_B | Input::eButtons::BUTTON_HOME)) {
mNeedRedraw = true;
mCategoryRenderer.reset();
for (const auto &element : mActiveConfigs) {
for (const auto &element : configs) {
CallOnCloseCallback(element.get().getConfigInformation(), element.get().getConfig());
}
return SUB_STATE_RETURN;
}
if (mCursorPos < 0) {
mCursorPos = totalElementSize - 1;
} else if (mCursorPos > totalElementSize - 1) {
mCursorPos = (int32_t) totalElementSize - 1;
} else if (mCursorPos > (int32_t) (totalElementSize - 1)) {
mCursorPos = 0;
}
@@ -133,9 +147,9 @@ ConfigSubState ConfigRenderer::UpdateStateMain(const Input &input) {
return SUB_STATE_RUNNING;
}
void ConfigRenderer::RenderStateMain() const {
auto totalElementSize = (int32_t) mActiveConfigs.size();
auto &configs = GetConfigList();
auto totalElementSize = (int32_t) configs.size();
// Calculate the range of items to display
int start = std::max(0, mRenderOffset);
int end = std::min(start + MAX_BUTTONS_ON_SCREEN, totalElementSize);
@@ -145,7 +159,7 @@ void ConfigRenderer::RenderStateMain() const {
uint32_t yOffset = 8 + 24 + 8 + 4;
for (int32_t i = start; i < end; i++) {
DrawConfigEntry(yOffset, mActiveConfigs[i].get().getConfigInformation(), i == mCursorPos);
DrawConfigEntry(yOffset, configs[i].get().getConfigInformation(), i == mCursorPos, configs[i].get().isActivePlugin());
yOffset += 42 + 8;
}
@@ -153,7 +167,11 @@ void ConfigRenderer::RenderStateMain() const {
// draw top bar
DrawUtils::setFontSize(24);
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu");
if (mSetActivePluginsMode) {
DrawUtils::print(16, 6 + 24, "Please select the plugin that should be active");
} else {
DrawUtils::print(16, 6 + 24, "Wii U Plugin System Config Menu");
}
DrawUtils::setFontSize(18);
DrawUtils::print(SCREEN_WIDTH - 16, 8 + 24, MODULE_VERSION_FULL, true);
DrawUtils::drawRectFilled(8, 8 + 24 + 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK);
@@ -162,7 +180,11 @@ void ConfigRenderer::RenderStateMain() const {
DrawUtils::drawRectFilled(8, SCREEN_HEIGHT - 24 - 8 - 4, SCREEN_WIDTH - 8 * 2, 3, COLOR_BLACK);
DrawUtils::setFontSize(18);
DrawUtils::print(16, SCREEN_HEIGHT - 10, "\ue07d Navigate ");
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select", true);
if (mSetActivePluginsMode) {
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Select | \uE045 Apply", true);
} else {
DrawUtils::print(SCREEN_WIDTH - 16, SCREEN_HEIGHT - 10, "\ue000 Activate", true);
}
// draw scroll indicator
DrawUtils::setFontSize(24);
@@ -181,7 +203,7 @@ void ConfigRenderer::RenderStateMain() const {
DrawUtils::endDraw();
}
void ConfigRenderer::DrawConfigEntry(const uint32_t yOffset, const GeneralConfigInformation &configInformation, const bool isHighlighted) const {
void ConfigRenderer::DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted, bool isActive) const {
DrawUtils::setFontColor(COLOR_TEXT);
if (isHighlighted) {
@@ -190,11 +212,21 @@ void ConfigRenderer::DrawConfigEntry(const uint32_t yOffset, const GeneralConfig
DrawUtils::drawRect(16, yOffset, SCREEN_WIDTH - 16 * 2, 44, 2, COLOR_BORDER);
}
int textXOffset = 16 * 2;
if (mSetActivePluginsMode) {
DrawUtils::setFontSize(24);
if (isActive) {
DrawUtils::print(textXOffset, yOffset + 8 + 24, "x");
}
textXOffset += 32;
}
DrawUtils::setFontSize(24);
DrawUtils::print(16 * 2, yOffset + 8 + 24, configInformation.name.c_str());
const uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str());
DrawUtils::print(textXOffset, yOffset + 8 + 24, configInformation.name.c_str());
uint32_t sz = DrawUtils::getTextWidth(configInformation.name.c_str());
DrawUtils::setFontSize(12);
DrawUtils::print(16 * 2 + sz + 4, yOffset + 8 + 24, configInformation.author.c_str());
DrawUtils::print(textXOffset + sz + 4, yOffset + 8 + 24, configInformation.author.c_str());
DrawUtils::print(SCREEN_WIDTH - 16 * 2, yOffset + 8 + 24, configInformation.version.c_str(), true);
}
@@ -215,3 +247,10 @@ void ConfigRenderer::CallOnCloseCallback(const GeneralConfigInformation &info, c
item->onCloseCallback();
}
}
const std::vector<std::reference_wrapper<ConfigDisplayItem>> &ConfigRenderer::GetConfigList() const {
if (mSetActivePluginsMode) {
return mAllConfigs;
}
return mActiveConfigs;
}

View File

@@ -8,6 +8,7 @@
#include <cstdint>
#include <memory>
#include <vector>
#include <functional>
#include <wups/config.h>
class ConfigRenderer {
@@ -30,17 +31,20 @@ private:
void RenderStateMain() const;
void DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted) const;
void DrawConfigEntry(uint32_t yOffset, const GeneralConfigInformation &configInformation, bool isHighlighted, bool isActive) const;
void CallOnCloseCallback(const GeneralConfigInformation &info, const std::vector<std::unique_ptr<WUPSConfigAPIBackend::WUPSConfigCategory>> &categories);
void CallOnCloseCallback(const GeneralConfigInformation &info, const WUPSConfigAPIBackend::WUPSConfig &config);
const std::vector<std::reference_wrapper<ConfigDisplayItem>> &GetConfigList() const;
enum State {
STATE_MAIN = 0,
STATE_SUB = 1,
};
std::vector<ConfigDisplayItem> mConfigs;
std::vector<std::reference_wrapper<ConfigDisplayItem>> mAllConfigs;
std::vector<std::reference_wrapper<ConfigDisplayItem>> mActiveConfigs;
std::unique_ptr<CategoryRenderer> mCategoryRenderer = {};
@@ -50,6 +54,7 @@ private:
int32_t mRenderOffset = 0;
int32_t mCurrentOpen = -1;
bool mSetActivePluginsMode = false;
bool mNeedRedraw = true;
bool mSetActivePluginsMode = false;
bool mActivePluginsDirty = false;
};

View File

@@ -125,6 +125,7 @@ void ConfigUtils::displayMenu() {
if (!config) {
config = make_unique_nothrow<WUPSConfigAPIBackend::WUPSConfig>(info.name);
}
configs.emplace_back(info, std::move(config), plugin.isLinkedAndLoaded());
}

View File

@@ -35,7 +35,7 @@ extern "C" PluginBackendApiErrorType WUPSLoadAndLinkByDataHandle(const wups_back
for (const auto &pluginData : gLoadedData) {
if (pluginData->getHandle() == handle) {
gLoadOnNextLaunch.push_back(pluginData);
gLoadOnNextLaunch.emplace_back(pluginData, true);
found = true;
break;
}