mirror of
https://github.com/stenzek/duckstation.git
synced 2026-02-14 18:34:32 +00:00
FullscreenUI: Improve split window UX
- Fix sidebar scroll resetting after activation. - Fix selection rectangle displaying on escape down. - Improve padding and remove gaps.
This commit is contained in:
@@ -1903,13 +1903,7 @@ void FullscreenUI::DrawSettingsWindow()
|
||||
ImVec2(io.DisplaySize.x, io.DisplaySize.y - heading_size.y - LayoutScale(LAYOUT_FOOTER_HEIGHT)),
|
||||
TinyString::from_format("settings_page_{}", static_cast<u32>(s_settings_locals.settings_page)).c_str(),
|
||||
ImVec4(UIStyle.BackgroundColor.x, UIStyle.BackgroundColor.y, UIStyle.BackgroundColor.z,
|
||||
s_settings_locals.settings_last_bg_alpha),
|
||||
0.0f, ImVec2(LAYOUT_MENU_WINDOW_X_PADDING, LAYOUT_MENU_WINDOW_Y_PADDING));
|
||||
|
||||
// so the child windows get it
|
||||
ImGui::PushStyleColor(ImGuiCol_WindowBg,
|
||||
ModAlpha(UIStyle.BackgroundColor, s_settings_locals.settings_last_bg_alpha *
|
||||
s_settings_locals.settings_last_bg_alpha));
|
||||
s_settings_locals.settings_last_bg_alpha));
|
||||
|
||||
if (SplitWindowIsNavWindow() && WantsToCloseMenu())
|
||||
ReturnToPreviousWindow();
|
||||
@@ -1986,9 +1980,6 @@ void FullscreenUI::DrawSettingsWindow()
|
||||
}
|
||||
}
|
||||
|
||||
if (is_split_window)
|
||||
ImGui::PopStyleColor(1);
|
||||
|
||||
EndFullscreenWindow();
|
||||
|
||||
if (!ImGui::IsPopupOpen(0u, ImGuiPopupFlags_AnyPopup) && !WasSplitWindowChanged())
|
||||
@@ -3144,8 +3135,10 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
if (SplitWindowSidebarItem(FSUI_ICONVSTR(ICON_FA_GEARS, "Global Settings"),
|
||||
(s_settings_locals.selected_controller_port == -1)))
|
||||
{
|
||||
BeginTransition(DEFAULT_TRANSITION_TIME, []() { s_settings_locals.selected_controller_port = -1; });
|
||||
FullscreenUI::FocusSplitWindowContent(true);
|
||||
BeginTransition(DEFAULT_TRANSITION_TIME, []() {
|
||||
s_settings_locals.selected_controller_port = -1;
|
||||
FullscreenUI::FocusSplitWindowContent();
|
||||
});
|
||||
}
|
||||
|
||||
// load mtap settings
|
||||
@@ -3174,9 +3167,10 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
Controller::GetPortDisplayName(mtap_port, mtap_slot, mtap_enabled[mtap_port])),
|
||||
ci->GetDisplayName(), (s_settings_locals.selected_controller_port == static_cast<s8>(global_slot))))
|
||||
{
|
||||
BeginTransition(DEFAULT_TRANSITION_TIME,
|
||||
[global_slot]() { s_settings_locals.selected_controller_port = static_cast<s8>(global_slot); });
|
||||
FullscreenUI::FocusSplitWindowContent(true);
|
||||
BeginTransition(DEFAULT_TRANSITION_TIME, [global_slot]() {
|
||||
s_settings_locals.selected_controller_port = static_cast<s8>(global_slot);
|
||||
FullscreenUI::FocusSplitWindowContent();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3184,8 +3178,10 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
if (show_hotkeys && SplitWindowSidebarItem(FSUI_ICONVSTR(ICON_PF_KEYBOARD_ALT, "Hotkeys"),
|
||||
(s_settings_locals.selected_controller_port == -2)))
|
||||
{
|
||||
BeginTransition(DEFAULT_TRANSITION_TIME, []() { s_settings_locals.selected_controller_port = -2; });
|
||||
FullscreenUI::FocusSplitWindowContent(true);
|
||||
BeginTransition(DEFAULT_TRANSITION_TIME, []() {
|
||||
s_settings_locals.selected_controller_port = -2;
|
||||
FullscreenUI::FocusSplitWindowContent();
|
||||
});
|
||||
}
|
||||
|
||||
EndSplitWindowSidebar();
|
||||
@@ -3313,6 +3309,8 @@ void FullscreenUI::DrawControllerSettingsPage()
|
||||
|
||||
ImGui::PushID(TinyString::from_format("port_{}", global_slot));
|
||||
|
||||
MenuHeading(FSUI_VSTR("Controller Type"));
|
||||
|
||||
ResetSplitWindowContentFocusHere();
|
||||
|
||||
const TinyString section = TinyString::from_format("Pad{}", global_slot + 1);
|
||||
|
||||
@@ -1152,7 +1152,7 @@ void FullscreenUI::PushResetLayout()
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowRounding, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(8.0f, 8.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, LayoutScale(4.0f, 3.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, LayoutScale(8.0f, 4.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, LayoutScale(LAYOUT_ITEM_X_SPACING, LAYOUT_ITEM_Y_SPACING));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemInnerSpacing, LayoutScale(4.0f, 4.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, LayoutScale(4.0f, 2.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_IndentSpacing, LayoutScale(21.0f));
|
||||
@@ -1252,10 +1252,8 @@ bool FullscreenUI::IsFocusResetQueued()
|
||||
|
||||
bool FullscreenUI::IsFocusResetFromWindowChange()
|
||||
{
|
||||
return (s_state.focus_reset_queued != FocusResetType::None &&
|
||||
s_state.focus_reset_queued != FocusResetType::PopupOpened &&
|
||||
s_state.focus_reset_queued != FocusResetType::PopupClosed &&
|
||||
s_state.focus_reset_queued != FocusResetType::SplitWindowChanged);
|
||||
return (s_state.focus_reset_queued == FocusResetType::ViewChanged ||
|
||||
s_state.focus_reset_queued == FocusResetType::Other);
|
||||
}
|
||||
|
||||
FullscreenUI::FocusResetType FullscreenUI::GetQueuedFocusResetType()
|
||||
@@ -2216,8 +2214,8 @@ void FullscreenUI::MenuHeading(std::string_view title, bool draw_line /*= true*/
|
||||
const ImVec2 title_size =
|
||||
UIStyle.Font->CalcTextSizeA(font_size, font_weight, FLT_MAX, avail_width, IMSTR_START_END(title));
|
||||
const u32 title_color = ImGui::GetColorU32(ImGuiCol_TextDisabled);
|
||||
RenderShadowedTextClipped(UIStyle.Font, font_size, font_weight, pos, pos + title_size,
|
||||
title_color, title, &title_size, ImVec2(0.0f, 0.0f), avail_width);
|
||||
RenderShadowedTextClipped(UIStyle.Font, font_size, font_weight, pos, pos + title_size, title_color, title,
|
||||
&title_size, ImVec2(0.0f, 0.0f), avail_width);
|
||||
|
||||
float total_height = UIStyle.LargeFontSize + style.FramePadding.y;
|
||||
|
||||
@@ -3310,9 +3308,9 @@ void FullscreenUI::BeginInnerSplitWindow()
|
||||
window->DC.LayoutType = ImGuiLayoutType_Horizontal;
|
||||
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, LayoutScale(10.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, ImVec2(0.0f, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildBorderSize, 0.0f);
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, LayoutScale(LAYOUT_MENU_ITEM_BORDER_ROUNDING));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ChildRounding, 0.0f);
|
||||
|
||||
s_state.split_window_focus_change = SplitWindowFocusChange::None;
|
||||
|
||||
@@ -3338,14 +3336,18 @@ void FullscreenUI::EndInnerSplitWindow()
|
||||
|
||||
bool FullscreenUI::BeginSplitWindowSidebar(float sidebar_width /*= 0.2f*/)
|
||||
{
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(10.0f, 10.0f));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, DarkerColor(ImGui::GetStyle().Colors[ImGuiCol_WindowBg], 1.2f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding,
|
||||
LayoutScale(LAYOUT_MENU_WINDOW_X_PADDING, LAYOUT_MENU_WINDOW_Y_PADDING));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, LayoutScale(LAYOUT_ITEM_X_SPACING, LAYOUT_ITEM_Y_SPACING));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg,
|
||||
ModAlpha(DarkerColor(ImGui::GetStyle().Colors[ImGuiCol_WindowBg], 1.75f), 0.25f));
|
||||
|
||||
if (IsFocusResetFromWindowChange())
|
||||
ImGui::SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
||||
|
||||
const float sidebar_width_px = ImFloor(ImGui::GetCurrentWindowRead()->WorkRect.GetWidth() * sidebar_width);
|
||||
if (!ImGui::BeginChild("sidebar", ImVec2(sidebar_width_px, 0.0f)))
|
||||
if (!ImGui::BeginChild("sidebar", ImVec2(sidebar_width_px, 0.0f),
|
||||
ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_NoNavCancel))
|
||||
return false;
|
||||
|
||||
if (ImGui::IsWindowFocused())
|
||||
@@ -3380,7 +3382,7 @@ void FullscreenUI::EndSplitWindowSidebar()
|
||||
|
||||
ImGui::GetWindowDrawList()->ChannelsMerge();
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopStyleVar(1);
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
SetWindowNavWrapping(false, true);
|
||||
|
||||
@@ -3444,7 +3446,10 @@ bool FullscreenUI::SplitWindowSidebarItem(std::string_view title, std::string_vi
|
||||
|
||||
bool FullscreenUI::BeginSplitWindowContent(bool background)
|
||||
{
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg, DarkerColor(ImGui::GetStyle().Colors[ImGuiCol_WindowBg], 1.1f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, LayoutScale(LAYOUT_MENU_WINDOW_X_PADDING, 0.0f));
|
||||
ImGui::PushStyleVar(ImGuiStyleVar_ItemSpacing, LayoutScale(LAYOUT_ITEM_X_SPACING, LAYOUT_ITEM_Y_SPACING));
|
||||
ImGui::PushStyleColor(ImGuiCol_ChildBg,
|
||||
ModAlpha(DarkerColor(ImGui::GetStyle().Colors[ImGuiCol_WindowBg], 1.5f), 0.25f));
|
||||
|
||||
if (IsFocusResetFromWindowChange())
|
||||
ImGui::SetNextWindowScroll(ImVec2(0.0f, 0.0f));
|
||||
@@ -3452,8 +3457,9 @@ bool FullscreenUI::BeginSplitWindowContent(bool background)
|
||||
ImGuiWindow* const window = ImGui::GetCurrentWindow();
|
||||
const float content_width = window->WorkRect.Max.x - window->DC.CursorPos.x;
|
||||
|
||||
const bool ret =
|
||||
ImGui::BeginChild("content", ImVec2(content_width, 0.0f), 0, background ? 0 : ImGuiWindowFlags_NoBackground);
|
||||
const bool ret = ImGui::BeginChild("content", ImVec2(content_width, 0.0f),
|
||||
ImGuiChildFlags_AlwaysUseWindowPadding | ImGuiChildFlags_NoNavCancel,
|
||||
background ? 0 : ImGuiWindowFlags_NoBackground);
|
||||
|
||||
if (ImGui::IsWindowFocused())
|
||||
{
|
||||
@@ -3483,6 +3489,7 @@ void FullscreenUI::ResetSplitWindowContentFocusHere()
|
||||
void FullscreenUI::EndSplitWindowContent()
|
||||
{
|
||||
ImGui::PopStyleColor(1);
|
||||
ImGui::PopStyleVar(2);
|
||||
|
||||
SetWindowNavWrapping(false, true);
|
||||
|
||||
@@ -3494,10 +3501,10 @@ bool FullscreenUI::WasSplitWindowChanged()
|
||||
return (s_state.split_window_focus_change != SplitWindowFocusChange::None);
|
||||
}
|
||||
|
||||
void FullscreenUI::FocusSplitWindowContent(bool reset_content_nav)
|
||||
void FullscreenUI::FocusSplitWindowContent()
|
||||
{
|
||||
s_state.split_window_focus_change = SplitWindowFocusChange::FocusContent;
|
||||
QueueResetFocus(reset_content_nav ? FocusResetType::Other : FocusResetType::SplitWindowChanged);
|
||||
QueueResetFocus(FocusResetType::SplitContentChanged);
|
||||
}
|
||||
|
||||
bool FullscreenUI::SplitWindowIsNavWindow()
|
||||
|
||||
@@ -56,7 +56,9 @@ inline constexpr float LAYOUT_MENU_WINDOW_X_PADDING = 12.0f;
|
||||
inline constexpr float LAYOUT_MENU_WINDOW_Y_PADDING = 12.0f;
|
||||
inline constexpr float LAYOUT_MENU_ITEM_TITLE_SUMMARY_SPACING = 6.0f;
|
||||
inline constexpr float LAYOUT_MENU_ITEM_EXTRA_HEIGHT = 2.0f;
|
||||
static constexpr float LAYOUT_MENU_ITEM_BORDER_ROUNDING = 10.0f;
|
||||
inline constexpr float LAYOUT_MENU_ITEM_BORDER_ROUNDING = 10.0f;
|
||||
inline constexpr float LAYOUT_ITEM_X_SPACING = 8.0f;
|
||||
inline constexpr float LAYOUT_ITEM_Y_SPACING = 4.0f;
|
||||
inline constexpr float LAYOUT_FOOTER_PADDING = 10.0f;
|
||||
inline constexpr float LAYOUT_FOOTER_HEIGHT = LAYOUT_MEDIUM_FONT_SIZE + LAYOUT_FOOTER_PADDING * 2.0f;
|
||||
inline constexpr float LAYOUT_HORIZONTAL_MENU_HEIGHT = 320.0f;
|
||||
@@ -297,6 +299,7 @@ enum class FocusResetType : u8
|
||||
PopupClosed,
|
||||
ViewChanged,
|
||||
SplitWindowChanged,
|
||||
SplitContentChanged,
|
||||
Other,
|
||||
};
|
||||
void QueueResetFocus(FocusResetType type);
|
||||
@@ -480,7 +483,7 @@ bool BeginSplitWindowContent(bool background);
|
||||
void ResetSplitWindowContentFocusHere();
|
||||
void EndSplitWindowContent();
|
||||
bool WasSplitWindowChanged();
|
||||
void FocusSplitWindowContent(bool reset_content_nav);
|
||||
void FocusSplitWindowContent();
|
||||
bool SplitWindowIsNavWindow();
|
||||
|
||||
using FileSelectorCallback = std::function<void(std::string path)>;
|
||||
|
||||
Reference in New Issue
Block a user