diff --git a/Userland/Libraries/LibGUI/CMakeLists.txt b/Userland/Libraries/LibGUI/CMakeLists.txt index 5ebed7250a..367f41cdfc 100644 --- a/Userland/Libraries/LibGUI/CMakeLists.txt +++ b/Userland/Libraries/LibGUI/CMakeLists.txt @@ -136,4 +136,4 @@ set(GENERATED_SOURCES ) serenity_lib(LibGUI gui) -target_link_libraries(LibGUI LibCore LibGfx LibIPC LibThreading LibRegex LibSyntax LibConfig) +target_link_libraries(LibGUI LibCore LibGfx LibIPC LibThreading LibRegex LibSyntax LibConfig LibUnicode) diff --git a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp index 5ae43d410d..9f3d3487b2 100644 --- a/Userland/Libraries/LibGUI/EmojiInputDialog.cpp +++ b/Userland/Libraries/LibGUI/EmojiInputDialog.cpp @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include namespace GUI { @@ -32,6 +34,7 @@ EmojiInputDialog::EmojiInputDialog(Window* parent_window) resize(400, 300); auto& scrollable_container = *main_widget.find_descendant_of_type_named("scrollable_container"sv); + m_search_box = main_widget.find_descendant_of_type_named("search_box"sv); m_emojis_widget = main_widget.find_descendant_of_type_named("emojis"sv); m_emojis = supported_emoji(); @@ -42,6 +45,10 @@ EmojiInputDialog::EmojiInputDialog(Window* parent_window) if (!is_active_window) close(); }; + + m_search_box->on_change = [this]() { + update_displayed_emoji(); + }; } auto EmojiInputDialog::supported_emoji() -> Vector @@ -63,6 +70,7 @@ auto EmojiInputDialog::supported_emoji() -> Vector continue; u32 code_point = strtoul(basename.to_string().characters() + 2, nullptr, 16); + auto name = Unicode::code_point_display_name(code_point); // FIXME: Also emit U+FE0F for single code point emojis, currently // they get shown as text glyphs if available. @@ -82,7 +90,7 @@ auto EmojiInputDialog::supported_emoji() -> Vector done(ExecResult::OK); }; - code_points.empend(code_point, move(button)); + code_points.empend(code_point, move(name), move(button)); } return code_points; @@ -93,20 +101,32 @@ void EmojiInputDialog::update_displayed_emoji() ScopeGuard guard { [&] { m_emojis_widget->set_updates_enabled(true); } }; m_emojis_widget->set_updates_enabled(false); + m_emojis_widget->remove_all_children(); + constexpr size_t columns = 18; size_t rows = ceil_div(m_emojis.size(), columns); size_t index = 0; for (size_t row = 0; row < rows && index < m_emojis.size(); ++row) { auto& horizontal_container = m_emojis_widget->add(); + horizontal_container.set_preferred_height(SpecialDimension::Fit); + auto& horizontal_layout = horizontal_container.set_layout(); horizontal_layout.set_spacing(0); + for (size_t column = 0; column < columns; ++column) { - if (index < m_emojis.size()) { + bool found_match = false; + + while (!found_match && (index < m_emojis.size())) { auto& emoji = m_emojis[index++]; - horizontal_container.add_child(*emoji.button); - } else { - horizontal_container.add(); + + if (emoji.name.has_value()) + found_match = emoji.name->contains(m_search_box->text(), CaseSensitivity::CaseInsensitive); + else + found_match = m_search_box->text().is_empty(); + + if (found_match) + horizontal_container.add_child(*emoji.button); } } } diff --git a/Userland/Libraries/LibGUI/EmojiInputDialog.gml b/Userland/Libraries/LibGUI/EmojiInputDialog.gml index 132e54880b..6da0d01301 100644 --- a/Userland/Libraries/LibGUI/EmojiInputDialog.gml +++ b/Userland/Libraries/LibGUI/EmojiInputDialog.gml @@ -6,6 +6,11 @@ margins: [4] } + @GUI::TextBox { + name: "search_box" + fixed_height: 22 + } + @GUI::ScrollableContainerWidget { name: "scrollable_container" content_widget: @GUI::Widget { diff --git a/Userland/Libraries/LibGUI/EmojiInputDialog.h b/Userland/Libraries/LibGUI/EmojiInputDialog.h index acf8981270..5374332325 100644 --- a/Userland/Libraries/LibGUI/EmojiInputDialog.h +++ b/Userland/Libraries/LibGUI/EmojiInputDialog.h @@ -15,6 +15,7 @@ class EmojiInputDialog final : public Dialog { struct Emoji { u32 code_point { 0 }; + Optional name; RefPtr