diff options
-rw-r--r-- | Applications/Terminal/Terminal.cpp | 8 | ||||
-rw-r--r-- | Applications/Terminal/Terminal.h | 1 | ||||
-rw-r--r-- | Applications/Terminal/main.cpp | 20 | ||||
-rw-r--r-- | Kernel/GUITypes.h | 5 | ||||
-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 | ||||
-rw-r--r-- | WindowServer/WSMenu.cpp | 11 |
10 files changed, 93 insertions, 3 deletions
diff --git a/Applications/Terminal/Terminal.cpp b/Applications/Terminal/Terminal.cpp index 3f68b193b8..3e169505f4 100644 --- a/Applications/Terminal/Terminal.cpp +++ b/Applications/Terminal/Terminal.cpp @@ -749,3 +749,11 @@ void Terminal::flush_dirty_lines() } update(rect); } + +void Terminal::force_repaint() +{ + for (int i = 0; i < m_rows; ++i) + line(i).dirty = true; + m_need_full_flush = true; + update(); +} diff --git a/Applications/Terminal/Terminal.h b/Applications/Terminal/Terminal.h index a3a4ac018e..298596a479 100644 --- a/Applications/Terminal/Terminal.h +++ b/Applications/Terminal/Terminal.h @@ -19,6 +19,7 @@ public: void on_char(byte); void flush_dirty_lines(); + void force_repaint(); private: virtual void event(GEvent&) override; diff --git a/Applications/Terminal/main.cpp b/Applications/Terminal/main.cpp index 50e4a7010b..c539a882f2 100644 --- a/Applications/Terminal/main.cpp +++ b/Applications/Terminal/main.cpp @@ -80,9 +80,23 @@ int main(int argc, char** argv) menubar->add_menu(move(app_menu)); auto font_menu = make<GMenu>("Font"); - font_menu->add_item(30, "Liza 8x10"); - font_menu->add_item(31, "LizaRegular 8x10"); - font_menu->add_item(32, "LizaBold 8x10"); + font_menu->add_item(30, "Liza Thin"); + font_menu->add_item(31, "Liza Regular"); + font_menu->add_item(32, "Liza Bold"); + font_menu->on_item_activation = [&terminal] (unsigned identifier) { + switch (identifier) { + case 30: + terminal.set_font(Font::load_from_file("/res/fonts/Liza8x10.font")); + break; + case 31: + terminal.set_font(Font::load_from_file("/res/fonts/LizaRegular8x10.font")); + break; + case 32: + terminal.set_font(Font::load_from_file("/res/fonts/LizaBold8x10.font")); + break; + } + terminal.force_repaint(); + }; menubar->add_menu(move(font_menu)); auto help_menu = make<GMenu>("Help"); diff --git a/Kernel/GUITypes.h b/Kernel/GUITypes.h index 61aa6587eb..263cca0145 100644 --- a/Kernel/GUITypes.h +++ b/Kernel/GUITypes.h @@ -67,6 +67,7 @@ struct GUI_Event { WindowActivated, WindowDeactivated, WindowCloseRequest, + MenuItemActivated, }; Type type { Invalid }; int window_id { -1 }; @@ -88,6 +89,10 @@ struct GUI_Event { bool alt : 1; bool shift : 1; } key; + struct { + int menu_id; + unsigned identifier; + } menu; }; }; 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) diff --git a/WindowServer/WSMenu.cpp b/WindowServer/WSMenu.cpp index e8bd9361ae..0e93ab893d 100644 --- a/WindowServer/WSMenu.cpp +++ b/WindowServer/WSMenu.cpp @@ -137,7 +137,18 @@ void WSMenu::did_activate(WSMenuItem& item) { if (on_item_activation) on_item_activation(item); + close(); + + GUI_Event gui_event; + gui_event.type = GUI_Event::Type::MenuItemActivated; + gui_event.menu.menu_id = m_menu_id; + gui_event.menu.identifier = item.identifier(); + + if (!m_process) + return; + LOCKER(m_process->gui_events_lock()); + m_process->gui_events().append(move(gui_event)); } WSMenuItem* WSMenu::item_at(const Point& position) |