1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 08:58:11 +00:00

WindowServer+LibGUI: Add support for nested menus

It's now possible to add a GMenu as a submenu of another GMenu.
Simply use the GMenu::add_submenu(NonnullOwnPtr<GMenu>) API :^)

The WindowServer now keeps track of a stack of open menus rather than
just one "current menu". This code needs a bit more work, but the basic
functionality is now here!
This commit is contained in:
Andreas Kling 2019-08-28 21:11:53 +02:00
parent d3ebd8897f
commit 63e6b09816
16 changed files with 177 additions and 12 deletions

View file

@ -211,14 +211,22 @@ int WSWindowManager::menubar_menu_margin() const
return 16;
}
void WSWindowManager::set_current_menu(WSMenu* menu)
void WSWindowManager::set_current_menu(WSMenu* menu, bool is_submenu)
{
if (m_current_menu == menu)
return;
if (m_current_menu)
if (!is_submenu && m_current_menu)
m_current_menu->close();
if (menu)
m_current_menu = menu->make_weak_ptr();
if (!is_submenu) {
m_menu_manager.open_menu_stack().clear();
if (menu)
m_menu_manager.open_menu_stack().append(menu->make_weak_ptr());
} else {
m_menu_manager.open_menu_stack().append(menu->make_weak_ptr());
}
}
void WSWindowManager::set_current_menubar(WSMenuBar* menubar)
@ -393,6 +401,11 @@ void WSWindowManager::close_current_menu()
if (m_current_menu && m_current_menu->menu_window())
m_current_menu->menu_window()->set_visible(false);
m_current_menu = nullptr;
for (auto& menu : m_menu_manager.open_menu_stack()) {
if (menu)
menu->menu_window()->set_visible(false);
}
m_menu_manager.open_menu_stack().clear();
m_menu_manager.refresh();
}
@ -696,6 +709,18 @@ void WSWindowManager::process_mouse_event(WSMouseEvent& event, WSWindow*& hovere
m_current_menu->clear_hovered_item();
if (event.type() == WSEvent::MouseDown || event.type() == WSEvent::MouseUp)
close_current_menu();
if (event.type() == WSEvent::MouseMove) {
for (auto& menu : m_menu_manager.open_menu_stack()) {
if (!menu)
continue;
if (!menu->menu_window()->rect().contains(event.position()))
continue;
hovered_window = menu->menu_window();
auto translated_event = event.translated(-menu->menu_window()->position());
deliver_mouse_event(*menu->menu_window(), translated_event);
break;
}
}
} else {
hovered_window = &window;
auto translated_event = event.translated(-window.position());