FullscreenUI: Add load/save input profile
This commit is contained in:
parent
8990ade721
commit
d2d2e3ae6e
|
@ -791,6 +791,7 @@ Global
|
|||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.DebugUWP|x86.ActiveCfg = DebugUWP|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x64.ActiveCfg = Release|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x64.Build.0 = Release|x64
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x86.ActiveCfg = Release|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.Release|x86.Build.0 = Release|Win32
|
||||
{0A172B2E-DC67-49FC-A4C1-975F93C586C4}.ReleaseLTCG|ARM64.ActiveCfg = ReleaseLTCG|ARM64
|
||||
|
|
|
@ -107,6 +107,7 @@ using ImGuiFullscreen::NavButton;
|
|||
using ImGuiFullscreen::NavTitle;
|
||||
using ImGuiFullscreen::OpenChoiceDialog;
|
||||
using ImGuiFullscreen::OpenFileSelector;
|
||||
using ImGuiFullscreen::OpenInputStringDialog;
|
||||
using ImGuiFullscreen::PopPrimaryColor;
|
||||
using ImGuiFullscreen::PushPrimaryColor;
|
||||
using ImGuiFullscreen::QueueResetFocus;
|
||||
|
@ -246,7 +247,6 @@ static void DrawEmulationSettingsPage();
|
|||
static void DrawDisplaySettingsPage();
|
||||
static void DrawAudioSettingsPage();
|
||||
static void DrawMemoryCardSettingsPage();
|
||||
static void DrawCreateMemoryCardWindow();
|
||||
static void DrawControllerSettingsPage();
|
||||
static void DrawHotkeySettingsPage();
|
||||
static void DrawAchievementsSettingsPage();
|
||||
|
@ -268,6 +268,9 @@ static void DoCopyGameSettings();
|
|||
static void DoClearGameSettings();
|
||||
static void CopyGlobalControllerSettingsToGame();
|
||||
static void ResetControllerSettings();
|
||||
static void DoLoadInputProfile();
|
||||
static void DoSaveInputProfile();
|
||||
static void DoSaveInputProfile(const std::string& name);
|
||||
|
||||
static bool DrawToggleSetting(SettingsInterface* bsi, const char* title, const char* summary, const char* section,
|
||||
const char* key, bool default_value, bool enabled = true, bool allow_tristate = true,
|
||||
|
@ -1877,7 +1880,16 @@ ImGuiFullscreen::ChoiceDialogOptions FullscreenUI::GetGameListDirectoryOptions(b
|
|||
|
||||
void FullscreenUI::DoCopyGameSettings()
|
||||
{
|
||||
//
|
||||
if (!s_game_settings_interface)
|
||||
return;
|
||||
|
||||
Settings temp_settings;
|
||||
temp_settings.Load(*GetEditingSettingsInterface(false));
|
||||
temp_settings.Save(*s_game_settings_interface);
|
||||
SetSettingsChanged(s_game_settings_interface.get());
|
||||
|
||||
ShowToast("Game Settings Copied", fmt::format("Game settings initialized with global settings for '{}'.",
|
||||
Path::GetFileTitle(s_game_settings_interface->GetFileName())));
|
||||
}
|
||||
|
||||
void FullscreenUI::DoClearGameSettings()
|
||||
|
@ -1889,191 +1901,12 @@ void FullscreenUI::DoClearGameSettings()
|
|||
if (!s_game_settings_interface->GetFileName().empty())
|
||||
FileSystem::DeleteFile(s_game_settings_interface->GetFileName().c_str());
|
||||
|
||||
s_settings_changed.store(false, std::memory_order_release);
|
||||
Host::RunOnCPUThread([]() { System::ReloadGameSettings(false); });
|
||||
SetSettingsChanged(s_game_settings_interface.get());
|
||||
|
||||
ShowToast("Game Settings Cleared", fmt::format("Game settings have been cleared for {}.",
|
||||
ShowToast("Game Settings Cleared", fmt::format("Game settings have been cleared for '{}'.",
|
||||
Path::GetFileTitle(s_game_settings_interface->GetFileName())));
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
static bool SettingInfoButton(const SettingInfo& si, const char* section)
|
||||
{
|
||||
// this.. isn't pretty :(
|
||||
TinyString title;
|
||||
title.Format("%s##%s/%s", si.visible_name, section, si.key);
|
||||
switch (si.type)
|
||||
{
|
||||
case SettingInfo::Type::Boolean:
|
||||
{
|
||||
bool value = s_host_interface->GetSettingsInterface()->GetBoolValue(
|
||||
section, si.key, StringUtil::FromChars<bool>(si.default_value).value_or(false));
|
||||
if (ToggleButton(title, si.description, &value))
|
||||
{
|
||||
s_host_interface->GetSettingsInterface()->SetBoolValue(section, si.key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case SettingInfo::Type::Integer:
|
||||
{
|
||||
int value = s_host_interface->GetSettingsInterface()->GetIntValue(
|
||||
section, si.key, StringUtil::FromChars<int>(si.default_value).value_or(0));
|
||||
const int min = StringUtil::FromChars<int>(si.min_value).value_or(0);
|
||||
const int max = StringUtil::FromChars<int>(si.max_value).value_or(0);
|
||||
const int step = StringUtil::FromChars<int>(si.step_value).value_or(0);
|
||||
if (RangeButton(title, si.description, &value, min, max, step))
|
||||
{
|
||||
s_host_interface->GetSettingsInterface()->SetIntValue(section, si.key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case SettingInfo::Type::Float:
|
||||
{
|
||||
float value = s_host_interface->GetSettingsInterface()->GetFloatValue(
|
||||
section, si.key, StringUtil::FromChars<float>(si.default_value).value_or(0));
|
||||
const float min = StringUtil::FromChars<float>(si.min_value).value_or(0);
|
||||
const float max = StringUtil::FromChars<float>(si.max_value).value_or(0);
|
||||
const float step = StringUtil::FromChars<float>(si.step_value).value_or(0);
|
||||
if (RangeButton(title, si.description, &value, min, max, step))
|
||||
{
|
||||
s_host_interface->GetSettingsInterface()->SetFloatValue(section, si.key, value);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
case SettingInfo::Type::Path:
|
||||
{
|
||||
std::string value = s_host_interface->GetSettingsInterface()->GetStringValue(section, si.key);
|
||||
if (MenuButtonWithValue(title, si.description, value.c_str()))
|
||||
{
|
||||
std::string section_copy(section);
|
||||
std::string key_copy(si.key);
|
||||
auto callback = [section_copy, key_copy](const std::string& path) {
|
||||
if (!path.empty())
|
||||
{
|
||||
s_host_interface->GetSettingsInterface()->SetStringValue(section_copy.c_str(), key_copy.c_str(),
|
||||
path.c_str());
|
||||
s_host_interface->RunLater(SaveAndApplySettings);
|
||||
}
|
||||
|
||||
ClearImGuiFocus();
|
||||
CloseFileSelector();
|
||||
};
|
||||
OpenFileSelector(si.visible_name, false, std::move(callback), ImGuiFullscreen::FileSelectorFilters(),
|
||||
std::string(Path::GetDirectory(std::move(value))));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef WITH_CHEEVOS
|
||||
|
||||
#if 0
|
||||
static void DrawAchievementsLoginWindow()
|
||||
{
|
||||
ImGui::SetNextWindowSize(LayoutScale(700.0f, 0.0f));
|
||||
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(20.0f, 20.0f));
|
||||
ImGui::PushFont(g_large_font);
|
||||
|
||||
bool is_open = true;
|
||||
if (ImGui::BeginPopupModal("Achievements Login", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
|
||||
{
|
||||
|
||||
ImGui::TextWrapped("Please enter user name and password for retroachievements.org.");
|
||||
ImGui::NewLine();
|
||||
ImGui::TextWrapped(
|
||||
"Your password will not be saved in DuckStation, an access token will be generated and used instead.");
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
static char username[256] = {};
|
||||
static char password[256] = {};
|
||||
|
||||
ImGui::Text("User Name: ");
|
||||
ImGui::SameLine(LayoutScale(200.0f));
|
||||
ImGui::InputText("##username", username, sizeof(username));
|
||||
|
||||
ImGui::Text("Password: ");
|
||||
ImGui::SameLine(LayoutScale(200.0f));
|
||||
ImGui::InputText("##password", password, sizeof(password), ImGuiInputTextFlags_Password);
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
const bool login_enabled = (std::strlen(username) > 0 && std::strlen(password) > 0);
|
||||
|
||||
if (ActiveButton(ICON_FA_KEY " Login", false, login_enabled))
|
||||
{
|
||||
Cheevos::LoginAsync(username, password);
|
||||
std::memset(username, 0, sizeof(username));
|
||||
std::memset(password, 0, sizeof(password));
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
if (ActiveButton(ICON_FA_TIMES " Cancel", false))
|
||||
ImGui::CloseCurrentPopup();
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
static bool ConfirmChallengeModeEnable()
|
||||
{
|
||||
if (!System::IsValid())
|
||||
return true;
|
||||
|
||||
const bool cheevos_enabled = s_host_interface->GetBoolSettingValue("Cheevos", "Enabled", false);
|
||||
const bool cheevos_hardcore = s_host_interface->GetBoolSettingValue("Cheevos", "ChallengeMode", false);
|
||||
if (!cheevos_enabled || !cheevos_hardcore)
|
||||
return true;
|
||||
|
||||
SmallString message;
|
||||
message.AppendString("Enabling hardcore mode will shut down your current game.\n\n");
|
||||
|
||||
if (s_host_interface->ShouldSaveResumeState())
|
||||
{
|
||||
message.AppendString(
|
||||
"The current state will be saved, but you will be unable to load it until you disable hardcore mode.\n\n");
|
||||
}
|
||||
|
||||
message.AppendString("Do you want to continue?");
|
||||
|
||||
if (!s_host_interface->ConfirmMessage(message))
|
||||
return false;
|
||||
|
||||
SaveAndApplySettings();
|
||||
s_host_interface->PowerOffSystem(s_host_interface->ShouldSaveResumeState());
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
void FullscreenUI::DrawSettingsWindow()
|
||||
{
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
|
@ -2274,7 +2107,6 @@ void FullscreenUI::DrawSummarySettingsPage()
|
|||
|
||||
MenuHeading("Options");
|
||||
|
||||
// TODO: Implement this.
|
||||
if (MenuButton(ICON_FA_COPY " Copy Settings", "Copies the current global settings to this game.", false))
|
||||
DoCopyGameSettings();
|
||||
if (MenuButton(ICON_FA_TRASH " Clear Settings", "Clears all settings set for this game."))
|
||||
|
@ -2687,6 +2519,90 @@ void FullscreenUI::CopyGlobalControllerSettingsToGame()
|
|||
ShowToast(std::string(), "Per-game controller configuration initialized with global settings.");
|
||||
}
|
||||
|
||||
void FullscreenUI::DoLoadInputProfile()
|
||||
{
|
||||
std::vector<std::string> profiles(InputManager::GetInputProfileNames());
|
||||
if (profiles.empty())
|
||||
{
|
||||
ShowToast(std::string(), "No input profiles available.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiFullscreen::ChoiceDialogOptions coptions;
|
||||
coptions.reserve(profiles.size());
|
||||
for (std::string& name : profiles)
|
||||
coptions.emplace_back(std::move(name), false);
|
||||
OpenChoiceDialog(ICON_FA_FOLDER_OPEN " Load Profile", false, std::move(coptions),
|
||||
[](s32 index, const std::string& title, bool checked) {
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
INISettingsInterface ssi(System::GetInputProfilePath(title));
|
||||
if (!ssi.Load())
|
||||
{
|
||||
ShowToast(std::string(), fmt::format("Failed to load '{}'.", title));
|
||||
CloseChoiceDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* dsi = GetEditingSettingsInterface();
|
||||
InputManager::CopyConfiguration(dsi, ssi, true, true, IsEditingGameSettings(dsi));
|
||||
SetSettingsChanged(dsi);
|
||||
ShowToast(std::string(), fmt::format("Input profile '{}' loaded.", title));
|
||||
CloseChoiceDialog();
|
||||
});
|
||||
}
|
||||
|
||||
void FullscreenUI::DoSaveInputProfile(const std::string& name)
|
||||
{
|
||||
INISettingsInterface dsi(System::GetInputProfilePath(name));
|
||||
|
||||
auto lock = Host::GetSettingsLock();
|
||||
SettingsInterface* ssi = GetEditingSettingsInterface();
|
||||
InputManager::CopyConfiguration(&dsi, *ssi, true, true, IsEditingGameSettings(ssi));
|
||||
if (dsi.Save())
|
||||
ShowToast(std::string(), fmt::format("Input profile '{}' saved.", name));
|
||||
else
|
||||
ShowToast(std::string(), fmt::format("Failed to save input profile '{}'.", name));
|
||||
}
|
||||
|
||||
void FullscreenUI::DoSaveInputProfile()
|
||||
{
|
||||
std::vector<std::string> profiles(InputManager::GetInputProfileNames());
|
||||
if (profiles.empty())
|
||||
{
|
||||
ShowToast(std::string(), "No input profiles available.");
|
||||
return;
|
||||
}
|
||||
|
||||
ImGuiFullscreen::ChoiceDialogOptions coptions;
|
||||
coptions.reserve(profiles.size() + 1);
|
||||
coptions.emplace_back("Create New...", false);
|
||||
for (std::string& name : profiles)
|
||||
coptions.emplace_back(std::move(name), false);
|
||||
OpenChoiceDialog(
|
||||
ICON_FA_SAVE " Save Profile", false, std::move(coptions), [](s32 index, const std::string& title, bool checked) {
|
||||
if (index < 0)
|
||||
return;
|
||||
|
||||
if (index > 0)
|
||||
{
|
||||
DoSaveInputProfile(title);
|
||||
CloseChoiceDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
CloseChoiceDialog();
|
||||
|
||||
OpenInputStringDialog(ICON_FA_SAVE " Save Profile", "Enter the name of the input profile you wish to create.",
|
||||
std::string(), ICON_FA_FOLDER_PLUS " Create", [](std::string title) {
|
||||
if (!title.empty())
|
||||
DoSaveInputProfile(title);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
void FullscreenUI::ResetControllerSettings()
|
||||
{
|
||||
SettingsInterface* dsi = GetEditingSettingsInterface();
|
||||
|
@ -2736,15 +2652,19 @@ void FullscreenUI::DrawControllerSettingsPage()
|
|||
{
|
||||
if (MenuButton(ICON_FA_FOLDER_MINUS " Reset Settings",
|
||||
"Resets all configuration to defaults (including bindings)."))
|
||||
{
|
||||
ResetControllerSettings();
|
||||
}
|
||||
}
|
||||
|
||||
if (MenuButton(ICON_FA_FOLDER_OPEN " Load Profile",
|
||||
"Replaces these settings with a previously saved input profile."))
|
||||
{
|
||||
DoLoadInputProfile();
|
||||
}
|
||||
if (MenuButton(ICON_FA_SAVE " Save Profile", "Stores the current settings to an input profile."))
|
||||
{
|
||||
DoSaveInputProfile();
|
||||
}
|
||||
|
||||
MenuHeading("Input Sources");
|
||||
|
@ -3031,8 +2951,34 @@ void FullscreenUI::DrawMemoryCardSettingsPage()
|
|||
|
||||
MenuHeading("Settings and Operations");
|
||||
if (MenuButton(ICON_FA_PLUS " Create Memory Card", "Creates a new memory card file or folder."))
|
||||
ImGui::OpenPopup("Create Memory Card");
|
||||
DrawCreateMemoryCardWindow();
|
||||
{
|
||||
OpenInputStringDialog(
|
||||
ICON_FA_PLUS " Create Memory Card", "Enter the name of the memory card you wish to create.",
|
||||
"Card Name: ", ICON_FA_FOLDER_PLUS " Create", [](std::string memcard_name) {
|
||||
if (memcard_name.empty())
|
||||
return;
|
||||
|
||||
const std::string filename(Path::Combine(EmuFolders::MemoryCards, fmt::format("{}.mcd", memcard_name)));
|
||||
if (!FileSystem::FileExists(filename.c_str()))
|
||||
{
|
||||
MemoryCardImage::DataArray data;
|
||||
MemoryCardImage::Format(&data);
|
||||
if (!FileSystem::WriteBinaryFile(filename.c_str(), data.data(), data.size()))
|
||||
{
|
||||
FileSystem::DeleteFile(filename.c_str());
|
||||
ShowToast(std::string(), fmt::format("Failed to create memory card '{}'.", memcard_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowToast(std::string(), fmt::format("Memory card '{}' created.", memcard_name));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowToast(std::string(), fmt::format("A memory card with the name '{}' already exists.", memcard_name));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
DrawFolderSetting(bsi, ICON_FA_FOLDER_OPEN " Memory Card Directory", "MemoryCards", "Directory",
|
||||
EmuFolders::MemoryCards);
|
||||
|
@ -3123,73 +3069,6 @@ void FullscreenUI::DrawMemoryCardSettingsPage()
|
|||
EndMenuButtons();
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawCreateMemoryCardWindow()
|
||||
{
|
||||
ImGui::SetNextWindowSize(LayoutScale(700.0f, 0.0f));
|
||||
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(20.0f, 20.0f));
|
||||
ImGui::PushFont(g_large_font);
|
||||
|
||||
bool is_open = true;
|
||||
if (ImGui::BeginPopupModal("Create Memory Card", &is_open, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize))
|
||||
{
|
||||
ImGui::TextWrapped("Enter the name of the memory card you wish to create.");
|
||||
ImGui::NewLine();
|
||||
|
||||
static char memcard_name[256] = {};
|
||||
ImGui::Text("Card Name: ");
|
||||
ImGui::InputText("##name", memcard_name, sizeof(memcard_name));
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
const bool create_enabled = (std::strlen(memcard_name) > 0);
|
||||
|
||||
if (ActiveButton(ICON_FA_FOLDER_OPEN " Create", false, create_enabled) && std::strlen(memcard_name) > 0)
|
||||
{
|
||||
const std::string filename(Path::Combine(EmuFolders::MemoryCards, fmt::format("{}.mcd", memcard_name)));
|
||||
if (!FileSystem::FileExists(filename.c_str()))
|
||||
{
|
||||
MemoryCardImage::DataArray data;
|
||||
MemoryCardImage::Format(&data);
|
||||
if (!FileSystem::WriteBinaryFile(filename.c_str(), data.data(), data.size()))
|
||||
{
|
||||
FileSystem::DeleteFile(filename.c_str());
|
||||
ShowToast(std::string(), fmt::format("Failed to create memory card '{}'.", memcard_name));
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowToast(std::string(), fmt::format("Memory card '{}' created.", memcard_name));
|
||||
|
||||
std::memset(memcard_name, 0, sizeof(memcard_name));
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowToast(std::string(), fmt::format("A memory card with the name '{}' already exists.", memcard_name));
|
||||
}
|
||||
}
|
||||
|
||||
if (ActiveButton(ICON_FA_TIMES " Cancel", false))
|
||||
{
|
||||
std::memset(memcard_name, 0, sizeof(memcard_name));
|
||||
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
void FullscreenUI::DrawDisplaySettingsPage()
|
||||
{
|
||||
static constexpr auto resolution_scales =
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "core/host_display.h"
|
||||
#include "fmt/core.h"
|
||||
#include "imgui_internal.h"
|
||||
#include "imgui_stdlib.h"
|
||||
#include <cmath>
|
||||
#include <condition_variable>
|
||||
#include <deque>
|
||||
|
@ -31,6 +32,7 @@ static void TextureLoaderThread();
|
|||
|
||||
static void DrawFileSelector();
|
||||
static void DrawChoiceDialog();
|
||||
static void DrawInputDialog();
|
||||
static void DrawBackgroundProgressDialogs(ImVec2& position, float spacing);
|
||||
static void DrawNotifications(ImVec2& position, float spacing);
|
||||
static void DrawToast();
|
||||
|
@ -88,6 +90,14 @@ static ImGuiID s_enum_choice_button_id = 0;
|
|||
static s32 s_enum_choice_button_value = 0;
|
||||
static bool s_enum_choice_button_set = false;
|
||||
|
||||
static bool s_input_dialog_open = false;
|
||||
static std::string s_input_dialog_title;
|
||||
static std::string s_input_dialog_message;
|
||||
static std::string s_input_dialog_caption;
|
||||
static std::string s_input_dialog_text;
|
||||
static std::string s_input_dialog_ok_text;
|
||||
static InputStringDialogCallback s_input_dialog_callback;
|
||||
|
||||
struct FileSelectorItem
|
||||
{
|
||||
FileSelectorItem() = default;
|
||||
|
@ -190,6 +200,7 @@ void ImGuiFullscreen::Shutdown()
|
|||
|
||||
s_notifications.clear();
|
||||
s_background_progress_dialogs.clear();
|
||||
CloseInputDialog();
|
||||
s_choice_dialog_open = false;
|
||||
s_choice_dialog_checkable = false;
|
||||
s_choice_dialog_title = {};
|
||||
|
@ -436,6 +447,7 @@ void ImGuiFullscreen::EndLayout()
|
|||
{
|
||||
DrawFileSelector();
|
||||
DrawChoiceDialog();
|
||||
DrawInputDialog();
|
||||
|
||||
const float notification_margin = LayoutScale(10.0f);
|
||||
const float spacing = LayoutScale(10.0f);
|
||||
|
@ -1834,6 +1846,95 @@ void ImGuiFullscreen::DrawChoiceDialog()
|
|||
}
|
||||
}
|
||||
|
||||
bool ImGuiFullscreen::IsInputDialogOpen()
|
||||
{
|
||||
return s_input_dialog_open;
|
||||
}
|
||||
|
||||
void ImGuiFullscreen::OpenInputStringDialog(std::string title, std::string message, std::string caption,
|
||||
std::string ok_button_text, InputStringDialogCallback callback)
|
||||
{
|
||||
s_input_dialog_open = true;
|
||||
s_input_dialog_title = std::move(title);
|
||||
s_input_dialog_message = std::move(message);
|
||||
s_input_dialog_caption = std::move(caption);
|
||||
s_input_dialog_ok_text = std::move(ok_button_text);
|
||||
s_input_dialog_callback = std::move(callback);
|
||||
}
|
||||
|
||||
void ImGuiFullscreen::DrawInputDialog()
|
||||
{
|
||||
if (!s_input_dialog_open)
|
||||
return;
|
||||
|
||||
ImGui::SetNextWindowSize(LayoutScale(700.0f, 0.0f));
|
||||
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
|
||||
ImGui::OpenPopup(s_input_dialog_title.c_str());
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, LayoutScale(10.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(20.0f, 20.0f));
|
||||
ImGui::PushFont(g_large_font);
|
||||
|
||||
bool is_open = true;
|
||||
if (ImGui::BeginPopupModal(s_input_dialog_title.c_str(), &is_open,
|
||||
ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize |
|
||||
ImGuiWindowFlags_NoMove))
|
||||
{
|
||||
ImGui::TextWrapped("%s", s_input_dialog_message.c_str());
|
||||
ImGui::NewLine();
|
||||
|
||||
if (!s_input_dialog_caption.empty())
|
||||
ImGui::TextUnformatted(s_input_dialog_caption.c_str());
|
||||
ImGui::InputText("##input", &s_input_dialog_text);
|
||||
|
||||
ImGui::NewLine();
|
||||
|
||||
BeginMenuButtons();
|
||||
|
||||
const bool ok_enabled = !s_input_dialog_text.empty();
|
||||
|
||||
if (ActiveButton(s_input_dialog_ok_text.c_str(), false, ok_enabled) && ok_enabled)
|
||||
{
|
||||
// have to move out in case they open another dialog in the callback
|
||||
InputStringDialogCallback cb(std::move(s_input_dialog_callback));
|
||||
std::string text(std::move(s_input_dialog_text));
|
||||
CloseInputDialog();
|
||||
ImGui::CloseCurrentPopup();
|
||||
cb(std::move(text));
|
||||
}
|
||||
|
||||
if (ActiveButton(ICON_FA_TIMES " Cancel", false))
|
||||
{
|
||||
CloseInputDialog();
|
||||
|
||||
ImGui::CloseCurrentPopup();
|
||||
}
|
||||
|
||||
EndMenuButtons();
|
||||
|
||||
ImGui::EndPopup();
|
||||
}
|
||||
if (!is_open)
|
||||
CloseInputDialog();
|
||||
|
||||
ImGui::PopFont();
|
||||
ImGui::PopStyleVar(2);
|
||||
}
|
||||
|
||||
void ImGuiFullscreen::CloseInputDialog()
|
||||
{
|
||||
if (!s_input_dialog_open)
|
||||
return;
|
||||
|
||||
s_input_dialog_open = false;
|
||||
s_input_dialog_title = {};
|
||||
s_input_dialog_message = {};
|
||||
s_input_dialog_caption = {};
|
||||
s_input_dialog_ok_text = {};
|
||||
s_input_dialog_text = {};
|
||||
s_input_dialog_callback = {};
|
||||
}
|
||||
|
||||
static float s_notification_vertical_position = 0.3f;
|
||||
static float s_notification_vertical_direction = -1.0f;
|
||||
|
||||
|
|
|
@ -234,6 +234,11 @@ bool IsChoiceDialogOpen();
|
|||
void OpenChoiceDialog(const char* title, bool checkable, ChoiceDialogOptions options, ChoiceDialogCallback callback);
|
||||
void CloseChoiceDialog();
|
||||
|
||||
using InputStringDialogCallback = std::function<void(std::string text)>;
|
||||
bool IsInputDialogOpen();
|
||||
void OpenInputStringDialog(std::string title, std::string message, std::string caption, std::string ok_button_text, InputStringDialogCallback callback);
|
||||
void CloseInputDialog();
|
||||
|
||||
float GetNotificationVerticalPosition();
|
||||
float GetNotificationVerticalDirection();
|
||||
void SetNotificationVerticalPosition(float position, float direction);
|
||||
|
|
Loading…
Reference in New Issue