mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-04-03 03:57:21 +02:00
222 lines
6.4 KiB
C++
222 lines
6.4 KiB
C++
#pragma once
|
|
|
|
#include "Emu/RSX/Overlays/overlays.h"
|
|
#include "Utilities/Config.h"
|
|
|
|
namespace rsx
|
|
{
|
|
namespace overlays
|
|
{
|
|
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
|
|
{
|
|
stay,
|
|
back,
|
|
next,
|
|
exit
|
|
};
|
|
|
|
struct home_menu_entry : horizontal_layout
|
|
{
|
|
public:
|
|
home_menu_entry(const std::string& text);
|
|
};
|
|
|
|
template <typename T, typename C>
|
|
struct home_menu_setting : horizontal_layout
|
|
{
|
|
public:
|
|
home_menu_setting(C* setting, const std::string& text) : m_setting(setting)
|
|
{
|
|
std::unique_ptr<overlay_element> layout = std::make_unique<vertical_layout>();
|
|
std::unique_ptr<overlay_element> padding = std::make_unique<spacer>();
|
|
std::unique_ptr<overlay_element> title = std::make_unique<label>(text);
|
|
|
|
padding->set_size(1, 1);
|
|
title->set_size(available_side_width, menu_entry_height);
|
|
title->set_font("Arial", 16);
|
|
title->set_wrap_text(true);
|
|
title->align_text(text_align::right);
|
|
|
|
// Make back color transparent for text
|
|
title->back_color.a = 0.f;
|
|
|
|
static_cast<vertical_layout*>(layout.get())->pack_padding = 5;
|
|
static_cast<vertical_layout*>(layout.get())->add_element(padding);
|
|
static_cast<vertical_layout*>(layout.get())->add_element(title);
|
|
|
|
// Pack
|
|
this->pack_padding = 15;
|
|
add_element(layout);
|
|
|
|
update_value(true);
|
|
}
|
|
|
|
void update_value(bool initializing = false)
|
|
{
|
|
if (m_setting)
|
|
{
|
|
if (const T new_value = m_setting->get(); new_value != m_last_value || initializing)
|
|
{
|
|
m_last_value = new_value;
|
|
is_compiled = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
protected:
|
|
T m_last_value = {};
|
|
C* m_setting = nullptr;
|
|
};
|
|
|
|
struct home_menu_checkbox : public home_menu_setting<bool, cfg::_bool>
|
|
{
|
|
public:
|
|
home_menu_checkbox(cfg::_bool* setting, const std::string& text);
|
|
compiled_resource& get_compiled() override;
|
|
private:
|
|
overlay_element m_background;
|
|
overlay_element m_checkbox;
|
|
};
|
|
|
|
template <typename T>
|
|
struct home_menu_dropdown : public home_menu_setting<T, cfg::_enum<T>>
|
|
{
|
|
public:
|
|
home_menu_dropdown(cfg::_enum<T>* setting, const std::string& text) : home_menu_setting<T, cfg::_enum<T>>(setting, text)
|
|
{
|
|
m_dropdown.set_size(available_side_width / 2, element_height);
|
|
m_dropdown.set_pos(overlay::virtual_width / 2 + menu_entry_margin, 0);
|
|
m_dropdown.set_font("Arial", 14);
|
|
m_dropdown.align_text(home_menu_dropdown<T>::text_align::center);
|
|
m_dropdown.back_color = { 0.3f, 0.3f, 0.3f, 1.0f };
|
|
}
|
|
|
|
compiled_resource& get_compiled() override
|
|
{
|
|
this->update_value();
|
|
|
|
if (!this->is_compiled)
|
|
{
|
|
m_dropdown.set_text(fmt::format("%s", this->m_last_value));
|
|
m_dropdown.set_pos(m_dropdown.x, this->y + (this->h - m_dropdown.h) / 2);
|
|
|
|
this->compiled_resources = horizontal_layout::get_compiled();
|
|
this->compiled_resources.add(m_dropdown.get_compiled());
|
|
}
|
|
|
|
return this->compiled_resources;
|
|
}
|
|
|
|
private:
|
|
label m_dropdown;
|
|
};
|
|
|
|
template <typename T, typename C>
|
|
struct home_menu_slider : public home_menu_setting<T, C>
|
|
{
|
|
public:
|
|
home_menu_slider(C* setting, const std::string& text, const std::string& suffix, std::map<T, std::string> special_labels = {}, T minimum = C::min, T maximum = C::max)
|
|
: home_menu_setting<T, C>(setting, text)
|
|
, m_suffix(suffix)
|
|
, m_special_labels(std::move(special_labels))
|
|
, m_minimum(minimum)
|
|
, m_maximum(maximum)
|
|
{
|
|
m_slider.set_size(available_side_width / 2, element_height);
|
|
m_slider.set_pos(overlay::virtual_width / 2 + menu_entry_margin, 0);
|
|
m_slider.back_color = { 0.3f, 0.3f, 0.3f, 1.0f };
|
|
|
|
m_handle.set_size(element_height / 2, element_height);
|
|
m_handle.set_pos(m_slider.x, 0);
|
|
m_handle.back_color = { 1.0f, 1.0f, 1.0f, 1.0f };
|
|
|
|
m_value_label.back_color = m_slider.back_color;
|
|
m_value_label.set_font("Arial", 14);
|
|
}
|
|
|
|
compiled_resource& get_compiled() override
|
|
{
|
|
this->update_value();
|
|
|
|
if (!this->is_compiled)
|
|
{
|
|
const f64 percentage = std::clamp((this->m_last_value - static_cast<T>(m_minimum)) / std::fabs(m_maximum - m_minimum), 0.0, 1.0);
|
|
m_slider.set_pos(m_slider.x, this->y + (this->h - m_slider.h) / 2);
|
|
m_handle.set_pos(m_slider.x + static_cast<u16>(percentage * (m_slider.w - m_handle.w)), this->y + (this->h - m_handle.h) / 2);
|
|
|
|
const auto set_label_text = [this]() -> void
|
|
{
|
|
if (const auto it = m_special_labels.find(this->m_last_value); it != m_special_labels.cend())
|
|
{
|
|
m_value_label.set_text(it->second);
|
|
return;
|
|
}
|
|
|
|
if constexpr (std::is_floating_point<T>::value)
|
|
{
|
|
m_value_label.set_text(fmt::format("%.2f%s", this->m_last_value, m_suffix));
|
|
}
|
|
else
|
|
{
|
|
m_value_label.set_text(fmt::format("%d%s", this->m_last_value, m_suffix));
|
|
}
|
|
};
|
|
|
|
set_label_text();
|
|
m_value_label.auto_resize();
|
|
|
|
constexpr u16 handle_margin = 10;
|
|
|
|
if ((m_handle.x - m_slider.x) > (m_slider.w - (m_handle.w + 2 * handle_margin + m_value_label.w)))
|
|
{
|
|
m_value_label.set_pos(m_handle.x - (handle_margin + m_value_label.w), m_handle.y);
|
|
}
|
|
else
|
|
{
|
|
m_value_label.set_pos(m_handle.x + m_handle.w + handle_margin, m_handle.y);
|
|
}
|
|
|
|
this->compiled_resources = horizontal_layout::get_compiled();
|
|
this->compiled_resources.add(m_slider.get_compiled());
|
|
this->compiled_resources.add(m_handle.get_compiled());
|
|
this->compiled_resources.add(m_value_label.get_compiled());
|
|
}
|
|
|
|
return this->compiled_resources;
|
|
}
|
|
|
|
private:
|
|
overlay_element m_slider;
|
|
overlay_element m_handle;
|
|
label m_value_label;
|
|
std::string m_suffix;
|
|
std::map<T, std::string> m_special_labels;
|
|
T m_minimum{};
|
|
T m_maximum{};
|
|
};
|
|
|
|
template <s64 Min, s64 Max>
|
|
struct home_menu_signed_slider : public home_menu_slider<s64, cfg::_int<Min, Max>>
|
|
{
|
|
using home_menu_slider<s64, cfg::_int<Min, Max>>::home_menu_slider;
|
|
};
|
|
|
|
template <u64 Min, u64 Max>
|
|
struct home_menu_unsigned_slider : public home_menu_slider<u64, cfg::uint<Min, Max>>
|
|
{
|
|
using home_menu_slider<u64, cfg::uint<Min, Max>>::home_menu_slider;
|
|
};
|
|
|
|
template <s32 Min, s32 Max>
|
|
struct home_menu_float_slider : public home_menu_slider<f64, cfg::_float<Min, Max>>
|
|
{
|
|
using home_menu_slider<f64, cfg::_float<Min, Max>>::home_menu_slider;
|
|
};
|
|
}
|
|
}
|