Overlays: set layouts dirty if children are dirty

This fixes updates of widget items in lists.
Only set text dirty if it changed.
Properly mark spacers as compiled.
This commit is contained in:
Megamouse 2025-03-28 23:29:14 +01:00
parent 2f8ed1a6bd
commit 0e7945db53
12 changed files with 76 additions and 49 deletions

View file

@ -40,7 +40,7 @@ namespace rsx
{
update_value();
if (!is_compiled)
if (!is_compiled())
{
const f32 col = m_last_value ? 1.0f : 0.3f;
const f32 bkg = m_last_value ? 0.3f : 1.0f;

View file

@ -64,7 +64,7 @@ namespace rsx
if (const T new_value = m_setting->get(); new_value != m_last_value || initializing)
{
m_last_value = new_value;
is_compiled = false;
m_is_compiled = false;
}
}
}
@ -101,7 +101,7 @@ namespace rsx
{
this->update_value();
if (!this->is_compiled)
if (!this->is_compiled())
{
const std::string value_text = Emu.GetCallbacks().get_localized_setting(home_menu_setting<T, cfg::_enum<T>>::m_setting, static_cast<u32>(this->m_last_value));
m_dropdown.set_text(value_text);
@ -145,7 +145,7 @@ namespace rsx
{
this->update_value();
if (!this->is_compiled)
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);

View file

@ -44,7 +44,7 @@ namespace rsx
compiled_resource& home_menu_message_box::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
compiled_resource& compiled = overlay_element::get_compiled();
compiled.add(m_label.get_compiled());

View file

@ -258,9 +258,9 @@ namespace rsx
compiled_resource& home_menu_page::get_compiled()
{
if (!is_compiled || (m_message_box && !m_message_box->is_compiled))
if (!is_compiled() || (m_message_box && !m_message_box->is_compiled()))
{
is_compiled = false;
m_is_compiled = false;
if (home_menu_page* page = get_current_page(false))
{
@ -281,7 +281,7 @@ namespace rsx
}
}
is_compiled = true;
m_is_compiled = true;
}
return compiled_resources;

View file

@ -58,7 +58,7 @@ namespace rsx
compiled_resource& animated_icon::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
compiled_resources = image_view::get_compiled();
}

View file

@ -302,7 +302,7 @@ namespace rsx
void overlay_element::refresh()
{
// Just invalidate for draw when get_compiled() is called
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::translate(s16 _x, s16 _y)
@ -310,7 +310,7 @@ namespace rsx
x += _x;
y += _y;
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::scale(f32 _x, f32 _y, bool origin_scaling)
@ -324,7 +324,7 @@ namespace rsx
w = static_cast<u16>(_x * w);
h = static_cast<u16>(_y * h);
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::set_pos(s16 _x, s16 _y)
@ -332,7 +332,7 @@ namespace rsx
x = _x;
y = _y;
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::set_size(u16 _w, u16 _h)
@ -340,7 +340,7 @@ namespace rsx
w = _w;
h = _h;
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::set_padding(u16 left, u16 right, u16 top, u16 bottom)
@ -350,13 +350,13 @@ namespace rsx
padding_top = top;
padding_bottom = bottom;
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::set_padding(u16 padding)
{
padding_left = padding_right = padding_top = padding_bottom = padding;
is_compiled = false;
m_is_compiled = false;
}
// NOTE: Functions as a simple position offset. Top left corner is the anchor.
@ -365,25 +365,36 @@ namespace rsx
margin_left = left;
margin_top = top;
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::set_margin(u16 margin)
{
margin_left = margin_top = margin;
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::set_text(const std::string& text)
{
this->text = utf8_to_u32string(text);
is_compiled = false;
std::u32string new_text = utf8_to_u32string(text);
const bool is_dirty = this->text != new_text;
this->text = std::move(new_text);
if (is_dirty)
{
m_is_compiled = false;
}
}
void overlay_element::set_unicode_text(const std::u32string& text)
{
const bool is_dirty = this->text != text;
this->text = text;
is_compiled = false;
if (is_dirty)
{
m_is_compiled = false;
}
}
void overlay_element::set_text(localized_string_id id)
@ -394,19 +405,19 @@ namespace rsx
void overlay_element::set_font(const char* font_name, u16 font_size)
{
font_ref = fontmgr::get(font_name, font_size);
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::align_text(text_align align)
{
alignment = align;
is_compiled = false;
m_is_compiled = false;
}
void overlay_element::set_wrap_text(bool state)
{
wrap_text = state;
is_compiled = false;
m_is_compiled = false;
}
font* overlay_element::get_font() const
@ -563,7 +574,7 @@ namespace rsx
compiled_resource& overlay_element::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
compiled_resources.clear();
@ -599,7 +610,7 @@ namespace rsx
compiled_resources.add(std::move(compiled_resources_temp), margin_left - horizontal_scroll_offset, margin_top - vertical_scroll_offset);
}
is_compiled = true;
m_is_compiled = true;
}
return compiled_resources;
@ -664,7 +675,7 @@ namespace rsx
{
overlay_element::translate(_x, _y);
for (auto &itm : m_items)
for (auto& itm : m_items)
itm->translate(_x, _y);
}
@ -675,13 +686,23 @@ namespace rsx
translate(dx, dy);
}
bool layout_container::is_compiled()
{
if (m_is_compiled && std::any_of(m_items.cbegin(), m_items.cend(), [](const auto& item){ return item && !item->is_compiled(); }))
{
m_is_compiled = false;
}
return m_is_compiled;
}
compiled_resource& layout_container::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
compiled_resource result = overlay_element::get_compiled();
for (auto &itm : m_items)
for (auto& itm : m_items)
result.add(itm->get_compiled());
compiled_resources = result;
@ -716,7 +737,7 @@ namespace rsx
return m_items.back().get();
}
auto result = item.get();
overlay_element* result = item.get();
m_items.insert(m_items.begin() + offset, std::move(item));
return result;
}
@ -726,12 +747,12 @@ namespace rsx
if (scroll_offset_value == 0 && auto_resize)
return layout_container::get_compiled();
if (!is_compiled)
if (!is_compiled())
{
compiled_resource result = overlay_element::get_compiled();
const f32 global_y_offset = static_cast<f32>(-scroll_offset_value);
for (auto &item : m_items)
for (auto& item : m_items)
{
if (!item)
{
@ -808,7 +829,7 @@ namespace rsx
if (scroll_offset_value == 0 && auto_resize)
return layout_container::get_compiled();
if (!is_compiled)
if (!is_compiled())
{
compiled_resource result = overlay_element::get_compiled();
const f32 global_x_offset = static_cast<f32>(-scroll_offset_value);
@ -862,7 +883,7 @@ namespace rsx
compiled_resource& image_view::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
auto& result = overlay_element::get_compiled();
auto& cmd_img = result.draw_commands.front();
@ -880,7 +901,7 @@ namespace rsx
verts[2] += vertex(padding_left, -padding_top, 0, 0);
verts[3] += vertex(-padding_right, -padding_top, 0, 0);
is_compiled = true;
m_is_compiled = true;
}
return compiled_resources;
@ -935,7 +956,7 @@ namespace rsx
compiled_resource& image_button::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
auto& compiled = image_view::get_compiled();
for (auto& cmd : compiled.draw_commands)
@ -987,7 +1008,7 @@ namespace rsx
compiled_resource& rounded_rect::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
compiled_resources.clear();
@ -1068,7 +1089,7 @@ namespace rsx
compiled_resources.add(std::move(compiled_resources_temp), margin_left, margin_top);
}
is_compiled = true;
m_is_compiled = true;
}
return compiled_resources;

View file

@ -165,7 +165,6 @@ namespace rsx
void set_sinus_offset(f32 sinus_modifier);
compiled_resource compiled_resources;
bool is_compiled = false;
bool visible = true;
@ -185,6 +184,7 @@ namespace rsx
virtual ~overlay_element() = default;
virtual void refresh();
virtual bool is_compiled() { return m_is_compiled; }
virtual void translate(s16 _x, s16 _y);
virtual void scale(f32 _x, f32 _y, bool origin_scaling);
virtual void set_pos(s16 _x, s16 _y);
@ -204,6 +204,9 @@ namespace rsx
virtual std::vector<vertex> render_text(const char32_t* string, f32 x, f32 y);
virtual compiled_resource& get_compiled();
void measure_text(u16& width, u16& height, bool ignore_word_wrap = false) const;
protected:
bool m_is_compiled = false; // Only use m_is_compiled as a getter in is_compiled() if possible
};
struct layout_container : public overlay_element
@ -221,6 +224,8 @@ namespace rsx
void translate(s16 _x, s16 _y) override;
void set_pos(s16 _x, s16 _y) override;
bool is_compiled() override;
compiled_resource& get_compiled() override;
virtual u16 get_scroll_offset_px() = 0;
@ -248,6 +253,7 @@ namespace rsx
compiled_resource& get_compiled() override
{
// No draw
m_is_compiled = true;
return compiled_resources;
}
};

