Merge pull request #1657 from CookiePLMonster/savestate-ui-legend

Save State UI: Add legend showing hotkeys
This commit is contained in:
Connor McLaughlin 2021-02-24 01:21:24 +10:00 committed by GitHub
commit 75776f9b33
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 110 additions and 33 deletions

View File

@ -1310,6 +1310,8 @@ void CommonHostInterface::UpdateHotkeyInputMap(SettingsInterface& si)
AddButtonToInputMap(binding, device, button, hi.handler); AddButtonToInputMap(binding, device, button, hi.handler);
} }
} }
m_save_state_selector_ui->RefreshHotkeyLegend();
} }
bool CommonHostInterface::AddButtonToInputMap(const std::string& binding, const std::string_view& device, bool CommonHostInterface::AddButtonToInputMap(const std::string& binding, const std::string_view& device,

View File

@ -1,5 +1,6 @@
#include "save_state_selector_ui.h" #include "save_state_selector_ui.h"
#include "common/log.h" #include "common/log.h"
#include "common/string_util.h"
#include "common/timestamp.h" #include "common/timestamp.h"
#include "core/host_display.h" #include "core/host_display.h"
#include "core/system.h" #include "core/system.h"
@ -23,6 +24,7 @@ void SaveStateSelectorUI::Open(float open_time /* = DEFAULT_OPEN_TIME */)
m_open = true; m_open = true;
RefreshList(); RefreshList();
RefreshHotkeyLegend();
} }
void SaveStateSelectorUI::Close() void SaveStateSelectorUI::Close()
@ -78,6 +80,32 @@ void SaveStateSelectorUI::RefreshList()
m_current_selection = 0; m_current_selection = 0;
} }
void SaveStateSelectorUI::RefreshHotkeyLegend()
{
if (!m_open)
return;
auto format_legend_entry = [](std::string_view setting, std::string_view caption) {
auto slash_pos = setting.find_first_of('/');
if (slash_pos != setting.npos)
{
setting = setting.substr(slash_pos + 1);
}
return StringUtil::StdStringFromFormat("%.*s - %.*s", static_cast<int>(setting.size()), setting.data(),
static_cast<int>(caption.size()), caption.data());
};
m_load_legend = format_legend_entry(m_host_interface->GetStringSettingValue("Hotkeys", "LoadSelectedSaveState"),
m_host_interface->TranslateStdString("SaveStateSelectorUI", "Load"));
m_save_legend = format_legend_entry(m_host_interface->GetStringSettingValue("Hotkeys", "SaveSelectedSaveState"),
m_host_interface->TranslateStdString("SaveStateSelectorUI", "Save"));
m_prev_legend = format_legend_entry(m_host_interface->GetStringSettingValue("Hotkeys", "SelectPreviousSaveStateSlot"),
m_host_interface->TranslateStdString("SaveStateSelectorUI", "Select Previous"));
m_next_legend = format_legend_entry(m_host_interface->GetStringSettingValue("Hotkeys", "SelectNextSaveStateSlot"),
m_host_interface->TranslateStdString("SaveStateSelectorUI", "Select Next"));
}
const char* SaveStateSelectorUI::GetSelectedStatePath() const const char* SaveStateSelectorUI::GetSelectedStatePath() const
{ {
if (m_slots.empty() || m_slots[m_current_selection].path.empty()) if (m_slots.empty() || m_slots[m_current_selection].path.empty())
@ -158,7 +186,7 @@ std::pair<s32, bool> SaveStateSelectorUI::GetSlotTypeFromSelection(u32 selection
void SaveStateSelectorUI::InitializePlaceholderListEntry(ListEntry* li, s32 slot, bool global) void SaveStateSelectorUI::InitializePlaceholderListEntry(ListEntry* li, s32 slot, bool global)
{ {
li->title = "No Save State"; li->title = m_host_interface->TranslateStdString("SaveStateSelectorUI", "No Save State");
std::string().swap(li->game_code); std::string().swap(li->game_code);
std::string().swap(li->path); std::string().swap(li->path);
std::string().swap(li->formatted_timestamp); std::string().swap(li->formatted_timestamp);
@ -187,9 +215,16 @@ void SaveStateSelectorUI::Draw()
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, rounding); ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, rounding);
if (ImGui::Begin("##save_state_selector", nullptr, if (ImGui::Begin("##save_state_selector", nullptr,
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar)) ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoScrollbar))
{ {
// Leave 2 lines for the legend
const float legend_margin = ImGui::GetFontSize() * 2.0f + ImGui::GetStyle().ItemSpacing.y * 3.0f;
const float padding = 10.0f * framebuffer_scale; const float padding = 10.0f * framebuffer_scale;
ImGui::BeginChild("##item_list", ImVec2(0, -legend_margin), false,
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar);
{
const ImVec2 image_size = ImVec2(128.0f * framebuffer_scale, (128.0f / (4.0f / 3.0f)) * framebuffer_scale); const ImVec2 image_size = ImVec2(128.0f * framebuffer_scale, (128.0f / (4.0f / 3.0f)) * framebuffer_scale);
const float item_height = image_size.y + padding * 2.0f; const float item_height = image_size.y + padding * 2.0f;
const float text_indent = image_size.x + padding + padding; const float text_indent = image_size.x + padding + padding;
@ -220,8 +255,19 @@ void SaveStateSelectorUI::Draw()
ImGui::Indent(text_indent); ImGui::Indent(text_indent);
ImGui::Text("%s Slot %d", entry.global ? "Global" : (entry.game_code.empty() ? "Game" : entry.game_code.c_str()), if (entry.global)
{
ImGui::Text(m_host_interface->TranslateString("SaveStateSelectorUI", "Global Slot %d"), entry.slot);
}
else if (entry.game_code.empty())
{
ImGui::Text(m_host_interface->TranslateString("SaveStateSelectorUI", "Gane Slot %d"), entry.slot);
}
else
{
ImGui::Text(m_host_interface->TranslateString("SaveStateSelectorUI", "%s Slot %d"), entry.game_code.c_str(),
entry.slot); entry.slot);
}
ImGui::TextUnformatted(entry.title.c_str()); ImGui::TextUnformatted(entry.title.c_str());
ImGui::TextUnformatted(entry.formatted_timestamp.c_str()); ImGui::TextUnformatted(entry.formatted_timestamp.c_str());
ImGui::TextUnformatted(entry.path.c_str()); ImGui::TextUnformatted(entry.path.c_str());
@ -229,10 +275,32 @@ void SaveStateSelectorUI::Draw()
ImGui::Unindent(text_indent); ImGui::Unindent(text_indent);
} }
} }
ImGui::EndChild();
ImGui::BeginChild("##legend", ImVec2(0, 0), false,
ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoTitleBar |
ImGuiWindowFlags_NoScrollbar);
{
ImGui::SetCursorPosX(padding);
ImGui::BeginTable("table", 2);
ImGui::TableNextColumn();
ImGui::TextUnformatted(m_load_legend.c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(m_prev_legend.c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(m_save_legend.c_str());
ImGui::TableNextColumn();
ImGui::TextUnformatted(m_next_legend.c_str());
ImGui::EndTable();
}
ImGui::EndChild();
}
ImGui::End();
ImGui::PopStyleVar(2); ImGui::PopStyleVar(2);
ImGui::PopStyleColor(); ImGui::PopStyleColor();
ImGui::End();
// auto-close // auto-close
if (m_open_timer.GetTimeSeconds() >= m_open_time) if (m_open_timer.GetTimeSeconds() >= m_open_time)

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include "common_host_interface.h"
#include "common/timer.h" #include "common/timer.h"
#include "common_host_interface.h"
#include <memory> #include <memory>
class HostDisplayTexture; class HostDisplayTexture;
@ -24,6 +24,8 @@ public:
void ClearList(); void ClearList();
void RefreshList(); void RefreshList();
void RefreshHotkeyLegend();
const char* GetSelectedStatePath() const; const char* GetSelectedStatePath() const;
s32 GetSelectedStateSlot() const; s32 GetSelectedStateSlot() const;
@ -51,6 +53,11 @@ private:
void InitializeListEntry(ListEntry* li, CommonHostInterface::ExtendedSaveStateInfo* ssi); void InitializeListEntry(ListEntry* li, CommonHostInterface::ExtendedSaveStateInfo* ssi);
std::pair<s32, bool> GetSlotTypeFromSelection(u32 selection) const; std::pair<s32, bool> GetSlotTypeFromSelection(u32 selection) const;
std::string m_load_legend;
std::string m_save_legend;
std::string m_prev_legend;
std::string m_next_legend;
CommonHostInterface* m_host_interface; CommonHostInterface* m_host_interface;
std::vector<ListEntry> m_slots; std::vector<ListEntry> m_slots;
u32 m_current_selection = 0; u32 m_current_selection = 0;