diff options
author | thankyouverycool <66646555+thankyouverycool@users.noreply.github.com> | 2022-02-13 13:46:45 -0500 |
---|---|---|
committer | Tim Flynn <trflynn89@pm.me> | 2022-02-15 10:13:19 -0500 |
commit | 170afc2f47bbbc289021be7f2b71e5697f83ad8b (patch) | |
tree | e8d98f12ab3d375960b0ae30dfe75a8d20c7cee6 | |
parent | 5658524aa332e67a512f45d6a4a4af97a0f1e4f5 (diff) | |
download | serenity-170afc2f47bbbc289021be7f2b71e5697f83ad8b.zip |
LibGUI: Allow GlyphMapWidget to filter by code point ranges
-rw-r--r-- | Userland/Libraries/LibGUI/GlyphMapWidget.cpp | 61 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/GlyphMapWidget.h | 3 |
2 files changed, 44 insertions, 20 deletions
diff --git a/Userland/Libraries/LibGUI/GlyphMapWidget.cpp b/Userland/Libraries/LibGUI/GlyphMapWidget.cpp index 4abe9b882f..a023d2301e 100644 --- a/Userland/Libraries/LibGUI/GlyphMapWidget.cpp +++ b/Userland/Libraries/LibGUI/GlyphMapWidget.cpp @@ -81,6 +81,7 @@ void GlyphMapWidget::set_active_glyph(int glyph, ShouldResetSelection should_res Gfx::IntRect GlyphMapWidget::get_outer_rect(int glyph) const { + glyph -= m_active_range.first; int row = glyph / columns(); int column = glyph % columns(); return Gfx::IntRect { @@ -110,8 +111,10 @@ void GlyphMapWidget::paint_event(PaintEvent& event) int scroll_steps = vertical_scrollbar().value() / vertical_scrollbar().step(); int first_visible_glyph = scroll_steps * columns(); + int range_offset = m_active_range.first; + int last_glyph = m_active_range.last + 1; - for (int glyph = first_visible_glyph; glyph <= first_visible_glyph + m_visible_glyphs && glyph < m_glyph_count; ++glyph) { + for (int glyph = first_visible_glyph + range_offset; glyph <= first_visible_glyph + m_visible_glyphs + range_offset && glyph < last_glyph; ++glyph) { Gfx::IntRect outer_rect = get_outer_rect(glyph); Gfx::IntRect inner_rect( outer_rect.x() + m_horizontal_spacing / 2, @@ -141,8 +144,8 @@ Optional<int> GlyphMapWidget::glyph_at_position(Gfx::IntPoint position) const auto map_position = position - map_offset; auto col = (map_position.x() - 1) / ((font().max_glyph_width() + m_horizontal_spacing)); auto row = (map_position.y() - 1) / ((font().glyph_height() + m_vertical_spacing)); - auto glyph = row * columns() + col; - if (row >= 0 && row < rows() && col >= 0 && col < columns() && glyph < m_glyph_count) + auto glyph = row * columns() + col + m_active_range.first; + if (row >= 0 && row < rows() && col >= 0 && col < columns() && glyph < m_glyph_count + m_active_range.first) return glyph; return {}; @@ -208,13 +211,15 @@ void GlyphMapWidget::keydown_event(KeyEvent& event) { Frame::keydown_event(event); + int range_offset = m_active_range.first; + if (!event.ctrl() && !event.shift()) { m_selection.set_size(1); m_selection.set_start(m_active_glyph); } if (event.key() == KeyCode::Key_Up) { - if (m_selection.start() >= m_columns) { + if (m_selection.start() - range_offset >= m_columns) { if (event.shift()) m_selection.resize_by(-m_columns); else @@ -225,7 +230,7 @@ void GlyphMapWidget::keydown_event(KeyEvent& event) } } if (event.key() == KeyCode::Key_Down) { - if (m_selection.start() < m_glyph_count - m_columns) { + if (m_selection.start() < m_glyph_count + range_offset - m_columns) { if (event.shift()) m_selection.resize_by(m_columns); else @@ -236,7 +241,7 @@ void GlyphMapWidget::keydown_event(KeyEvent& event) } } if (event.key() == KeyCode::Key_Left) { - if (m_selection.start() > 0) { + if (m_selection.start() > range_offset) { if (event.shift()) m_selection.resize_by(-1); else @@ -247,7 +252,7 @@ void GlyphMapWidget::keydown_event(KeyEvent& event) } } if (event.key() == KeyCode::Key_Right) { - if (m_selection.start() < m_glyph_count - 1) { + if (m_selection.start() < m_glyph_count + range_offset - 1) { if (event.shift()) m_selection.resize_by(1); else @@ -260,24 +265,24 @@ void GlyphMapWidget::keydown_event(KeyEvent& event) // FIXME: Support selection for these. if (event.ctrl() && event.key() == KeyCode::Key_Home) { - set_active_glyph(0); + set_active_glyph(m_active_range.first); scroll_to_glyph(m_active_glyph); return; } if (event.ctrl() && event.key() == KeyCode::Key_End) { - set_active_glyph(m_glyph_count - 1); + set_active_glyph(m_active_range.last); scroll_to_glyph(m_active_glyph); return; } if (!event.ctrl() && event.key() == KeyCode::Key_Home) { - set_active_glyph(m_active_glyph / m_columns * m_columns); + auto start_of_row = (m_active_glyph - range_offset) / m_columns * m_columns; + set_active_glyph(start_of_row + range_offset); return; } if (!event.ctrl() && event.key() == KeyCode::Key_End) { - int new_selection = m_active_glyph / m_columns * m_columns + (m_columns - 1); - int max = m_glyph_count - 1; - new_selection = clamp(new_selection, 0, max); - set_active_glyph(new_selection); + auto end_of_row = (m_active_glyph - range_offset) / m_columns * m_columns + (m_columns - 1); + end_of_row = clamp(end_of_row + range_offset, m_active_range.first, m_active_range.last); + set_active_glyph(end_of_row); return; } } @@ -290,6 +295,7 @@ void GlyphMapWidget::did_change_font() void GlyphMapWidget::scroll_to_glyph(int glyph) { + glyph -= m_active_range.first; int row = glyph / columns(); int column = glyph % columns(); auto scroll_rect = Gfx::IntRect { @@ -304,11 +310,13 @@ void GlyphMapWidget::scroll_to_glyph(int glyph) void GlyphMapWidget::select_previous_existing_glyph() { bool search_wrapped = false; + int first_glyph = m_active_range.first; + int last_glyph = m_active_range.last; for (int i = active_glyph() - 1;; --i) { - if (i < 0 && !search_wrapped) { - i = 0x10FFFF; + if (i < first_glyph && !search_wrapped) { + i = last_glyph; search_wrapped = true; - } else if (i < 0 && search_wrapped) { + } else if (i < first_glyph && search_wrapped) { break; } if (font().contains_glyph(i)) { @@ -323,11 +331,13 @@ void GlyphMapWidget::select_previous_existing_glyph() void GlyphMapWidget::select_next_existing_glyph() { bool search_wrapped = false; + int first_glyph = m_active_range.first; + int last_glyph = m_active_range.last; for (int i = active_glyph() + 1;; ++i) { - if (i > 0x10FFFF && !search_wrapped) { - i = 0; + if (i > last_glyph && !search_wrapped) { + i = first_glyph; search_wrapped = true; - } else if (i > 0x10FFFF && search_wrapped) { + } else if (i > last_glyph && search_wrapped) { break; } if (font().contains_glyph(i)) { @@ -355,4 +365,15 @@ void GlyphMapWidget::recalculate_content_size() scroll_to_glyph(m_active_glyph); } +void GlyphMapWidget::set_active_range(Unicode::CodePointRange range) +{ + if (m_active_range.first == range.first && m_active_range.last == range.last) + return; + m_active_range = range; + m_glyph_count = range.last - range.first + 1; + set_active_glyph(range.first); + recalculate_content_size(); + update(); +} + } diff --git a/Userland/Libraries/LibGUI/GlyphMapWidget.h b/Userland/Libraries/LibGUI/GlyphMapWidget.h index 518c616aa7..f2295d95fe 100644 --- a/Userland/Libraries/LibGUI/GlyphMapWidget.h +++ b/Userland/Libraries/LibGUI/GlyphMapWidget.h @@ -10,6 +10,7 @@ #include <LibGUI/AbstractScrollableWidget.h> #include <LibGUI/TextRange.h> #include <LibGfx/BitmapFont.h> +#include <LibUnicode/CharacterTypes.h> namespace GUI { @@ -50,6 +51,7 @@ public: No }; + void set_active_range(Unicode::CodePointRange); void set_active_glyph(int, ShouldResetSelection = ShouldResetSelection::Yes); void clear_selection() { m_selection.set_size(0); } void scroll_to_glyph(int); @@ -89,6 +91,7 @@ private: int m_active_glyph { 0 }; int m_visible_glyphs { 0 }; bool m_in_drag_select { false }; + Unicode::CodePointRange m_active_range { 0x0000, 0x10FFFF }; }; } |