diff options
author | Andreas Kling <awesomekling@gmail.com> | 2019-02-12 10:08:35 +0100 |
---|---|---|
committer | Andreas Kling <awesomekling@gmail.com> | 2019-02-12 10:08:35 +0100 |
commit | db98327bdc24b3306961cde5036ea73e766008c3 (patch) | |
tree | 3980dd4690778151318bc28e7d5ae85aeecda28e /LibGUI | |
parent | 9c1c8854831005cee601d73bba3a0737f350c236 (diff) | |
download | serenity-db98327bdc24b3306961cde5036ea73e766008c3.zip |
Plumb menu item activation events from WindowServer to clients.
GMenu now has an "on_item_activation" callback that fires whenever one
of its items are activated. The menu item identifier is used to distinguish
between items.
Use this to implement font switching in Terminal. :^)
Diffstat (limited to 'LibGUI')
-rw-r--r-- | LibGUI/GEventLoop.cpp | 25 | ||||
-rw-r--r-- | LibGUI/GEventLoop.h | 1 | ||||
-rw-r--r-- | LibGUI/GMenu.cpp | 19 | ||||
-rw-r--r-- | LibGUI/GMenu.h | 5 | ||||
-rw-r--r-- | LibGUI/GWidget.cpp | 1 |
5 files changed, 51 insertions, 0 deletions
diff --git a/LibGUI/GEventLoop.cpp b/LibGUI/GEventLoop.cpp index e3db469230..70f38eb9ea 100644 --- a/LibGUI/GEventLoop.cpp +++ b/LibGUI/GEventLoop.cpp @@ -3,6 +3,7 @@ #include "GObject.h" #include "GWindow.h" #include <LibGUI/GNotifier.h> +#include <LibGUI/GMenu.h> #include <LibC/unistd.h> #include <LibC/stdio.h> #include <LibC/fcntl.h> @@ -147,6 +148,21 @@ void GEventLoop::handle_mouse_event(const GUI_Event& event, GWindow& window) post_event(&window, make<GMouseEvent>(type, event.mouse.position, event.mouse.buttons, button)); } +void GEventLoop::handle_menu_event(const GUI_Event& event) +{ + if (event.type == GUI_Event::Type::MenuItemActivated) { + auto* menu = GMenu::from_menu_id(event.menu.menu_id); + if (!menu) { + dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id); + return; + } + if (menu->on_item_activation) + menu->on_item_activation(event.menu.identifier); + return; + } + ASSERT_NOT_REACHED(); +} + void GEventLoop::wait_for_event() { fd_set rfds; @@ -219,6 +235,13 @@ void GEventLoop::wait_for_event() if (nread == 0) break; assert(nread == sizeof(event)); + + switch (event.type) { + case GUI_Event::MenuItemActivated: + handle_menu_event(event); + continue; + } + auto* window = GWindow::from_window_id(event.window_id); if (!window) { dbgprintf("GEventLoop received event for invalid window ID %d\n", event.window_id); @@ -244,6 +267,8 @@ void GEventLoop::wait_for_event() case GUI_Event::Type::KeyUp: handle_key_event(event, *window); break; + default: + break; } } } diff --git a/LibGUI/GEventLoop.h b/LibGUI/GEventLoop.h index 02d1066770..e68df0dc10 100644 --- a/LibGUI/GEventLoop.h +++ b/LibGUI/GEventLoop.h @@ -41,6 +41,7 @@ private: void handle_key_event(const GUI_Event&, GWindow&); void handle_window_activation_event(const GUI_Event&, GWindow&); void handle_window_close_request_event(const GUI_Event&, GWindow&); + void handle_menu_event(const GUI_Event&); void get_next_timer_expiration(timeval&); diff --git a/LibGUI/GMenu.cpp b/LibGUI/GMenu.cpp index de56467485..923fb784f9 100644 --- a/LibGUI/GMenu.cpp +++ b/LibGUI/GMenu.cpp @@ -1,5 +1,22 @@ #include <LibGUI/GMenu.h> #include <LibC/gui.h> +#include <AK/HashMap.h> + +static HashMap<int, GMenu*>& all_menus() +{ + static HashMap<int, GMenu*>* map; + if (!map) + map = new HashMap<int, GMenu*>(); + return *map; +} + +GMenu* GMenu::from_menu_id(int menu_id) +{ + auto it = all_menus().find(menu_id); + if (it == all_menus().end()) + return nullptr; + return (*it).value; +} GMenu::GMenu(const String& name) : m_name(name) @@ -9,6 +26,7 @@ GMenu::GMenu(const String& name) GMenu::~GMenu() { if (m_menu_id) { + all_menus().remove(m_menu_id); gui_menu_destroy(m_menu_id); m_menu_id = 0; } @@ -34,5 +52,6 @@ int GMenu::realize_menu() else if (item.type() == GMenuItem::Text) gui_menu_add_item(m_menu_id, item.identifier(), item.text().characters()); } + all_menus().set(m_menu_id, this); return m_menu_id; } diff --git a/LibGUI/GMenu.h b/LibGUI/GMenu.h index 5582049563..3eeed3527f 100644 --- a/LibGUI/GMenu.h +++ b/LibGUI/GMenu.h @@ -1,6 +1,7 @@ #pragma once #include <LibGUI/GMenuItem.h> +#include <AK/Function.h> #include <AK/Vector.h> class GMenu { @@ -8,9 +9,13 @@ public: explicit GMenu(const String& name); ~GMenu(); + static GMenu* from_menu_id(int); + void add_item(unsigned identifier, const String& text); void add_separator(); + Function<void(unsigned)> on_item_activation; + private: friend class GMenuBar; int menu_id() const { return m_menu_id; } diff --git a/LibGUI/GWidget.cpp b/LibGUI/GWidget.cpp index 9d05141f3d..58bdd25a59 100644 --- a/LibGUI/GWidget.cpp +++ b/LibGUI/GWidget.cpp @@ -234,6 +234,7 @@ void GWidget::set_font(RetainPtr<Font>&& font) m_font = Font::default_font(); else m_font = move(font); + update(); } void GWidget::set_global_cursor_tracking(bool enabled) |