WindowServer: Add basic search functionality in menus

Perform a case insensitive search through the current menu. Jump to the
first item matching all keys in the current search. Backspace can clear
the current search, and the search will timeout after 3 seconds.
This commit is contained in:
Shannon Booth 2020-05-09 15:57:25 +12:00 committed by Andreas Kling
parent d5c40899cb
commit eb43e2d544
2 changed files with 31 additions and 0 deletions

View file

@ -42,6 +42,7 @@
namespace WindowServer {
static MenuManager* s_the;
static constexpr int s_search_timeout = 3000;
MenuManager& MenuManager::the()
{
@ -59,6 +60,10 @@ MenuManager::MenuManager()
m_window = Window::construct(*this, WindowType::Menubar);
m_window->set_rect(menubar_rect());
m_search_timer = Core::Timer::create_single_shot(0, [this] {
m_current_search.clear();
});
}
MenuManager::~MenuManager()
@ -133,6 +138,26 @@ void MenuManager::event(Core::Event& event)
return;
}
if (key_event.key() == Key_Backspace) {
m_current_search.clear();
return;
}
if (m_current_menu && event.type() == Event::KeyDown
&& ((key_event.key() >= Key_A && key_event.key() <= Key_Z)
|| (key_event.key() >= Key_0 && key_event.key() <= Key_9))) {
m_current_search.append(key_event.character());
m_search_timer->restart(s_search_timeout);
for (int i = 0; i < m_current_menu->item_count(); ++i) {
auto text = m_current_menu->item(i).text();
if (text.to_lowercase().starts_with(m_current_search.to_string().to_lowercase())) {
m_current_menu->set_hovered_item(i);
return;
}
}
return;
}
if (event.type() == Event::KeyDown) {
if (key_event.key() == Key_Left) {
@ -285,6 +310,7 @@ void MenuManager::close_everyone()
menu->clear_hovered_item();
}
m_open_menu_stack.clear();
m_current_search.clear();
m_current_menu = nullptr;
refresh();
}
@ -382,6 +408,7 @@ void MenuManager::set_current_menu(Menu* menu)
return;
}
m_current_search.clear();
m_current_menu = menu->make_weak_ptr();
}

View file

@ -30,7 +30,9 @@
#include "MenuBar.h"
#include "Window.h"
#include <AK/HashMap.h>
#include <AK/StringBuilder.h>
#include <LibCore/Object.h>
#include <LibCore/Timer.h>
namespace WindowServer {
@ -110,6 +112,8 @@ private:
WeakPtr<Menu> m_current_menu;
Vector<WeakPtr<Menu>> m_open_menu_stack;
RefPtr<Core::Timer> m_search_timer;
StringBuilder m_current_search;
WeakPtr<Menu> m_system_menu;
bool m_needs_window_resize { false };