feat: Allow plugins to add their own welcome screen quick settings, improve UI

This commit is contained in:
WerWolv
2025-08-06 22:51:47 +02:00
parent cf87294a8c
commit f358069cc1
3 changed files with 90 additions and 4 deletions

View File

@@ -796,6 +796,7 @@ EXPORT_MODULE namespace hex {
using EnabledCallback = std::function<bool()>;
using SelectedCallback = std::function<bool()>;
using ClickCallback = std::function<void()>;
using ToggleCallback = std::function<void(bool)>;
struct MainMenuItem {
UnlocalizedString unlocalizedName;
@@ -824,6 +825,13 @@ EXPORT_MODULE namespace hex {
ClickCallback callback;
};
struct WelcomeScreenQuickSettingsToggle {
std::string onIcon, offIcon;
UnlocalizedString unlocalizedTooltip;
ToggleCallback callback;
mutable bool state;
};
constexpr static auto SeparatorValue = "$SEPARATOR$";
constexpr static auto SubMenuValue = "$SUBMENU$";
@@ -838,6 +846,7 @@ EXPORT_MODULE namespace hex {
const std::vector<DrawCallback>& getToolbarItems();
const std::vector<SidebarItem>& getSidebarItems();
const std::vector<TitleBarButton>& getTitlebarButtons();
const std::vector<WelcomeScreenQuickSettingsToggle>& getWelcomeScreenQuickSettingsToggles();
}
@@ -1007,6 +1016,36 @@ EXPORT_MODULE namespace hex {
const impl::ClickCallback &function
);
/**
* @brief Adds a new welcome screen quick settings toggle
* @param icon The icon to use for the button
* @param unlocalizedTooltip The unlocalized tooltip to use for the button
* @param defaultState The default state of the toggle
* @param function The function to call when the button is clicked
*/
void addWelcomeScreenQuickSettingsToggle(
const std::string &icon,
const UnlocalizedString &unlocalizedTooltip,
bool defaultState,
const impl::ToggleCallback &function
);
/**
* @brief Adds a new welcome screen quick settings toggle
* @param onIcon The icon to use for the button when it's on
* @param offIcon The icon to use for the button when it's off
* @param unlocalizedTooltip The unlocalized tooltip to use for the button
* @param defaultState The default state of the toggle
* @param function The function to call when the button is clicked
*/
void addWelcomeScreenQuickSettingsToggle(
const std::string &onIcon,
const std::string &offIcon,
const UnlocalizedString &unlocalizedTooltip,
bool defaultState,
const impl::ToggleCallback &function
);
}
/* Provider Registry. Allows adding new data providers to be created from the UI */

View File

@@ -948,6 +948,11 @@ namespace hex {
return *s_titlebarButtons;
}
static AutoReset<std::vector<WelcomeScreenQuickSettingsToggle>> s_welcomeScreenQuickSettingsToggles;
const std::vector<WelcomeScreenQuickSettingsToggle>& getWelcomeScreenQuickSettingsToggles() {
return *s_welcomeScreenQuickSettingsToggles;
}
}
void registerMainMenuItem(const UnlocalizedString &unlocalizedName, u32 priority) {
@@ -1070,6 +1075,15 @@ namespace hex {
impl::s_titlebarButtons->push_back({ icon, unlocalizedTooltip, function });
}
void addWelcomeScreenQuickSettingsToggle(const std::string &icon, const UnlocalizedString &unlocalizedTooltip, bool defaultState, const impl::ToggleCallback &function) {
impl::s_welcomeScreenQuickSettingsToggles->push_back({ icon, icon, unlocalizedTooltip, function, defaultState });
}
void addWelcomeScreenQuickSettingsToggle(const std::string &onIcon, const std::string &offIcon, const UnlocalizedString &unlocalizedTooltip, bool defaultState, const impl::ToggleCallback &function) {
impl::s_welcomeScreenQuickSettingsToggles->push_back({ onIcon, offIcon, unlocalizedTooltip, function, defaultState });
}
}
namespace ContentRegistry::Provider {

View File

@@ -519,11 +519,19 @@ namespace hex::plugin::builtin {
ImGui::SetCursorScreenPos(ImGui::GetWindowPos() + ImGui::GetWindowSize() - windowSize - ImGui::GetStyle().WindowPadding);
ImGui::PushStyleColor(ImGuiCol_ChildBg, ImGui::GetStyleColorVec4(ImGuiCol_WindowBg));
if (ImGuiExt::BeginSubWindow("hex.builtin.welcome.header.quick_settings"_lang, nullptr, windowSize, ImGuiChildFlags_AutoResizeY)) {
if (ImGuiExt::DimmedIconToggle(ICON_VS_COMPASS_ACTIVE, ICON_VS_COMPASS, &s_simplifiedWelcomeScreen)) {
ContentRegistry::Settings::write<bool>("hex.builtin.setting.interface", "hex.builtin.setting.interface.simplified_welcome_screen", s_simplifiedWelcomeScreen);
WorkspaceManager::switchWorkspace(s_simplifiedWelcomeScreen ? "Minimal" : "Default");
u32 id = 0;
for (auto &[onIcon, offIcon, unlocalizedTooltip, toggleCallback, state] : ContentRegistry::Interface::impl::getWelcomeScreenQuickSettingsToggles()) {
ImGui::PushID(id + 1);
if (ImGuiExt::DimmedIconToggle(onIcon.c_str(), offIcon.c_str(), &state)) {
toggleCallback(state);
ContentRegistry::Settings::write<bool>("hex.builtin.settings.quick_settings", unlocalizedTooltip, state);
}
if (id % 5 > 0)
ImGui::SameLine();
ImGui::SetItemTooltip("%s", Lang(unlocalizedTooltip).get());
ImGui::PopID();
id += 1;
}
ImGui::SetItemTooltip("%s", "hex.builtin.welcome.quick_settings.simplified"_lang.get());
}
ImGuiExt::EndSubWindow();
@@ -634,6 +642,31 @@ namespace hex::plugin::builtin {
ImHexApi::System::setTargetFPS(static_cast<float>(value.get<int>(14)));
});
ContentRegistry::Interface::addWelcomeScreenQuickSettingsToggle(ICON_VS_COMPASS_ACTIVE, ICON_VS_COMPASS, "hex.builtin.welcome.quick_settings.simplified", false, [](bool state) {
s_simplifiedWelcomeScreen = state;
WorkspaceManager::switchWorkspace(s_simplifiedWelcomeScreen ? "Minimal" : "Default");
});
EventImHexStartupFinished::subscribe([]() {
for (const auto &quickSetting : ContentRegistry::Interface::impl::getWelcomeScreenQuickSettingsToggles()) {
auto &setting = quickSetting.unlocalizedTooltip;
ContentRegistry::Settings::onChange("hex.builtin.settings.quick_settings", setting, [setting](const ContentRegistry::Settings::SettingsValue &value) {
for (auto &[onIcon, offIcon, unlocalizedTooltip, toggleCallback, state] : ContentRegistry::Interface::impl::getWelcomeScreenQuickSettingsToggles()) {
if (unlocalizedTooltip == setting) {
state = value.get<bool>(state);
toggleCallback(state);
break;
}
}
});
bool state = ContentRegistry::Settings::read<bool>("hex.builtin.settings.quick_settings", quickSetting.unlocalizedTooltip, quickSetting.state);
quickSetting.state = state;
quickSetting.callback(state);
}
});
static auto updateTextures = [](float scale) {
auto changeTexture = [&](const std::string &path) {
return ImGuiExt::Texture::fromImage(romfs::get(path).span(), ImGuiExt::Texture::Filter::Nearest);