From bd41774960342f4e7838da7de00f38feff50988e Mon Sep 17 00:00:00 2001 From: Megamouse Date: Thu, 27 Feb 2025 04:06:39 +0100 Subject: [PATCH] overlays/osk: implement horizontal scroll --- rpcs3/Emu/RSX/Overlays/overlay_controls.cpp | 2 +- rpcs3/Emu/RSX/Overlays/overlay_controls.h | 3 ++ rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp | 48 +++++++++++++++----- rpcs3/Emu/RSX/Overlays/overlay_edit_text.hpp | 1 - rpcs3/Emu/RSX/Overlays/overlay_osk.cpp | 2 +- 5 files changed, 42 insertions(+), 14 deletions(-) diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp b/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp index e2c208b933..db1fc704a8 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.cpp @@ -596,7 +596,7 @@ namespace rsx cmd_text.verts = render_text(text.c_str(), static_cast(x), static_cast(y)); if (!cmd_text.verts.empty()) - compiled_resources.add(std::move(compiled_resources_temp), margin_left, margin_top); + compiled_resources.add(std::move(compiled_resources_temp), margin_left - horizontal_scroll_offset, margin_top - vertical_scroll_offset); } is_compiled = true; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_controls.h b/rpcs3/Emu/RSX/Overlays/overlay_controls.h index 2427418dde..6fe1b216d7 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_controls.h +++ b/rpcs3/Emu/RSX/Overlays/overlay_controls.h @@ -177,6 +177,9 @@ namespace rsx u16 margin_left = 0; u16 margin_top = 0; + f32 horizontal_scroll_offset = 0.0f; + f32 vertical_scroll_offset = 0.0f; + overlay_element() = default; overlay_element(u16 _w, u16 _h) : w(_w), h(_h) {} virtual ~overlay_element() = default; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp b/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp index 6107d7f997..7658563bcc 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_edit_text.cpp @@ -5,24 +5,24 @@ namespace rsx { namespace overlays { - static usz get_line_start(const std::u32string& text, usz pos) + static usz get_line_start(std::u32string_view text, usz pos) { if (pos == 0) { return 0; } const usz line_start = text.rfind('\n', pos - 1); - if (line_start == std::string::npos) + if (line_start == umax) { return 0; } return line_start + 1; } - static usz get_line_end(const std::u32string& text, usz pos) + static usz get_line_end(std::u32string_view text, usz pos) { const usz line_end = text.find('\n', pos); - if (line_end == std::string::npos) + if (line_end == umax) { return text.length(); } @@ -198,13 +198,11 @@ namespace rsx { if (!is_compiled) { - auto& compiled = label::get_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); overlay_element caret; - auto renderer = get_font(); - const auto caret_loc = renderer->get_char_offset(text.c_str(), caret_position, clip_text ? w : -1, wrap_text); - - caret.set_pos(static_cast(caret_loc.first) + padding_left + x, static_cast(caret_loc.second) + padding_top + y); + caret.set_pos(static_cast(caret_x) + padding_left + x, static_cast(caret_y) + padding_top + y); caret.set_size(1, static_cast(renderer->get_size_px() + 2)); caret.fore_color = fore_color; caret.back_color = fore_color; @@ -217,11 +215,39 @@ namespace rsx m_reset_caret_pulse = false; } - compiled.add(caret.get_compiled()); + // Check if we have to scroll horizontally + // TODO: Vertical scrolling + const s32 available_width = w - padding_left - padding_right; + const f32 offset_right = caret_x + caret.w - available_width; + + if (text.empty()) + { + // Scroll to the beginning + horizontal_scroll_offset = 0.0f; + } + else if (horizontal_scroll_offset >= caret_x) + { + // Scroll to the left so that the entire caret is visible + horizontal_scroll_offset = caret_x; + } + else if (horizontal_scroll_offset <= offset_right && offset_right > 0.0f) + { + // Scroll to the right so that the entire caret is visible + horizontal_scroll_offset = offset_right; + } + else if (horizontal_scroll_offset > 0.0f && offset_right > 0.0f && caret_position >= text.size()) + { + // Scroll to the left so that the entire caret is visible and reveal preceding text + horizontal_scroll_offset = offset_right; + } + + horizontal_scroll_offset = std::max(0.0f, horizontal_scroll_offset); + + auto& compiled = label::get_compiled(); + compiled.add(caret.get_compiled(), -horizontal_scroll_offset, -vertical_scroll_offset); for (auto& cmd : compiled.draw_commands) { - // TODO: Scrolling by using scroll offset cmd.config.clip_region = true; cmd.config.clip_rect = {static_cast(x), static_cast(y), static_cast(x + w), static_cast(y + h)}; } diff --git a/rpcs3/Emu/RSX/Overlays/overlay_edit_text.hpp b/rpcs3/Emu/RSX/Overlays/overlay_edit_text.hpp index 0774a35f7d..624580e4f4 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_edit_text.hpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_edit_text.hpp @@ -17,7 +17,6 @@ namespace rsx }; usz caret_position = 0; - u16 vertical_scroll_offset = 0; bool m_reset_caret_pulse = false; bool password_mode = false; diff --git a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp index 4bf189e354..82047a72bd 100644 --- a/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp +++ b/rpcs3/Emu/RSX/Overlays/overlay_osk.cpp @@ -435,7 +435,7 @@ namespace rsx m_preview.set_pos(input_x, input_y + title_height); m_preview.set_size(input_w, preview_height); - m_preview.set_padding(get_scaled(15), 0, get_scaled(10), 0); + m_preview.set_padding(get_scaled(15), get_scaled(15), get_scaled(10), 0); const s16 button_y = panel_y + panel_h + button_margin;