mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 16:45:08 +00:00
LibGUI: Add Widget override cursor concept
We got ourselves into a mess by making widgets override the window cursor whenever they wanted a custom cursor. This patch introduces a better solution to that issue: per-widget override cursors. Each widget now has an override cursor that overrides the window cursor when that widget is hovered.
This commit is contained in:
parent
b4f307f982
commit
cf429a788c
4 changed files with 48 additions and 8 deletions
|
@ -318,12 +318,14 @@ void Widget::handle_mousedoubleclick_event(MouseEvent& event)
|
||||||
|
|
||||||
void Widget::handle_enter_event(Core::Event& event)
|
void Widget::handle_enter_event(Core::Event& event)
|
||||||
{
|
{
|
||||||
|
window()->update_cursor({});
|
||||||
show_tooltip();
|
show_tooltip();
|
||||||
enter_event(event);
|
enter_event(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::handle_leave_event(Core::Event& event)
|
void Widget::handle_leave_event(Core::Event& event)
|
||||||
{
|
{
|
||||||
|
window()->update_cursor({});
|
||||||
Application::the()->hide_tooltip();
|
Application::the()->hide_tooltip();
|
||||||
leave_event(event);
|
leave_event(event);
|
||||||
}
|
}
|
||||||
|
@ -878,4 +880,14 @@ Gfx::IntRect Widget::children_clip_rect() const
|
||||||
return rect();
|
return rect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Widget::set_override_cursor(Gfx::StandardCursor cursor)
|
||||||
|
{
|
||||||
|
if (m_override_cursor == cursor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_override_cursor = cursor;
|
||||||
|
if (auto* window = this->window())
|
||||||
|
window->update_cursor({});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@
|
||||||
#include <LibGfx/Forward.h>
|
#include <LibGfx/Forward.h>
|
||||||
#include <LibGfx/Orientation.h>
|
#include <LibGfx/Orientation.h>
|
||||||
#include <LibGfx/Rect.h>
|
#include <LibGfx/Rect.h>
|
||||||
|
#include <LibGfx/StandardCursor.h>
|
||||||
|
|
||||||
#define REGISTER_WIDGET(class_name) \
|
#define REGISTER_WIDGET(class_name) \
|
||||||
extern WidgetClassRegistration registration_##class_name; \
|
extern WidgetClassRegistration registration_##class_name; \
|
||||||
|
@ -277,6 +278,9 @@ public:
|
||||||
|
|
||||||
virtual Gfx::IntRect children_clip_rect() const;
|
virtual Gfx::IntRect children_clip_rect() const;
|
||||||
|
|
||||||
|
Gfx::StandardCursor override_cursor() const { return m_override_cursor; }
|
||||||
|
void set_override_cursor(Gfx::StandardCursor);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Widget();
|
Widget();
|
||||||
|
|
||||||
|
@ -349,6 +353,8 @@ private:
|
||||||
NonnullRefPtr<Gfx::PaletteImpl> m_palette;
|
NonnullRefPtr<Gfx::PaletteImpl> m_palette;
|
||||||
|
|
||||||
WeakPtr<Widget> m_focus_proxy;
|
WeakPtr<Widget> m_focus_proxy;
|
||||||
|
|
||||||
|
Gfx::StandardCursor m_override_cursor { Gfx::StandardCursor::None };
|
||||||
};
|
};
|
||||||
|
|
||||||
inline Widget* Widget::parent_widget()
|
inline Widget* Widget::parent_widget()
|
||||||
|
|
|
@ -228,23 +228,20 @@ void Window::set_window_type(WindowType window_type)
|
||||||
|
|
||||||
void Window::set_cursor(Gfx::StandardCursor cursor)
|
void Window::set_cursor(Gfx::StandardCursor cursor)
|
||||||
{
|
{
|
||||||
if (!is_visible())
|
if (m_cursor == cursor)
|
||||||
return;
|
return;
|
||||||
if (!m_custom_cursor && m_cursor == cursor)
|
|
||||||
return;
|
|
||||||
WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowCursor>(m_window_id, (u32)cursor);
|
|
||||||
m_cursor = cursor;
|
m_cursor = cursor;
|
||||||
m_custom_cursor = nullptr;
|
m_custom_cursor = nullptr;
|
||||||
|
update_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::set_cursor(const Gfx::Bitmap& cursor)
|
void Window::set_cursor(const Gfx::Bitmap& cursor)
|
||||||
{
|
{
|
||||||
if (!is_visible())
|
if (m_custom_cursor == &cursor)
|
||||||
return;
|
|
||||||
if (&cursor == m_custom_cursor.ptr())
|
|
||||||
return;
|
return;
|
||||||
|
m_cursor = Gfx::StandardCursor::None;
|
||||||
m_custom_cursor = &cursor;
|
m_custom_cursor = &cursor;
|
||||||
WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowCustomCursor>(m_window_id, m_custom_cursor->to_shareable_bitmap(WindowServerConnection::the().server_pid()));
|
update_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::handle_drop_event(DropEvent& event)
|
void Window::handle_drop_event(DropEvent& event)
|
||||||
|
@ -871,4 +868,24 @@ void Window::set_progress(int progress)
|
||||||
ASSERT(m_window_id);
|
ASSERT(m_window_id);
|
||||||
WindowServerConnection::the().post_message(Messages::WindowServer::SetWindowProgress(m_window_id, progress));
|
WindowServerConnection::the().post_message(Messages::WindowServer::SetWindowProgress(m_window_id, progress));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Window::update_cursor()
|
||||||
|
{
|
||||||
|
Gfx::StandardCursor new_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_effective_cursor == new_cursor)
|
||||||
|
return;
|
||||||
|
m_effective_cursor = new_cursor;
|
||||||
|
|
||||||
|
if (m_custom_cursor)
|
||||||
|
WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowCustomCursor>(m_window_id, m_custom_cursor->to_shareable_bitmap(WindowServerConnection::the().server_pid()));
|
||||||
|
else
|
||||||
|
WindowServerConnection::the().send_sync<Messages::WindowServer::SetWindowCursor>(m_window_id, (u32)m_effective_cursor);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,8 @@ public:
|
||||||
|
|
||||||
void set_progress(int);
|
void set_progress(int);
|
||||||
|
|
||||||
|
void update_cursor(Badge<Widget>) { update_cursor(); }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Window(Core::Object* parent = nullptr);
|
Window(Core::Object* parent = nullptr);
|
||||||
virtual void wm_event(WMEvent&);
|
virtual void wm_event(WMEvent&);
|
||||||
|
@ -203,6 +205,8 @@ protected:
|
||||||
private:
|
private:
|
||||||
virtual bool is_window() const override final { return true; }
|
virtual bool is_window() const override final { return true; }
|
||||||
|
|
||||||
|
void update_cursor();
|
||||||
|
|
||||||
void handle_drop_event(DropEvent&);
|
void handle_drop_event(DropEvent&);
|
||||||
void handle_mouse_event(MouseEvent&);
|
void handle_mouse_event(MouseEvent&);
|
||||||
void handle_multi_paint_event(MultiPaintEvent&);
|
void handle_multi_paint_event(MultiPaintEvent&);
|
||||||
|
@ -242,6 +246,7 @@ private:
|
||||||
Color m_background_color { Color::WarmGray };
|
Color m_background_color { Color::WarmGray };
|
||||||
WindowType m_window_type { WindowType::Normal };
|
WindowType m_window_type { WindowType::Normal };
|
||||||
Gfx::StandardCursor m_cursor { Gfx::StandardCursor::None };
|
Gfx::StandardCursor m_cursor { Gfx::StandardCursor::None };
|
||||||
|
Gfx::StandardCursor m_effective_cursor { Gfx::StandardCursor::None };
|
||||||
bool m_is_active { false };
|
bool m_is_active { false };
|
||||||
bool m_is_active_input { false };
|
bool m_is_active_input { false };
|
||||||
bool m_has_alpha_channel { false };
|
bool m_has_alpha_channel { false };
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue