rsx/overlays: Convert settings pages to a tabbed interface

This commit is contained in:
kd-11 2026-03-08 21:30:52 +03:00 committed by kd-11
parent d5928d99d7
commit 23eb67badc
6 changed files with 103 additions and 15 deletions

View file

@ -10,7 +10,6 @@ namespace rsx
{
static constexpr u16 menu_entry_height = 40;
static constexpr u16 menu_entry_margin = 20;
static constexpr u16 available_side_width = (overlay::virtual_width - 6 * menu_entry_margin) / 2;
static constexpr u16 element_height = 25;
enum class page_navigation

View file

@ -15,7 +15,7 @@ namespace rsx
void set_current_page(home_menu_page* page);
home_menu_page* get_current_page(bool include_this);
page_navigation handle_button_press(pad_button button_press, bool is_auto_repeat, u64 auto_repeat_interval_ms);
virtual page_navigation handle_button_press(pad_button button_press, bool is_auto_repeat, u64 auto_repeat_interval_ms);
void translate(s16 _x, s16 _y) override;
void set_size(u16 _w, u16 _h) override;

View file

@ -9,15 +9,85 @@ namespace rsx
home_menu_settings::home_menu_settings(s16 x, s16 y, u16 width, u16 height, bool use_separators, home_menu_page* parent)
: home_menu_page(x, y, width, height, use_separators, parent, get_localized_string(localized_string_id::HOME_MENU_SETTINGS))
{
add_page(std::make_shared<home_menu_settings_audio>(x, y, width, height, use_separators, this));
add_page(std::make_shared<home_menu_settings_video>(x, y, width, height, use_separators, this));
add_page(std::make_shared<home_menu_settings_input>(x, y, width, height, use_separators, this));
add_page(std::make_shared<home_menu_settings_advanced>(x, y, width, height, use_separators, this));
add_page(std::make_shared<home_menu_settings_overlays>(x, y, width, height, use_separators, this));
add_page(std::make_shared<home_menu_settings_performance_overlay>(x, y, width, height, use_separators, this));
add_page(std::make_shared<home_menu_settings_debug>(x, y, width, height, use_separators, this));
m_tabs = std::make_unique<tabbed_container>(width, height, 350);
m_tabs->set_pos(x, y);
apply_layout();
add_page(std::make_shared<home_menu_settings_audio>(x, y, width, height, use_separators, nullptr));
add_page(std::make_shared<home_menu_settings_video>(x, y, width, height, use_separators, nullptr));
add_page(std::make_shared<home_menu_settings_input>(x, y, width, height, use_separators, nullptr));
add_page(std::make_shared<home_menu_settings_advanced>(x, y, width, height, use_separators, nullptr));
add_page(std::make_shared<home_menu_settings_overlays>(x, y, width, height, use_separators, nullptr));
add_page(std::make_shared<home_menu_settings_performance_overlay>(x, y, width, height, use_separators, nullptr));
add_page(std::make_shared<home_menu_settings_debug>(x, y, width, height, use_separators, nullptr));
//apply_layout();
// Select the first item
m_tabs->set_selected_tab(0);
}
void home_menu_settings::add_page(std::shared_ptr<home_menu_page> page)
{
auto panel = std::static_pointer_cast<overlay_element>(page);
page->on_deactivate();
m_tabs->add_tab(page->title, panel);
}
page_navigation home_menu_settings::handle_button_press(pad_button button_press, bool is_auto_repeat, u64 auto_repeat_interval_ms)
{
if (!m_tabs->is_in_selection_mode())
{
auto page = ensure(dynamic_cast<home_menu_page*>(m_tabs->get_selected()));
const auto nav_action = page->handle_button_press(button_press, is_auto_repeat, auto_repeat_interval_ms);
switch (nav_action)
{
case page_navigation::exit:
m_tabs->toggle_selection_mode();
page->on_deactivate();
return page_navigation::stay;
default:
return nav_action;
}
}
const auto prev_tab = m_tabs->get_selected_idx();
auto next_tab = prev_tab;
switch (button_press)
{
case pad_button::dpad_up:
case pad_button::ls_up:
next_tab = (prev_tab > 0)
? (prev_tab - 1)
: (m_tabs->tab_count() - 1);
break;
case pad_button::dpad_down:
case pad_button::ls_down:
next_tab = ((prev_tab + 1) >= m_tabs->tab_count())
? 0
: prev_tab + 1;
break;
case pad_button::cross:
m_tabs->toggle_selection_mode();
ensure(dynamic_cast<home_menu_page*>(m_tabs->get_selected()))->on_activate();
return page_navigation::stay;
case pad_button::circle:
return page_navigation::exit;
}
if (prev_tab != next_tab)
{
m_tabs->set_selected_tab(next_tab);
}
return page_navigation::stay;
}
compiled_resource& home_menu_settings::get_compiled()
{
// TODO: Caching
compiled_resources = home_menu_page::get_compiled();
compiled_resources.add(m_tabs->get_compiled());
return compiled_resources;
}
home_menu_settings_audio::home_menu_settings_audio(s16 x, s16 y, u16 width, u16 height, bool use_separators, home_menu_page* parent)
@ -32,7 +102,7 @@ namespace rsx
add_checkbox(&g_cfg.audio.enable_time_stretching, localized_string_id::HOME_MENU_SETTINGS_AUDIO_TIME_STRETCHING);
add_signed_slider(&g_cfg.audio.time_stretching_threshold, localized_string_id::HOME_MENU_SETTINGS_AUDIO_TIME_STRETCHING_THRESHOLD, " %", 1);
apply_layout();
apply_layout(false);
}
home_menu_settings_video::home_menu_settings_video(s16 x, s16 y, u16 width, u16 height, bool use_separators, home_menu_page* parent)

