mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-14 01:04:38 +03:00
LibGUI: Fix search highlighting so that it matches the search query
There is a bug in the "search by typing" feature of AbstractView, where the highlighted text shown in items' title won't match the search query if the search query contains whitespace. This commit fixes that bug. The bug is caused by a bad assumption made in AbstractView::draw_item_text about the Painter::draw_text API. Specifically that the function passed to it will be called for each code point of the string instead of for each drawable glyph. This is fixed by not relying on looking at the length of the highlight string, but instead looking at its content.
This commit is contained in:
parent
f115e44066
commit
258af88b29
Notes:
sideshowbarker
2024-07-17 05:23:40 +09:00
Author: https://github.com/adamjoer 🔰 Commit: https://github.com/SerenityOS/serenity/commit/258af88b29 Pull-request: https://github.com/SerenityOS/serenity/pull/20726
@ -721,31 +721,34 @@ void AbstractView::draw_item_text(Gfx::Painter& painter, ModelIndex const& index
|
||||
text_color = is_focused() ? palette().selection_text() : palette().inactive_selection_text();
|
||||
else
|
||||
text_color = index.data(ModelRole::ForegroundColor).to_color(palette().color(foreground_role()));
|
||||
|
||||
if (index == m_highlighted_search_index) {
|
||||
Utf8View searching_text(m_highlighted_search);
|
||||
auto searching_length = searching_text.length();
|
||||
if (searching_length > search_highlighting_offset)
|
||||
searching_length -= search_highlighting_offset;
|
||||
else if (search_highlighting_offset > 0)
|
||||
searching_length = 0;
|
||||
auto const byte_offset = search_highlighting_offset < m_highlighted_search.length() ? 0 : item_text.length();
|
||||
auto const byte_length = min(item_text.length() - byte_offset, m_highlighted_search.length() - search_highlighting_offset);
|
||||
Utf8View const searching_text(item_text.substring_view(byte_offset, byte_length));
|
||||
|
||||
// Highlight the text background first
|
||||
auto background_searching_length = searching_length;
|
||||
painter.draw_text([&](Gfx::FloatRect const& rect, Utf8CodePointIterator&) {
|
||||
if (background_searching_length > 0) {
|
||||
background_searching_length--;
|
||||
painter.fill_rect(rect.to_type<int>().inflated(0, 2), palette().highlight_searching());
|
||||
}
|
||||
},
|
||||
text_rect, item_text, font, alignment, elision);
|
||||
auto highlight_rect = text_rect.shrunken(0, text_rect.height() - font.pixel_size_rounded_up() - 2);
|
||||
highlight_rect.set_width((int)font.width(searching_text));
|
||||
|
||||
// If the text is center aligned the highlight rect needs to be shifted to the right so that the two line up
|
||||
if (alignment == Gfx::TextAlignment::Center)
|
||||
highlight_rect.translate_by((text_rect.width() - (int)font.width(item_text)) / 2, 0);
|
||||
|
||||
painter.fill_rect(highlight_rect, palette().highlight_searching());
|
||||
|
||||
// Then draw the text
|
||||
auto text_searching_length = searching_length;
|
||||
auto highlight_text_color = palette().highlight_searching_text();
|
||||
searching_length = searching_text.length();
|
||||
auto searching_text_it = searching_text.begin();
|
||||
while (searching_text_it != searching_text.end() && is_ascii_space(*searching_text_it))
|
||||
++searching_text_it;
|
||||
|
||||
auto const highlight_text_color = palette().highlight_searching_text();
|
||||
painter.draw_text([&](auto const& rect, Utf8CodePointIterator& it) {
|
||||
if (text_searching_length > 0) {
|
||||
text_searching_length--;
|
||||
if (searching_text_it != searching_text.end()) {
|
||||
do {
|
||||
++searching_text_it;
|
||||
} while (searching_text_it != searching_text.end() && is_ascii_space(*searching_text_it));
|
||||
|
||||
painter.draw_glyph_or_emoji(rect.location(), it, font, highlight_text_color);
|
||||
} else {
|
||||
painter.draw_glyph_or_emoji(rect.location(), it, font, text_color);
|
||||
|
Loading…
Reference in New Issue
Block a user