Forráskód Böngészése

LibGUI: Add a ThemeChange event

Oriko 5 éve
szülő
commit
2a32330257

+ 10 - 1
Libraries/LibGUI/Event.h

@@ -28,9 +28,9 @@
 
 #include <Kernel/KeyCode.h>
 #include <LibCore/Event.h>
+#include <LibGUI/WindowType.h>
 #include <LibGfx/Point.h>
 #include <LibGfx/Rect.h>
-#include <LibGUI/WindowType.h>
 
 namespace GUI {
 
@@ -62,6 +62,7 @@ public:
         EnabledChange,
         DragMove,
         Drop,
+        ThemeChange,
 
         __Begin_WM_Events,
         WM_WindowRemoved,
@@ -340,4 +341,12 @@ private:
     NonnullRefPtr<Core::MimeData> m_mime_data;
 };
 
+class ThemeChangeEvent final : public Event {
+public:
+    ThemeChangeEvent()
+        : Event(Type::ThemeChange)
+    {
+    }
+};
+
 }

+ 7 - 0
Libraries/LibGUI/TextEditor.cpp

@@ -1279,6 +1279,13 @@ void TextEditor::resize_event(ResizeEvent& event)
     recompute_all_visual_lines();
 }
 
+void TextEditor::theme_change_event(ThemeChangeEvent& event)
+{
+    ScrollableWidget::theme_change_event(event);
+    if (m_highlighter)
+        m_highlighter->rehighlight(palette());
+}
+
 void TextEditor::set_selection(const TextRange& selection)
 {
     if (m_selection == selection)

+ 1 - 0
Libraries/LibGUI/TextEditor.h

@@ -148,6 +148,7 @@ protected:
     virtual void leave_event(Core::Event&) override;
     virtual void context_menu_event(ContextMenuEvent&) override;
     virtual void resize_event(ResizeEvent&) override;
+    virtual void theme_change_event(ThemeChangeEvent&) override;
     virtual void cursor_did_change() {}
 
     TextPosition text_position_at(const Gfx::Point&) const;

+ 6 - 0
Libraries/LibGUI/Widget.cpp

@@ -206,6 +206,8 @@ void Widget::event(Core::Event& event)
         return drag_move_event(static_cast<DragEvent&>(event));
     case Event::Drop:
         return drop_event(static_cast<DropEvent&>(event));
+    case Event::ThemeChange:
+        return theme_change_event(static_cast<ThemeChangeEvent&>(event));
     case Event::Enter:
         return handle_enter_event(event);
     case Event::Leave:
@@ -417,6 +419,10 @@ void Widget::drop_event(DropEvent& event)
     event.ignore();
 }
 
+void Widget::theme_change_event(ThemeChangeEvent&)
+{
+}
+
 void Widget::update()
 {
     if (rect().is_empty())

+ 1 - 0
Libraries/LibGUI/Widget.h

@@ -292,6 +292,7 @@ protected:
     virtual void change_event(Event&);
     virtual void drag_move_event(DragEvent&);
     virtual void drop_event(DropEvent&);
+    virtual void theme_change_event(ThemeChangeEvent&);
 
     virtual void did_begin_inspection() override;
     virtual void did_end_inspection() override;

+ 24 - 0
Libraries/LibGUI/Window.cpp

@@ -334,6 +334,22 @@ void Window::event(Core::Event& event)
         return result.widget->dispatch_event(*local_event, this);
     }
 
+    if (event.type() == Event::ThemeChange) {
+        if (!m_main_widget)
+            return;
+        auto theme_event = static_cast<ThemeChangeEvent&>(event);
+        auto dispatch_theme_change = [&](auto& widget, auto recursive) {
+            widget.dispatch_event(theme_event, this);
+            widget.for_each_child_widget([&](auto& widget) -> IterationDecision {
+                widget.dispatch_event(theme_event, this);
+                recursive(widget, recursive);
+                return IterationDecision::Continue;
+            });
+        };
+        dispatch_theme_change(*m_main_widget.ptr(), dispatch_theme_change);
+        return;
+    }
+
     Core::Object::event(event);
 }
 
@@ -635,6 +651,14 @@ void Window::schedule_relayout()
     });
 }
 
+void Window::for_each_window(Badge<WindowServerConnection>, Function<void(Window&)> callback)
+{
+    for (auto& e : *reified_windows) {
+        ASSERT(e.value);
+        callback(*e.value);
+    }
+}
+
 void Window::update_all_windows(Badge<WindowServerConnection>)
 {
     for (auto& e : *reified_windows) {

+ 1 - 0
Libraries/LibGUI/Window.h

@@ -172,6 +172,7 @@ public:
 
     void schedule_relayout();
 
+    static void for_each_window(Badge<WindowServerConnection>, Function<void(Window&)>);
     static void update_all_windows(Badge<WindowServerConnection>);
     void notify_state_changed(Badge<WindowServerConnection>, bool minimized, bool occluded);
 

+ 3 - 0
Libraries/LibGUI/WindowServerConnection.cpp

@@ -73,6 +73,9 @@ void WindowServerConnection::handle(const Messages::WindowClient::UpdateSystemTh
 {
     set_system_theme_from_shbuf_id(message.system_theme_buffer_id());
     Window::update_all_windows({});
+    Window::for_each_window({}, [](auto& window) {
+        Core::EventLoop::current().post_event(window, make<ThemeChangeEvent>());
+    });
 }
 
 void WindowServerConnection::handle(const Messages::WindowClient::Paint& message)