From 6673284b06298cf54af5c46e5bdeeffa6e561c86 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 2 Apr 2019 02:34:09 +0200 Subject: [PATCH] LibGUI: Switch to a resizing cursor when hovering or using a GSplitter. Also expose the various standard cursors on WSWindowManager so they can be reused by the override mechanism. --- AK/RetainPtr.h | 1 + AK/Retained.h | 1 + LibGUI/GSplitter.cpp | 7 +++++++ LibGUI/GWindow.h | 2 ++ Servers/WindowServer/WSAPITypes.h | 2 ++ Servers/WindowServer/WSCursor.cpp | 9 +++++++-- Servers/WindowServer/WSCursor.h | 2 ++ Servers/WindowServer/WSWindowManager.h | 9 +++++++++ 8 files changed, 31 insertions(+), 2 deletions(-) diff --git a/AK/RetainPtr.h b/AK/RetainPtr.h index 5620c8de0a..be92b181f0 100644 --- a/AK/RetainPtr.h +++ b/AK/RetainPtr.h @@ -14,6 +14,7 @@ public: RetainPtr(const T* ptr) : m_ptr(const_cast(ptr)) { retain_if_not_null(m_ptr); } RetainPtr(T* ptr) : m_ptr(ptr) { retain_if_not_null(m_ptr); } RetainPtr(T& object) : m_ptr(&object) { m_ptr->retain(); } + RetainPtr(const T& object) : m_ptr(const_cast(&object)) { m_ptr->retain(); } RetainPtr(AdoptTag, T& object) : m_ptr(&object) { } RetainPtr(RetainPtr& other) : m_ptr(other.copy_ref().leak_ref()) { } RetainPtr(RetainPtr&& other) : m_ptr(other.leak_ref()) { } diff --git a/AK/Retained.h b/AK/Retained.h index 1b27e5d3a1..93f245e0bc 100644 --- a/AK/Retained.h +++ b/AK/Retained.h @@ -35,6 +35,7 @@ class CONSUMABLE(unconsumed) Retained { public: enum AdoptTag { Adopt }; + RETURN_TYPESTATE(unconsumed) Retained(const T& object) : m_ptr(&object) { m_ptr->retain(); } RETURN_TYPESTATE(unconsumed) Retained(T& object) : m_ptr(&object) { m_ptr->retain(); } template RETURN_TYPESTATE(unconsumed) Retained(U& object) : m_ptr(&static_cast(object)) { m_ptr->retain(); } RETURN_TYPESTATE(unconsumed) Retained(AdoptTag, T& object) : m_ptr(&object) { } diff --git a/LibGUI/GSplitter.cpp b/LibGUI/GSplitter.cpp index c6e1ef7b96..cb71bd927e 100644 --- a/LibGUI/GSplitter.cpp +++ b/LibGUI/GSplitter.cpp @@ -1,5 +1,6 @@ #include #include +#include GSplitter::GSplitter(Orientation orientation, GWidget* parent) : GFrame(parent) @@ -18,12 +19,15 @@ GSplitter::~GSplitter() void GSplitter::enter_event(GEvent&) { set_background_color(Color::from_rgb(0xd6d2ce)); + window()->set_override_cursor(m_orientation == Orientation::Horizontal ? GStandardCursor::ResizeHorizontal : GStandardCursor::ResizeVertical); update(); } void GSplitter::leave_event(GEvent&) { set_background_color(Color::LightGray); + if (!m_resizing) + window()->set_override_cursor(GStandardCursor::None); update(); } @@ -108,4 +112,7 @@ void GSplitter::mouseup_event(GMouseEvent& event) if (event.button() != GMouseButton::Left) return; m_resizing = false; + if (!rect().contains(event.position())) + window()->set_override_cursor(GStandardCursor::None); + } diff --git a/LibGUI/GWindow.h b/LibGUI/GWindow.h index 86ee57bcaa..81cb417606 100644 --- a/LibGUI/GWindow.h +++ b/LibGUI/GWindow.h @@ -12,6 +12,8 @@ enum class GStandardCursor { None = 0, Arrow, IBeam, + ResizeHorizontal, + ResizeVertical, }; class GWindow : public GObject { diff --git a/Servers/WindowServer/WSAPITypes.h b/Servers/WindowServer/WSAPITypes.h index 31bcc54e99..cc3318aa24 100644 --- a/Servers/WindowServer/WSAPITypes.h +++ b/Servers/WindowServer/WSAPITypes.h @@ -51,6 +51,8 @@ enum class WSAPI_StandardCursor : unsigned char { None = 0, Arrow, IBeam, + ResizeHorizontal, + ResizeVertical, }; struct WSAPI_ServerMessage { diff --git a/Servers/WindowServer/WSCursor.cpp b/Servers/WindowServer/WSCursor.cpp index 61854a75a7..7862447550 100644 --- a/Servers/WindowServer/WSCursor.cpp +++ b/Servers/WindowServer/WSCursor.cpp @@ -1,4 +1,5 @@ #include +#include WSCursor::WSCursor(Retained&& bitmap, const Point& hotspot) : m_bitmap(move(bitmap)) @@ -26,9 +27,13 @@ RetainPtr WSCursor::create(WSStandardCursor standard_cursor) case WSStandardCursor::None: return nullptr; case WSStandardCursor::Arrow: - return create(*GraphicsBitmap::load_from_file("/res/cursors/arrow.png")); + return WSWindowManager::the().arrow_cursor(); case WSStandardCursor::IBeam: - return create(*GraphicsBitmap::load_from_file("/res/cursors/i-beam.png")); + return WSWindowManager::the().i_beam_cursor(); + case WSStandardCursor::ResizeHorizontal: + return WSWindowManager::the().resize_horizontally_cursor(); + case WSStandardCursor::ResizeVertical: + return WSWindowManager::the().resize_vertically_cursor(); } ASSERT_NOT_REACHED(); } diff --git a/Servers/WindowServer/WSCursor.h b/Servers/WindowServer/WSCursor.h index 4a07f2b6de..82d71bcbc8 100644 --- a/Servers/WindowServer/WSCursor.h +++ b/Servers/WindowServer/WSCursor.h @@ -6,6 +6,8 @@ enum class WSStandardCursor { None = 0, Arrow, IBeam, + ResizeHorizontal, + ResizeVertical, }; class WSCursor : public Retainable { diff --git a/Servers/WindowServer/WSWindowManager.h b/Servers/WindowServer/WSWindowManager.h index 40bae77754..84307984b5 100644 --- a/Servers/WindowServer/WSWindowManager.h +++ b/Servers/WindowServer/WSWindowManager.h @@ -87,6 +87,15 @@ public: const WSCursor& active_cursor() const; Rect current_cursor_rect() const; + const WSCursor& arrow_cursor() const { return *m_arrow_cursor; } + const WSCursor& resize_horizontally_cursor() const { return *m_resize_horizontally_cursor; } + const WSCursor& resize_vertically_cursor() const { return *m_resize_vertically_cursor; } + const WSCursor& resize_diagonally_tlbr_cursor() const { return *m_resize_diagonally_tlbr_cursor; } + const WSCursor& resize_diagonally_bltr_cursor() const { return *m_resize_diagonally_bltr_cursor; } + const WSCursor& i_beam_cursor() const { return *m_i_beam_cursor; } + const WSCursor& disallowed_cursor() const { return *m_disallowed_cursor; } + const WSCursor& move_cursor() const { return *m_move_cursor; } + private: void process_mouse_event(const WSMouseEvent&, WSWindow*& event_window); bool process_ongoing_window_resize(const WSMouseEvent&, WSWindow*& event_window);