mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-09 01:20:46 +00:00
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:
parent
d5c40899cb
commit
eb43e2d544
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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 };
|
||||
|
|
Loading…
Reference in a new issue