mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-03-17 18:55:19 +01:00
rsx/overlays: Implement slider control
This commit is contained in:
parent
1be7b9f983
commit
63ed8881a4
|
|
@ -730,9 +730,10 @@ namespace rsx
|
|||
return compiled_resources;
|
||||
}
|
||||
|
||||
void layout_container::add_spacer()
|
||||
void layout_container::add_spacer(u16 size)
|
||||
{
|
||||
std::unique_ptr<overlay_element> spacer_element = std::make_unique<spacer>();
|
||||
spacer_element->set_size(size, size);
|
||||
add_element(spacer_element);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ namespace rsx
|
|||
compiled_resource& get_compiled() override;
|
||||
|
||||
virtual u16 get_scroll_offset_px() = 0;
|
||||
void add_spacer();
|
||||
void add_spacer(u16 size = 0);
|
||||
};
|
||||
|
||||
struct vertical_layout : public layout_container
|
||||
|
|
|
|||
|
|
@ -1 +1,178 @@
|
|||
#include "stdafx.h"
|
||||
#include "overlay_slider.h"
|
||||
|
||||
namespace rsx::overlays
|
||||
{
|
||||
constexpr u16 slider_rail_thickness = 5;
|
||||
constexpr u16 slider_cover_thickness = 6;
|
||||
constexpr u16 slider_indicator_radius = 8;
|
||||
constexpr u16 slider_indicator_dia = slider_indicator_radius * 2;
|
||||
|
||||
void slider::init()
|
||||
{
|
||||
back_color = color4f(0.3f, 0.3f, 0.3f, 0.f);
|
||||
fore_color = color4f(0.5647f, 0.7922f, 0.9765f, 1.f);
|
||||
auto_resize = false;
|
||||
m_current_value = m_min_value;
|
||||
}
|
||||
|
||||
void slider::set_size(u16 w, u16 h)
|
||||
{
|
||||
horizontal_layout::set_size(w, h);
|
||||
clear_items();
|
||||
|
||||
// Clamp the height
|
||||
h = std::max<u16>(h, 8);
|
||||
|
||||
// Base components
|
||||
auto background = std::make_unique<rounded_rect>();
|
||||
auto foreground = std::make_unique<rounded_rect>();
|
||||
auto indicator = std::make_unique<rounded_rect>();
|
||||
auto value_label = std::make_unique<label>();
|
||||
auto min_label = std::make_unique<label>();
|
||||
auto max_label = std::make_unique<label>();
|
||||
|
||||
indicator->radius = slider_indicator_radius;
|
||||
indicator->set_size(slider_indicator_dia, slider_indicator_dia);
|
||||
indicator->back_color = color4f(1.f);
|
||||
|
||||
background->radius = slider_rail_thickness / 2;
|
||||
background->back_color = this->back_color;
|
||||
background->back_color.a = 1.f;
|
||||
background->set_size(w, slider_rail_thickness);
|
||||
background->set_pos(0, (slider_indicator_dia / 2) - background->radius);
|
||||
|
||||
foreground->radius = slider_cover_thickness / 2;
|
||||
foreground->back_color = this->fore_color;
|
||||
foreground->set_size(0, slider_cover_thickness);
|
||||
foreground->set_pos(0, (slider_indicator_dia / 2) - foreground->radius);
|
||||
|
||||
value_label->set_padding(2);
|
||||
value_label->set_font("Arial", 10);
|
||||
value_label->set_text(m_formatter(m_current_value));
|
||||
value_label->auto_resize();
|
||||
value_label->back_color.a = 0.f;
|
||||
value_label->fore_color = color4f(1.f);
|
||||
|
||||
min_label->fore_color = color4f(0.75f, 0.75f, 0.75f, 1.f);
|
||||
min_label->back_color.a = 0.f;
|
||||
min_label->set_font("Arial", 10);
|
||||
min_label->set_text(m_formatter(m_min_value));
|
||||
min_label->set_pos(0, (value_label->h / 2) + slider_indicator_radius + 8); // Margin = Text Height + Indicator Rad (gets to half point) - Text Height / 2 (Offset back to box origin)
|
||||
min_label->auto_resize();
|
||||
|
||||
max_label->fore_color = color4f(0.75f, 0.75f, 0.75f, 1.f);
|
||||
max_label->back_color.a = 0.f;
|
||||
max_label->set_font("Arial", 10);
|
||||
max_label->set_text(m_formatter(m_max_value));
|
||||
max_label->set_pos(0, (value_label->h / 2) + slider_indicator_radius + 8); // Margin
|
||||
max_label->auto_resize();
|
||||
|
||||
const u16 horizontal_padding = slider_indicator_dia;
|
||||
|
||||
if (m_show_labels)
|
||||
{
|
||||
const u16 unusable_space = max_label->w + min_label->w + (2 * horizontal_padding);
|
||||
if (unusable_space < w)
|
||||
{
|
||||
background->w -= unusable_space;
|
||||
foreground->w = unusable_space;
|
||||
}
|
||||
}
|
||||
|
||||
// Pack the slider part
|
||||
auto slider_part = std::make_unique<box_layout>();
|
||||
slider_part->set_size(background->w, 8);
|
||||
m_rail_component = slider_part->add_element(background);
|
||||
m_slider_component = slider_part->add_element(foreground);
|
||||
m_indicator_component = slider_part->add_element(indicator);
|
||||
|
||||
// Middle part of the sandwich
|
||||
auto stack_part = std::make_unique<vertical_layout>();
|
||||
m_value_component = stack_part->add_element(value_label);
|
||||
stack_part->add_spacer(8);
|
||||
stack_part->add_element(slider_part);
|
||||
|
||||
if (m_show_labels)
|
||||
{
|
||||
// Assemble the sandwich
|
||||
add_element(min_label);
|
||||
add_spacer(horizontal_padding);
|
||||
add_element(stack_part);
|
||||
add_spacer(horizontal_padding);
|
||||
add_element(max_label);
|
||||
}
|
||||
else
|
||||
{
|
||||
add_element(stack_part);
|
||||
}
|
||||
|
||||
update_elements();
|
||||
}
|
||||
|
||||
void slider::set_value(f64 value)
|
||||
{
|
||||
value = std::clamp(value, m_min_value, m_max_value);
|
||||
if (value == m_current_value)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_current_value = value;
|
||||
update_elements();
|
||||
}
|
||||
|
||||
void slider::set_show_labels(bool show)
|
||||
{
|
||||
if (m_show_labels == show)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_show_labels = show;
|
||||
set_size(w, h);
|
||||
}
|
||||
|
||||
void slider::update_elements()
|
||||
{
|
||||
if (!m_slider_component || !m_value_component || !m_rail_component)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto slider_w = (std::abs(m_current_value - m_min_value) * m_rail_component->w) / std::abs(m_max_value - m_min_value);
|
||||
const auto slider_w16 = static_cast<u16>(std::floor(slider_w));
|
||||
|
||||
m_slider_component->set_size(slider_w16, m_slider_component->h);
|
||||
m_indicator_component->set_pos(m_slider_component->x + slider_w16 - slider_indicator_radius, m_indicator_component->y);
|
||||
|
||||
m_value_component->set_text(m_formatter(m_current_value));
|
||||
m_value_component->auto_resize();
|
||||
|
||||
// If the label would touch the end, flip it
|
||||
u16 offset = (slider_w16 + m_value_component->w) >= m_rail_component->w ? m_value_component->w : 0;
|
||||
m_value_component->set_pos(m_slider_component->x + slider_w16 - offset, m_value_component->y);
|
||||
|
||||
// Hide indicator when slider is completely empty or completely full
|
||||
m_value_component->visible = (m_current_value != m_min_value) && (m_current_value != m_max_value);
|
||||
}
|
||||
|
||||
void slider::set_value_format(std::function<std::string(f64)> formatter)
|
||||
{
|
||||
m_formatter = formatter;
|
||||
set_size(w, h);
|
||||
}
|
||||
|
||||
compiled_resource& slider::get_compiled()
|
||||
{
|
||||
if (is_compiled())
|
||||
{
|
||||
return compiled_resources;
|
||||
}
|
||||
|
||||
horizontal_layout::get_compiled();
|
||||
|
||||
m_is_compiled = true;
|
||||
return compiled_resources;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,48 @@
|
|||
|
||||
namespace rsx::overlays
|
||||
{
|
||||
struct slider : public overlay_element
|
||||
struct slider : public horizontal_layout
|
||||
{
|
||||
slider()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
slider(f64 min, f64 max, f64 step)
|
||||
: m_min_value(min)
|
||||
, m_max_value(max)
|
||||
, m_step(step)
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
void set_size(u16 w, u16 h) override;
|
||||
void set_value_format(std::function<std::string(f64)> formatter);
|
||||
void set_show_labels(bool show);
|
||||
|
||||
void inc_value() { set_value(m_current_value + m_step); }
|
||||
void dec_value() { set_value(m_current_value - m_step); }
|
||||
void set_value(f64 value);
|
||||
|
||||
compiled_resource& get_compiled() override;
|
||||
|
||||
private:
|
||||
f64 m_min_value = 0.0;
|
||||
f64 m_max_value = 100.0;
|
||||
f64 m_current_value = 0.0;
|
||||
f64 m_step = 1.0;
|
||||
|
||||
bool m_show_labels = true;
|
||||
|
||||
std::function<std::string(f64)> m_formatter =
|
||||
[](f64 v) { return std::to_string(v); };
|
||||
|
||||
overlay_element* m_slider_component = nullptr;
|
||||
overlay_element* m_rail_component = nullptr;
|
||||
overlay_element* m_indicator_component = nullptr;
|
||||
label* m_value_component = nullptr;
|
||||
|
||||
void init();
|
||||
void update_elements();
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue