diff options
author | Marco Cutecchia <marco.cutecchia@outlook.it> | 2021-10-15 22:24:41 +0200 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-10-31 12:37:49 +0100 |
commit | 116bb4888fb7c7f5c80091caca6f3cdf68ef6383 (patch) | |
tree | afa59f7b21d9d88f96c4176af3c1a9b850ce745a /Userland/Libraries | |
parent | 4bfe060336b96926dfd72bc3b0ef0b7ffdf5e168 (diff) | |
download | serenity-116bb4888fb7c7f5c80091caca6f3cdf68ef6383.zip |
LibGUI: Support using a bitmap as override cursor
Diffstat (limited to 'Userland/Libraries')
-rw-r--r-- | Userland/Libraries/LibGUI/Widget.cpp | 17 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/Widget.h | 7 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/Window.cpp | 38 | ||||
-rw-r--r-- | Userland/Libraries/LibGUI/Window.h | 10 |
4 files changed, 46 insertions, 26 deletions
diff --git a/Userland/Libraries/LibGUI/Widget.cpp b/Userland/Libraries/LibGUI/Widget.cpp index 811ec1a312..6062142819 100644 --- a/Userland/Libraries/LibGUI/Widget.cpp +++ b/Userland/Libraries/LibGUI/Widget.cpp @@ -1036,14 +1036,23 @@ Gfx::IntRect Widget::children_clip_rect() const return rect(); } -void Widget::set_override_cursor(Gfx::StandardCursor cursor) +void Widget::set_override_cursor(AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> cursor) { - if (m_override_cursor == cursor) + auto const& are_cursors_the_same = [](AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> const& a, AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> const& b) { + if (a.has<Gfx::StandardCursor>() != b.has<Gfx::StandardCursor>()) + return false; + if (a.has<Gfx::StandardCursor>()) + return a.get<Gfx::StandardCursor>() == b.get<Gfx::StandardCursor>(); + return a.get<NonnullRefPtr<Gfx::Bitmap>>().ptr() == b.get<NonnullRefPtr<Gfx::Bitmap>>().ptr(); + }; + + if (are_cursors_the_same(m_override_cursor, cursor)) return; - m_override_cursor = cursor; - if (auto* window = this->window()) + m_override_cursor = move(cursor); + if (auto* window = this->window()) { window->update_cursor({}); + } } bool Widget::load_from_gml(const StringView& gml_string) diff --git a/Userland/Libraries/LibGUI/Widget.h b/Userland/Libraries/LibGUI/Widget.h index 29ae0f0079..07b870e28a 100644 --- a/Userland/Libraries/LibGUI/Widget.h +++ b/Userland/Libraries/LibGUI/Widget.h @@ -9,6 +9,7 @@ #include <AK/EnumBits.h> #include <AK/JsonObject.h> #include <AK/String.h> +#include <AK/Variant.h> #include <LibCore/Object.h> #include <LibGUI/Event.h> #include <LibGUI/FocusPolicy.h> @@ -272,8 +273,8 @@ public: virtual Gfx::IntRect children_clip_rect() const; - Gfx::StandardCursor override_cursor() const { return m_override_cursor; } - void set_override_cursor(Gfx::StandardCursor); + AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> override_cursor() const { return m_override_cursor; } + void set_override_cursor(AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>>); bool load_from_gml(const StringView&); bool load_from_gml(const StringView&, RefPtr<Core::Object> (*unregistered_child_handler)(const String&)); @@ -373,7 +374,7 @@ private: WeakPtr<Widget> m_focus_proxy; FocusPolicy m_focus_policy { FocusPolicy::NoFocus }; - Gfx::StandardCursor m_override_cursor { Gfx::StandardCursor::None }; + AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> m_override_cursor { Gfx::StandardCursor::None }; }; inline Widget* Widget::parent_widget() diff --git a/Userland/Libraries/LibGUI/Window.cpp b/Userland/Libraries/LibGUI/Window.cpp index 6e5f1cfe8c..6f7265f3ac 100644 --- a/Userland/Libraries/LibGUI/Window.cpp +++ b/Userland/Libraries/LibGUI/Window.cpp @@ -317,21 +317,28 @@ void Window::make_window_manager(unsigned event_mask) GUI::WindowManagerServerConnection::the().async_set_manager_window(m_window_id); } +bool Window::are_cursors_the_same(AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> const& left, AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> const& right) const +{ + if (left.has<Gfx::StandardCursor>() != right.has<Gfx::StandardCursor>()) + return false; + if (left.has<Gfx::StandardCursor>()) + return left.get<Gfx::StandardCursor>() == right.get<Gfx::StandardCursor>(); + return left.get<NonnullRefPtr<Gfx::Bitmap>>().ptr() == right.get<NonnullRefPtr<Gfx::Bitmap>>().ptr(); +} + void Window::set_cursor(Gfx::StandardCursor cursor) { - if (m_cursor == cursor) + if (are_cursors_the_same(m_cursor, cursor)) return; m_cursor = cursor; - m_custom_cursor = nullptr; update_cursor(); } -void Window::set_cursor(const Gfx::Bitmap& cursor) +void Window::set_cursor(NonnullRefPtr<Gfx::Bitmap> cursor) { - if (m_custom_cursor == &cursor) + if (are_cursors_the_same(m_cursor, cursor)) return; - m_cursor = Gfx::StandardCursor::None; - m_custom_cursor = &cursor; + m_cursor = cursor; update_cursor(); } @@ -1135,21 +1142,22 @@ void Window::set_progress(Optional<int> progress) void Window::update_cursor() { - Gfx::StandardCursor new_cursor; + auto new_cursor = m_cursor; - if (m_hovered_widget && m_hovered_widget->override_cursor() != Gfx::StandardCursor::None) - new_cursor = m_hovered_widget->override_cursor(); - else - new_cursor = m_cursor; + if (m_hovered_widget) { + auto override_cursor = m_hovered_widget->override_cursor(); + if (override_cursor.has<NonnullRefPtr<Gfx::Bitmap>>() || override_cursor.get<Gfx::StandardCursor>() != Gfx::StandardCursor::None) + new_cursor = move(override_cursor); + } - if (!m_custom_cursor && m_effective_cursor == new_cursor) + if (are_cursors_the_same(m_effective_cursor, new_cursor)) return; m_effective_cursor = new_cursor; - if (m_custom_cursor) - WindowServerConnection::the().async_set_window_custom_cursor(m_window_id, m_custom_cursor->to_shareable_bitmap()); + if (new_cursor.has<NonnullRefPtr<Gfx::Bitmap>>()) + WindowServerConnection::the().async_set_window_custom_cursor(m_window_id, new_cursor.get<NonnullRefPtr<Gfx::Bitmap>>()->to_shareable_bitmap()); else - WindowServerConnection::the().async_set_window_cursor(m_window_id, (u32)m_effective_cursor); + WindowServerConnection::the().async_set_window_cursor(m_window_id, (u32)new_cursor.get<Gfx::StandardCursor>()); } void Window::focus_a_widget_if_possible(FocusSource source) diff --git a/Userland/Libraries/LibGUI/Window.h b/Userland/Libraries/LibGUI/Window.h index 119a5529b7..6723b9ee09 100644 --- a/Userland/Libraries/LibGUI/Window.h +++ b/Userland/Libraries/LibGUI/Window.h @@ -9,6 +9,7 @@ #include <AK/Function.h> #include <AK/OwnPtr.h> #include <AK/String.h> +#include <AK/Variant.h> #include <AK/WeakPtr.h> #include <LibCore/Object.h> #include <LibGUI/FocusSource.h> @@ -169,7 +170,7 @@ public: void set_resize_aspect_ratio(const Optional<Gfx::IntSize>& ratio); void set_cursor(Gfx::StandardCursor); - void set_cursor(const Gfx::Bitmap&); + void set_cursor(NonnullRefPtr<Gfx::Bitmap>); void set_icon(const Gfx::Bitmap*); void apply_icon(); @@ -240,6 +241,8 @@ private: void flip(const Vector<Gfx::IntRect, 32>& dirty_rects); void force_update(); + bool are_cursors_the_same(AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> const&, AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> const&) const; + WeakPtr<Widget> m_previously_focused_widget; OwnPtr<WindowBackingStore> m_front_store; @@ -248,7 +251,6 @@ private: NonnullRefPtr<Menubar> m_menubar; RefPtr<Gfx::Bitmap> m_icon; - RefPtr<Gfx::Bitmap> m_custom_cursor; int m_window_id { 0 }; float m_opacity_when_windowless { 1.0f }; float m_alpha_hit_threshold { 0.0f }; @@ -265,8 +267,8 @@ private: Gfx::IntSize m_base_size; Color m_background_color { Color::WarmGray }; WindowType m_window_type { WindowType::Normal }; - Gfx::StandardCursor m_cursor { Gfx::StandardCursor::None }; - Gfx::StandardCursor m_effective_cursor { Gfx::StandardCursor::None }; + AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> m_cursor { Gfx::StandardCursor::None }; + AK::Variant<Gfx::StandardCursor, NonnullRefPtr<Gfx::Bitmap>> m_effective_cursor { Gfx::StandardCursor::None }; bool m_is_active_input { false }; bool m_has_alpha_channel { false }; bool m_double_buffering_enabled { true }; |