Преглед на файлове

Add a slight hover highlight to GButton and WSButton. :^)

Andreas Kling преди 6 години
родител
ревизия
f12573cb63

+ 18 - 8
Servers/WindowServer/WSButton.cpp

@@ -20,7 +20,7 @@ void WSButton::paint(Painter& painter)
 {
     PainterStateSaver saver(painter);
     painter.translate(relative_rect().location());
-    StylePainter::paint_button(painter, rect(), ButtonStyle::Normal, m_pressed);
+    StylePainter::paint_button(painter, rect(), ButtonStyle::Normal, m_pressed, m_hovered);
     auto x_location = rect().center();
     x_location.move_by(-(m_bitmap->width() / 2), -(m_bitmap->height() / 2));
     if (m_pressed)
@@ -39,13 +39,6 @@ void WSButton::on_mouse_event(const WSMouseEvent& event)
         return;
     }
 
-    if (event.type() == WSMessage::MouseMove) {
-        bool old_pressed = m_pressed;
-        m_pressed = rect().contains(event.position());
-        if (old_pressed != m_pressed)
-            wm.invalidate(screen_rect());
-    }
-
     if (event.type() == WSMessage::MouseUp && event.button() == MouseButton::Left) {
         WSWindowManager::the().set_cursor_tracking_button(nullptr);
         bool old_pressed = m_pressed;
@@ -56,6 +49,23 @@ void WSButton::on_mouse_event(const WSMouseEvent& event)
         }
         if (old_pressed != m_pressed)
             wm.invalidate(screen_rect());
+        return;
+    }
+
+    if (event.type() == WSMessage::MouseMove) {
+        bool old_hovered = m_hovered;
+        m_hovered = rect().contains(event.position());
+        wm.set_hovered_button(m_hovered ? this : nullptr);
+        if (old_hovered != m_hovered)
+            wm.invalidate(screen_rect());
+        dbgprintf("move, hov=%d, rect=%s, evpos=%s\n", m_hovered, rect().to_string().characters(), event.position().to_string().characters());
+    }
+
+    if (event.type() == WSMessage::MouseMove && event.buttons() & (unsigned)MouseButton::Left) {
+        bool old_pressed = m_pressed;
+        m_pressed = m_hovered;
+        if (old_pressed != m_pressed)
+            wm.invalidate(screen_rect());
     }
 }
 

+ 1 - 0
Servers/WindowServer/WSButton.h

@@ -34,4 +34,5 @@ private:
     Retained<CharacterBitmap> m_bitmap;
     bool m_pressed { false };
     bool m_visible { true };
+    bool m_hovered { false };
 };

+ 1 - 1
Servers/WindowServer/WSWindowFrame.cpp

@@ -239,7 +239,7 @@ void WSWindowFrame::on_mouse_event(const WSMouseEvent& event)
 
         for (auto& button : m_buttons) {
             if (button->relative_rect().contains(event.position()))
-                return button->on_mouse_event(event);
+                return button->on_mouse_event(event.translated(-button->relative_rect().location()));
         }
         if (event.type() == WSMessage::MouseDown && event.button() == MouseButton::Left)
             wm.start_window_drag(m_window, event.translated(rect().location()));

+ 9 - 0
Servers/WindowServer/WSWindowManager.cpp

@@ -623,6 +623,10 @@ void WSWindowManager::process_mouse_event(const WSMouseEvent& event, WSWindow*&
     if (m_cursor_tracking_button)
         return m_cursor_tracking_button->on_mouse_event(event.translated(-m_cursor_tracking_button->screen_rect().location()));
 
+    // This is quite hackish, but it's how the WSButton hover effect is implemented.
+    if (m_hovered_button && event.type() == WSMessage::MouseMove)
+        m_hovered_button->on_mouse_event(event.translated(-m_hovered_button->screen_rect().location()));
+
     HashTable<WSWindow*> windows_who_received_mouse_event_due_to_cursor_tracking;
 
     for (auto* window = m_windows_in_order.tail(); window; window = window->prev()) {
@@ -1099,3 +1103,8 @@ const WSCursor& WSWindowManager::active_cursor() const
 
     return *m_arrow_cursor;
 }
+
+void WSWindowManager::set_hovered_button(WSButton* button)
+{
+    m_hovered_button = button;
+}

+ 2 - 0
Servers/WindowServer/WSWindowManager.h

@@ -101,6 +101,7 @@ public:
 
     void set_active_window(WSWindow*);
     void set_cursor_tracking_button(WSButton* button) { m_cursor_tracking_button = button; }
+    void set_hovered_button(WSButton*);
 
 private:
     void process_mouse_event(const WSMouseEvent&, WSWindow*& event_window);
@@ -206,6 +207,7 @@ private:
 
     String m_username;
     WSButton* m_cursor_tracking_button { nullptr };
+    WSButton* m_hovered_button { nullptr };
 };
 
 template<typename Callback>

+ 9 - 4
SharedGraphics/StylePainter.cpp

@@ -1,15 +1,20 @@
 #include <SharedGraphics/StylePainter.h>
 #include <LibGUI/GPainter.h>
 
-static void paint_button_new(Painter& painter, const Rect& rect, bool pressed, bool checked)
+static void paint_button_new(Painter& painter, const Rect& rect, bool pressed, bool checked, bool hovered)
 {
     Color button_color = Color::from_rgb(0xc0c0c0);
     Color highlight_color2 = Color::from_rgb(0xdfdfdf);
     Color shadow_color1 = Color::from_rgb(0x808080);
     Color shadow_color2 = Color::from_rgb(0x404040);
 
-    if (checked)
-        button_color = Color::from_rgb(0xd6d2ce);
+    if (checked) {
+        if (hovered)
+            button_color = Color::from_rgb(0xe3dfdb);
+        else
+            button_color = Color::from_rgb(0xd6d2ce);
+    } else if (hovered)
+        button_color = Color::from_rgb(0xd4d4d4);
 
     PainterStateSaver saver(painter);
     painter.translate(rect.location());
@@ -51,7 +56,7 @@ static void paint_button_new(Painter& painter, const Rect& rect, bool pressed, b
 void StylePainter::paint_button(Painter& painter, const Rect& rect, ButtonStyle button_style, bool pressed, bool hovered, bool checked)
 {
     if (button_style == ButtonStyle::Normal)
-        return paint_button_new(painter, rect, pressed, checked);
+        return paint_button_new(painter, rect, pressed, checked, hovered);
 
     Color button_color = Color::LightGray;
     Color highlight_color = Color::White;