FullscreenUI: Fix button behaviour in Load/Save State

This commit is contained in:
Stenzek 2023-10-08 13:58:45 +10:00
parent 1f8dda5ffa
commit 5c0dab4fe8
No known key found for this signature in database

View file

@ -5166,6 +5166,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::PushStyleColor(ImGuiCol_ChildBg, ModAlpha(UIBackgroundColor, 0.9f));
ImGui::SetCursorPos(ImVec2(0.0f, heading_size.y));
bool closed = false;
bool close_handled = false;
if (s_save_state_selector_open &&
ImGui::BeginChild("state_list", ImVec2(io.DisplaySize.x, io.DisplaySize.y - heading_size.y), false,
@ -5193,90 +5194,12 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
u32 grid_x = 0;
ImGui::SetCursorPos(ImVec2(start_x, 0.0f));
for (u32 i = 0; i < s_save_state_selector_slots.size(); i++)
for (u32 i = 0; i < s_save_state_selector_slots.size();)
{
if (i == 0)
ResetFocusHere();
const SaveStateListEntry& entry = s_save_state_selector_slots[i];
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
continue;
const ImGuiID id = window->GetID(static_cast<int>(i));
const ImVec2 pos(window->DC.CursorPos);
ImRect bb(pos, pos + item_size);
ImGui::ItemSize(item_size);
if (ImGui::ItemAdd(bb, id))
{
bool held;
bool hovered;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
if (hovered)
{
const ImU32 col = ImGui::GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered, 1.0f);
const float t = std::min(static_cast<float>(std::abs(std::sin(ImGui::GetTime() * 0.75) * 1.1)), 1.0f);
ImGui::PushStyleColor(ImGuiCol_Border, ImGui::GetColorU32(ImGuiCol_Border, t));
ImGui::RenderFrame(bb.Min, bb.Max, col, true, 0.0f);
ImGui::PopStyleColor();
}
bb.Min += style.FramePadding;
bb.Max -= style.FramePadding;
GPUTexture* const screenshot =
entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get();
const ImRect image_rect(
CenterImage(ImRect(bb.Min, bb.Min + image_size),
ImVec2(static_cast<float>(screenshot->GetWidth()), static_cast<float>(screenshot->GetHeight()))));
ImGui::GetWindowDrawList()->AddImage(screenshot, image_rect.Min, image_rect.Max, ImVec2(0.0f, 0.0f),
ImVec2(1.0f, 1.0f), IM_COL32(255, 255, 255, 255));
const ImVec2 title_pos(bb.Min.x, bb.Min.y + image_height + title_spacing);
const ImRect title_bb(title_pos, ImVec2(bb.Max.x, title_pos.y + g_large_font->FontSize));
ImGui::PushFont(g_large_font);
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, entry.title.c_str(), nullptr, nullptr, ImVec2(0.0f, 0.0f),
&title_bb);
ImGui::PopFont();
if (!entry.summary.empty())
{
const ImVec2 summary_pos(bb.Min.x, title_pos.y + g_large_font->FontSize + summary_spacing);
const ImRect summary_bb(summary_pos, ImVec2(bb.Max.x, summary_pos.y + g_medium_font->FontSize));
ImGui::PushFont(g_medium_font);
ImGui::RenderTextClipped(summary_bb.Min, summary_bb.Max, entry.summary.c_str(), nullptr, nullptr,
ImVec2(0.0f, 0.0f), &summary_bb);
ImGui::PopFont();
}
if (pressed)
{
if (is_loading)
{
DoLoadState(entry.path);
CloseSaveStateSelector();
ReturnToPreviousWindow();
break;
}
else
{
DoSaveState(entry.slot, entry.global);
CloseSaveStateSelector();
ReturnToPreviousWindow();
break;
}
}
if (hovered && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
ImGui::IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed)))
{
s_save_state_selector_submenu_index = static_cast<s32>(i);
}
if (static_cast<s32>(i) == s_save_state_selector_submenu_index)
{
// can't use a choice dialog here, because we're already in a modal...
@ -5301,11 +5224,7 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::SetNextWindowPos(ImGui::GetIO().DisplaySize * 0.5f, ImGuiCond_Always, ImVec2(0.5f, 0.5f));
ImGui::OpenPopup(entry.title.c_str());
// don't let the back button flow through to the main window
bool submenu_open = !WantsToCloseMenu();
close_handled ^= submenu_open;
bool closed = false;
bool removed = false;
if (ImGui::BeginPopupModal(entry.title.c_str(), &is_open,
ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove))
{
@ -5322,8 +5241,6 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
else
DoSaveState(entry.slot, entry.global);
CloseSaveStateSelector();
ReturnToPreviousWindow();
closed = true;
}
@ -5339,18 +5256,13 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
{
ShowToast({}, fmt::format(FSUI_FSTR("{} deleted."), ImGuiFullscreen::RemoveHash(entry.title)));
s_save_state_selector_slots.erase(s_save_state_selector_slots.begin() + i);
removed = true;
if (s_save_state_selector_slots.empty())
{
CloseSaveStateSelector();
ReturnToPreviousWindow();
closed = true;
}
else
{
is_open = false;
}
}
else
{
ShowToast({}, fmt::format(FSUI_FSTR("Failed to delete {}."), ImGuiFullscreen::RemoveHash(entry.title)));
@ -5369,7 +5281,15 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::PopStyleColor();
ImGui::EndPopup();
}
if (!is_open)
// don't let the back button flow through to the main window
if (WantsToCloseMenu())
{
close_handled = true;
is_open = false;
}
if (!is_open || closed)
{
s_save_state_selector_submenu_index = -1;
if (!closed)
@ -5381,8 +5301,81 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::PopFont();
ImGuiFullscreen::PopResetLayout();
if (closed)
break;
if (removed)
continue;
}
ImGuiWindow* window = ImGui::GetCurrentWindow();
if (window->SkipItems)
{
i++;
continue;
}
const ImGuiID id = window->GetID(static_cast<int>(i));
const ImVec2 pos(window->DC.CursorPos);
ImRect bb(pos, pos + item_size);
ImGui::ItemSize(item_size);
if (ImGui::ItemAdd(bb, id))
{
bool held;
bool hovered;
bool pressed = ImGui::ButtonBehavior(bb, id, &hovered, &held, 0);
if (hovered)
{
const ImU32 col = ImGui::GetColorU32(held ? ImGuiCol_ButtonActive : ImGuiCol_ButtonHovered, 1.0f);
const float t = std::min(static_cast<float>(std::abs(std::sin(ImGui::GetTime() * 0.75) * 1.1)), 1.0f);
ImGui::PushStyleColor(ImGuiCol_Border, ImGui::GetColorU32(ImGuiCol_Border, t));
ImGui::RenderFrame(bb.Min, bb.Max, col, true, 0.0f);
ImGui::PopStyleColor();
}
bb.Min += style.FramePadding;
bb.Max -= style.FramePadding;
GPUTexture* const screenshot =
entry.preview_texture ? entry.preview_texture.get() : GetPlaceholderTexture().get();
const ImRect image_rect(
CenterImage(ImRect(bb.Min, bb.Min + image_size),
ImVec2(static_cast<float>(screenshot->GetWidth()), static_cast<float>(screenshot->GetHeight()))));
ImGui::GetWindowDrawList()->AddImage(screenshot, image_rect.Min, image_rect.Max, ImVec2(0.0f, 0.0f),
ImVec2(1.0f, 1.0f), IM_COL32(255, 255, 255, 255));
const ImVec2 title_pos(bb.Min.x, bb.Min.y + image_height + title_spacing);
const ImRect title_bb(title_pos, ImVec2(bb.Max.x, title_pos.y + g_large_font->FontSize));
ImGui::PushFont(g_large_font);
ImGui::RenderTextClipped(title_bb.Min, title_bb.Max, entry.title.c_str(), nullptr, nullptr, ImVec2(0.0f, 0.0f),
&title_bb);
ImGui::PopFont();
if (!entry.summary.empty())
{
const ImVec2 summary_pos(bb.Min.x, title_pos.y + g_large_font->FontSize + summary_spacing);
const ImRect summary_bb(summary_pos, ImVec2(bb.Max.x, summary_pos.y + g_medium_font->FontSize));
ImGui::PushFont(g_medium_font);
ImGui::RenderTextClipped(summary_bb.Min, summary_bb.Max, entry.summary.c_str(), nullptr, nullptr,
ImVec2(0.0f, 0.0f), &summary_bb);
ImGui::PopFont();
}
if (pressed)
{
if (is_loading)
DoLoadState(entry.path);
else
DoSaveState(entry.slot, entry.global);
closed = true;
}
if (hovered && (ImGui::IsItemClicked(ImGuiMouseButton_Right) ||
ImGui::IsNavInputTest(ImGuiNavInput_Input, ImGuiNavReadMode_Pressed)))
{
s_save_state_selector_submenu_index = static_cast<s32>(i);
}
}
@ -5397,6 +5390,8 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
{
ImGui::SameLine(start_x + static_cast<float>(grid_x) * (item_width + item_spacing));
}
i++;
}
EndMenuButtons();
@ -5408,7 +5403,12 @@ void FullscreenUI::DrawSaveStateSelector(bool is_loading)
ImGui::EndPopup();
ImGui::PopStyleVar(5);
if (!close_handled && WantsToCloseMenu())
if (closed)
{
CloseSaveStateSelector();
ReturnToMainWindow();
}
else if (!close_handled && WantsToCloseMenu())
{
CloseSaveStateSelector();
ReturnToPreviousWindow();