overlays/list-view: Use track to indicate scrolling instead of ugly highlight

This commit is contained in:
kd-11 2026-03-16 01:05:46 +03:00 committed by kd-11
parent f9af53f215
commit 6c0c80b7bb
4 changed files with 69 additions and 41 deletions

View file

@ -48,13 +48,11 @@ namespace rsx
void home_menu_page::on_activate()
{
hide_scroll_indicators(false);
hide_row_highliter(false);
}
void home_menu_page::on_deactivate()
{
hide_scroll_indicators(true);
hide_row_highliter(true);
}

View file

@ -12,20 +12,25 @@ namespace rsx
w = width;
h = height;
m_scroll_indicator_top = std::make_unique<image_view>(width, 5);
m_scroll_indicator_bottom = std::make_unique<image_view>(width, 5);
m_accept_btn = std::make_unique<image_button>(120, 20);
m_cancel_btn = std::make_unique<image_button>(120, 20);
m_highlight_box = std::make_unique<overlay_element>(width, 0);
auto scroll_indicator_track = std::make_unique<overlay_element>(5, height);
auto scroll_indicator_grip = std::make_unique<rounded_rect>(5, height);
scroll_indicator_grip->set_pos(1, 0);
scroll_indicator_grip->set_size(5, 5);
scroll_indicator_grip->radius = 2;
scroll_indicator_track->set_size(7, height);
m_scroll_indicator = std::make_unique<box_layout>();
m_scroll_indicator_track = m_scroll_indicator->add_element(scroll_indicator_track);
m_scroll_indicator_grip = m_scroll_indicator->add_element(scroll_indicator_grip);
m_accept_btn = std::make_unique<image_button>(120, 20);
m_cancel_btn = std::make_unique<image_button>(120, 20);
m_highlight_box = std::make_unique<overlay_element>(width, 0);
m_scroll_indicator_top->set_size(width, 10);
m_scroll_indicator_bottom->set_size(width, 10);
m_accept_btn->set_size(120, 30);
m_cancel_btn->set_size(120, 30);
m_scroll_indicator_top->set_image_resource(resource_config::standard_image_resource::fade_top);
m_scroll_indicator_bottom->set_image_resource(resource_config::standard_image_resource::fade_bottom);
if (g_cfg.sys.enter_button_assignment == enter_button_assign::circle)
{
m_accept_btn->set_image_resource(resource_config::standard_image_resource::circle);
@ -37,7 +42,7 @@ namespace rsx
m_cancel_btn->set_image_resource(resource_config::standard_image_resource::circle);
}
m_scroll_indicator_bottom->set_pos(0, height - 10);
m_scroll_indicator->set_pos(width - 7, 0);
m_accept_btn->set_pos(30, height + 20);
if (can_deny)
@ -67,8 +72,6 @@ namespace rsx
m_highlight_box->back_color = {.5f, .5f, .8f, 0.2f};
m_highlight_box->pulse_effect_enabled = true;
m_scroll_indicator_top->fore_color.a = 0.f;
m_scroll_indicator_bottom->fore_color.a = 0.f;
}
const overlay_element* list_view::get_selected_entry() const
@ -118,23 +121,16 @@ namespace rsx
scroll_offset_value = max_y - h - 2;
}
if ((scroll_offset_value + h + 2) >= m_elements_height)
m_scroll_indicator_bottom->fore_color.a = 0.f;
else
m_scroll_indicator_bottom->fore_color.a = 0.5f;
if (scroll_offset_value == 0)
m_scroll_indicator_top->fore_color.a = 0.f;
else
m_scroll_indicator_top->fore_color.a = 0.5f;
if (m_elements_height > h)
{
update_scroll_indicator();
}
m_highlight_box->set_pos(current_element->x, current_element->y);
m_highlight_box->h = current_element->h + pack_padding;
m_highlight_box->y -= scroll_offset_value;
m_highlight_box->refresh();
m_scroll_indicator_top->refresh();
m_scroll_indicator_bottom->refresh();
refresh();
}
@ -221,10 +217,10 @@ namespace rsx
refresh();
}
void list_view::hide_scroll_indicators(bool hidden)
void list_view::hide_scroll_indicator(bool hidden)
{
m_scroll_indicator_top->set_visible(!hidden);
m_scroll_indicator_bottom->set_visible(!hidden);
m_scroll_indicator_track->set_visible(!hidden);
m_scroll_indicator_grip->set_visible(!hidden);
refresh();
}
@ -265,8 +261,7 @@ namespace rsx
void list_view::translate(s16 _x, s16 _y)
{
layout_container::translate(_x, _y);
m_scroll_indicator_top->translate(_x, _y);
m_scroll_indicator_bottom->translate(_x, _y);
m_scroll_indicator->translate(_x, _y);
m_accept_btn->translate(_x, _y);
m_cancel_btn->translate(_x, _y);
@ -280,22 +275,49 @@ namespace rsx
{
vertical_layout::set_size(w, h);
m_scroll_indicator_top->w = w;
m_scroll_indicator_bottom->w = w;
m_highlight_box->w = w;
m_scroll_indicator_top->refresh();
m_scroll_indicator_bottom->refresh();
update_scroll_indicator();
m_scroll_indicator->refresh();
m_highlight_box->refresh();
}
void list_view::set_pos(s16 x, s16 y)
{
const auto prev_x = this->x, prev_y = this->y;
vertical_layout::set_pos(x, y);
update_selection();
}
void list_view::update_scroll_indicator()
{
// Always reposition
m_scroll_indicator->set_pos(x + w - 7, y);
m_scroll_indicator->set_size(7, h);
// Render grip and track
m_scroll_indicator_track->back_color = this->fore_color * 0.25f;
m_scroll_indicator_track->back_color.a = 1.f;
m_scroll_indicator_track->h = m_scroll_indicator->h;
m_scroll_indicator_grip->back_color = this->fore_color;
m_scroll_indicator_grip->back_color.a = 1.f;
m_scroll_indicator_grip->h = 0;
if (m_elements_height < h)
{
return;
}
const f32 viewable_ratio = static_cast<f32>(m_scroll_indicator->h) / m_elements_height;
const f32 scroll_ratio = static_cast<f32>(scroll_offset_value) / m_elements_height;
m_scroll_indicator_grip->h = static_cast<u16>(viewable_ratio * m_scroll_indicator->h);
m_scroll_indicator_grip->y = m_scroll_indicator->y + static_cast<s16>(scroll_ratio * m_scroll_indicator->h);
}
compiled_resource& list_view::get_compiled()
{
if (is_compiled())
@ -313,10 +335,14 @@ namespace rsx
auto& compiled = vertical_layout::get_compiled();
compiled.add(m_highlight_box->get_compiled());
compiled.add(m_scroll_indicator_top->get_compiled());
compiled.add(m_scroll_indicator_bottom->get_compiled());
compiled.add(m_cancel_btn->get_compiled());
if (m_elements_height > h)
{
// Auto overflow
compiled.add(m_scroll_indicator->get_compiled());
}
if (m_cancel_only)
{
m_is_compiled = true;

View file

@ -9,13 +9,15 @@ namespace rsx
struct list_view : public vertical_layout
{
private:
std::unique_ptr<image_view> m_scroll_indicator_top;
std::unique_ptr<image_view> m_scroll_indicator_bottom;
std::unique_ptr<box_layout> m_scroll_indicator;
std::unique_ptr<image_button> m_cancel_btn;
std::unique_ptr<image_button> m_accept_btn;
std::unique_ptr<image_button> m_deny_btn;
std::unique_ptr<overlay_element> m_highlight_box;
overlay_element* m_scroll_indicator_track = nullptr;
rounded_rect* m_scroll_indicator_grip = nullptr;
u16 m_elements_height = 0;
s32 m_selected_entry = -1;
u16 m_elements_count = 0;
@ -23,6 +25,8 @@ namespace rsx
bool m_use_separators = false;
bool m_cancel_only = false;
void update_scroll_indicator();
public:
list_view(u16 width, u16 height, bool use_separators = true, bool can_deny = false);
@ -50,7 +54,7 @@ namespace rsx
const overlay_element* get_selected_entry() const;
void hide_prompt_buttons(bool hidden = true);
void hide_scroll_indicators(bool hidden = true);
void hide_scroll_indicator(bool hidden = true);
void hide_row_highliter(bool hidden = false);
void disable_selection_pulse(bool disabled = true);

View file

@ -11,7 +11,7 @@ namespace rsx::overlays
: list_view(w, h, false)
{
hide_prompt_buttons();
hide_scroll_indicators();
hide_scroll_indicator();
pack_padding = dropdown_pack_padding;
}