View file

@ -196,7 +196,7 @@ namespace rsx
compiled_resource& edit_text::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
auto renderer = get_font();
const auto [caret_x, caret_y] = renderer->get_char_offset(text.c_str(), caret_position, clip_text ? w : -1, wrap_text);
@ -252,7 +252,7 @@ namespace rsx
cmd.config.clip_rect = {static_cast<f32>(x), static_cast<f32>(y), static_cast<f32>(x + w), static_cast<f32>(y + h)};
}
is_compiled = true;
m_is_compiled = true;
}
return compiled_resources;

View file

@ -195,7 +195,7 @@ namespace rsx
m_cancel_btn->set_pos(x + 180, y + h + 20);
m_cancel_only = cancel_only;
is_compiled = false;
m_is_compiled = false;
}
bool list_view::get_cancel_only() const
@ -219,7 +219,7 @@ namespace rsx
compiled_resource& list_view::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
auto& compiled = vertical_layout::get_compiled();
compiled.add(m_highlight_box->get_compiled());

View file

@ -100,7 +100,7 @@ namespace rsx
}
// Disable caching
is_compiled = false;
m_is_compiled = false;
compiled_resources = rounded_rect::get_compiled();
compiled_resources.add(m_text.get_compiled());

View file

@ -814,7 +814,7 @@ namespace rsx
compiled_resource& graph::get_compiled()
{
if (is_compiled)
if (is_compiled())
{
return compiled_resources;
}

View file

@ -23,7 +23,7 @@ namespace rsx
void progress_bar::set_limit(f32 limit)
{
m_limit = limit;
is_compiled = false;
m_is_compiled = false;
}
void progress_bar::set_value(f32 value)
@ -32,7 +32,7 @@ namespace rsx
f32 indicator_width = (w * m_value) / m_limit;
indicator.set_size(static_cast<u16>(indicator_width), h);
is_compiled = false;
m_is_compiled = false;
}
void progress_bar::set_pos(s16 _x, s16 _y)
@ -68,12 +68,12 @@ namespace rsx
text_view.set_size(w, text_h);
set_pos(text_view.x, text_view.y);
is_compiled = false;
m_is_compiled = false;
}
compiled_resource& progress_bar::get_compiled()
{
if (!is_compiled)
if (!is_compiled())
{
auto& compiled = overlay_element::get_compiled();
compiled.add(text_view.get_compiled());