diff options
Diffstat (limited to 'Libraries/LibGUI')
-rw-r--r-- | Libraries/LibGUI/Menu.cpp | 26 | ||||
-rw-r--r-- | Libraries/LibGUI/Menu.h | 15 | ||||
-rw-r--r-- | Libraries/LibGUI/MenuItem.cpp | 11 | ||||
-rw-r--r-- | Libraries/LibGUI/MenuItem.h | 6 |
4 files changed, 39 insertions, 19 deletions
diff --git a/Libraries/LibGUI/Menu.cpp b/Libraries/LibGUI/Menu.cpp index ac3516b08a..77623dd267 100644 --- a/Libraries/LibGUI/Menu.cpp +++ b/Libraries/LibGUI/Menu.cpp @@ -83,15 +83,15 @@ void Menu::add_separator() m_items.append(make<MenuItem>(m_menu_id, MenuItem::Type::Separator)); } -void Menu::realize_if_needed() +void Menu::realize_if_needed(const RefPtr<Action>& default_action) { - if (m_menu_id == -1) - realize_menu(); + if (m_menu_id == -1 || m_last_default_action.ptr() != default_action) + realize_menu(default_action); } -void Menu::popup(const Gfx::IntPoint& screen_position) +void Menu::popup(const Gfx::IntPoint& screen_position, const RefPtr<Action>& default_action) { - realize_if_needed(); + realize_if_needed(default_action); WindowServerConnection::the().post_message(Messages::WindowServer::PopupMenu(m_menu_id, screen_position)); } @@ -102,7 +102,7 @@ void Menu::dismiss() WindowServerConnection::the().post_message(Messages::WindowServer::DismissMenu(m_menu_id)); } -int Menu::realize_menu() +int Menu::realize_menu(RefPtr<Action> default_action) { m_menu_id = WindowServerConnection::the().send_sync<Messages::WindowServer::CreateMenu>(m_name)->menu_id(); @@ -120,8 +120,8 @@ int Menu::realize_menu() } if (item.type() == MenuItem::Type::Submenu) { auto& submenu = *item.submenu(); - submenu.realize_if_needed(); - WindowServerConnection::the().send_sync<Messages::WindowServer::AddMenuItem>(m_menu_id, i, submenu.menu_id(), submenu.name(), true, false, false, "", -1, false); + submenu.realize_if_needed(default_action); + WindowServerConnection::the().send_sync<Messages::WindowServer::AddMenuItem>(m_menu_id, i, submenu.menu_id(), submenu.name(), true, false, false, false, "", -1, false); continue; } if (item.type() == MenuItem::Type::Action) { @@ -143,10 +143,12 @@ int Menu::realize_menu() } auto shortcut_text = action.shortcut().is_valid() ? action.shortcut().to_string() : String(); bool exclusive = action.group() && action.group()->is_exclusive() && action.is_checkable(); - WindowServerConnection::the().send_sync<Messages::WindowServer::AddMenuItem>(m_menu_id, i, -1, action.text(), action.is_enabled(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, shortcut_text, icon_buffer_id, exclusive); + bool is_default = (default_action.ptr() == &action); + WindowServerConnection::the().send_sync<Messages::WindowServer::AddMenuItem>(m_menu_id, i, -1, action.text(), action.is_enabled(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, is_default, shortcut_text, icon_buffer_id, exclusive); } } all_menus().set(m_menu_id, this); + m_last_default_action = default_action ? default_action->make_weak_ptr() : nullptr; return m_menu_id; } @@ -159,6 +161,12 @@ void Menu::unrealize_menu() m_menu_id = 0; } +void Menu::realize_menu_if_needed() +{ + if (menu_id() == -1) + realize_menu(); +} + Action* Menu::action_at(size_t index) { if (index >= m_items.size()) diff --git a/Libraries/LibGUI/Menu.h b/Libraries/LibGUI/Menu.h index 2b56e04d35..211e174798 100644 --- a/Libraries/LibGUI/Menu.h +++ b/Libraries/LibGUI/Menu.h @@ -27,7 +27,9 @@ #pragma once #include <AK/NonnullOwnPtrVector.h> +#include <AK/WeakPtr.h> #include <LibCore/Object.h> +#include <LibGUI/Action.h> #include <LibGUI/Forward.h> #include <LibGfx/Forward.h> @@ -39,11 +41,7 @@ public: explicit Menu(const StringView& name = ""); virtual ~Menu() override; - void realize_menu_if_needed() - { - if (menu_id() == -1) - realize_menu(); - } + void realize_menu_if_needed(); static Menu* from_menu_id(int); int menu_id() const { return m_menu_id; } @@ -56,19 +54,20 @@ public: void add_separator(); Menu& add_submenu(const String& name); - void popup(const Gfx::IntPoint& screen_position); + void popup(const Gfx::IntPoint& screen_position, const RefPtr<Action>& default_action = nullptr); void dismiss(); private: friend class MenuBar; - int realize_menu(); + int realize_menu(RefPtr<Action> default_action = nullptr); void unrealize_menu(); - void realize_if_needed(); + void realize_if_needed(const RefPtr<Action>& default_action); int m_menu_id { -1 }; String m_name; NonnullOwnPtrVector<MenuItem> m_items; + WeakPtr<Action> m_last_default_action; }; } diff --git a/Libraries/LibGUI/MenuItem.cpp b/Libraries/LibGUI/MenuItem.cpp index cc6aa81b22..8c6e5a92ec 100644 --- a/Libraries/LibGUI/MenuItem.cpp +++ b/Libraries/LibGUI/MenuItem.cpp @@ -79,13 +79,22 @@ void MenuItem::set_checked(bool checked) update_window_server(); } +void MenuItem::set_default(bool is_default) +{ + ASSERT(is_checkable()); + if (m_default == is_default) + return; + m_default = is_default; + update_window_server(); +} + void MenuItem::update_window_server() { if (m_menu_id < 0) return; auto& action = *m_action; auto shortcut_text = action.shortcut().is_valid() ? action.shortcut().to_string() : String(); - WindowServerConnection::the().send_sync<Messages::WindowServer::UpdateMenuItem>(m_menu_id, m_identifier, -1, action.text(), action.is_enabled(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, shortcut_text); + WindowServerConnection::the().send_sync<Messages::WindowServer::UpdateMenuItem>(m_menu_id, m_identifier, -1, action.text(), action.is_enabled(), action.is_checkable(), action.is_checkable() ? action.is_checked() : false, m_default, shortcut_text); } void MenuItem::set_menu_id(Badge<Menu>, unsigned int menu_id) diff --git a/Libraries/LibGUI/MenuItem.h b/Libraries/LibGUI/MenuItem.h index 871690a805..1441061661 100644 --- a/Libraries/LibGUI/MenuItem.h +++ b/Libraries/LibGUI/MenuItem.h @@ -47,7 +47,7 @@ public: ~MenuItem(); Type type() const { return m_type; } - String text() const; + const Action* action() const { return m_action.ptr(); } Action* action() { return m_action.ptr(); } unsigned identifier() const { return m_identifier; } @@ -64,6 +64,9 @@ public: bool is_enabled() const { return m_enabled; } void set_enabled(bool); + bool is_default() const { return m_default; } + void set_default(bool); + void set_menu_id(Badge<Menu>, unsigned menu_id); void set_identifier(Badge<Menu>, unsigned identifier); @@ -76,6 +79,7 @@ private: bool m_enabled { true }; bool m_checkable { false }; bool m_checked { false }; + bool m_default { false }; RefPtr<Action> m_action; RefPtr<Menu> m_submenu; }; |