View file

@ -1,6 +1,8 @@
#pragma once
#include "overlay_home_menu_page.h"
#include "../overlay_tabs.h"
#include "Emu/System.h"
#include "Utilities/Config.h"
@ -13,8 +15,13 @@ namespace rsx
public:
home_menu_settings(s16 x, s16 y, u16 width, u16 height, bool use_separators, home_menu_page* parent);
page_navigation handle_button_press(pad_button button_press, bool is_auto_repeat, u64 auto_repeat_interval_ms) override;
compiled_resource& get_compiled() override;
private:
std::vector<std::shared_ptr<home_menu_page>> m_settings_pages;
void add_page(std::shared_ptr<home_menu_page> page) override;
std::unique_ptr<tabbed_container> m_tabs;
};
struct home_menu_settings_page : public home_menu_page

View file

@ -3,10 +3,11 @@
namespace rsx::overlays
{
tabbed_container::tabbed_container(u16 header_width)
tabbed_container::tabbed_container(u16 w, u16 h, u16 header_width)
: m_headers_width(header_width)
{
auto_resize = false;
set_size(w, h);
}
overlay_element* tabbed_container::add_element(std::unique_ptr<overlay_element>& item, int offset)
@ -121,6 +122,12 @@ namespace rsx::overlays
return m_selected_idx;
}
void tabbed_container::toggle_selection_mode()
{
m_is_in_tab_selection_mode = !m_is_in_tab_selection_mode;
set_headers_pulse_effect(m_is_in_tab_selection_mode);
}
compiled_resource& tabbed_container::get_compiled()
{
// TODO: Caching

View file

@ -7,24 +7,28 @@ namespace rsx::overlays
{
struct tabbed_container : public horizontal_layout
{
tabbed_container(u16 header_width = 0);
tabbed_container(u16 w, u16 h, u16 header_width = 0);
void add_tab(std::string_view title, std::shared_ptr<overlay_element>& panel);
void add_tab(std::unique_ptr<overlay_element>& header, std::shared_ptr<overlay_element>& panel);
u32 tab_count() const { return m_tab_headers ? m_tab_headers->get_elements_count() : 0u; }
virtual void set_size(u16 _w, u16 _h) override;
virtual void set_headers_width(u16 size);
virtual void set_headers_pulse_effect(bool pulse);
overlay_element* set_selected_tab(u32 index);
overlay_element* get_selected() const;
u32 get_selected_idx() const;
void toggle_selection_mode();
bool is_in_selection_mode() const { return m_is_in_tab_selection_mode; }
compiled_resource& get_compiled() override;
protected:
void reflow_layout();
void set_current_tab(overlay_element* view);
void set_headers_pulse_effect(bool pulse);
overlay_element* add_element(std::unique_ptr<overlay_element>& item, int offset = -1) override;
@ -35,6 +39,7 @@ namespace rsx::overlays
u16 m_headers_width = 0;
u32 m_selected_idx = umax;
bool m_is_in_tab_selection_mode = true;
};
}