mirror of
https://github.com/RGBCube/serenity
synced 2025-05-22 17:15: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)
|
||||
{
|
||||
window()->update_cursor({});
|
||||
show_tooltip();
|
||||
enter_event(event);
|
||||
}
|
||||
|
||||
void Widget::handle_leave_event(Core::Event& event)
|
||||
{
|
||||
window()->update_cursor({});
|
||||
Application::the()->hide_tooltip();
|
||||
leave_event(event);
|
||||
}
|
||||
|
@ -878,4 +880,14 @@ Gfx::IntRect Widget::children_clip_rect() const
|
|||
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/Orientation.h>
|
||||
#include <LibGfx/Rect.h>
|
||||
#include <LibGfx/StandardCursor.h>
|
||||
|
||||
#define REGISTER_WIDGET(class_name) \
|
||||
extern WidgetClassRegistration registration_##class_name; \
|
||||
|
@ -277,6 +278,9 @@ public:
|
|||
|
||||
virtual Gfx::IntRect children_clip_rect() const;
|
||||
|
||||
Gfx::StandardCursor override_cursor() const { return m_override_cursor; }
|
||||
void set_override_cursor(Gfx::StandardCursor);
|
||||
|
||||
protected:
|
||||
Widget();
|
||||
|
||||
|
@ -349,6 +353,8 @@ private:
|
|||
NonnullRefPtr<Gfx::PaletteImpl> m_palette;
|
||||
|
||||
WeakPtr<Widget> m_focus_proxy;
|
||||
|
||||
Gfx::StandardCursor m_override_cursor { Gfx::StandardCursor::None };
|
||||
};
|
||||
|
||||
inline Widget* Widget::parent_widget()
|
||||
|
|
|
@ -228,23 +228,20 @@ void Window::set_window_type(WindowType window_type)
|
|||
|
||||
void Window::set_cursor(Gfx::StandardCursor cursor)
|
||||
{
|
||||
if (!is_visible())
|
||||
if (m_cursor == cursor)
|
||||
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_custom_cursor = nullptr;
|
||||
update_cursor();
|
||||
}
|
||||
|
||||
void Window::set_cursor(const Gfx::Bitmap& cursor)
|
||||
{
|
||||
if (!is_visible())
|
||||
return;
|
||||
if (&cursor == m_custom_cursor.ptr())
|
||||
if (m_custom_cursor == &cursor)
|
||||
return;
|
||||
m_cursor = Gfx::StandardCursor::None;
|
||||
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)
|
||||
|
@ -871,4 +868,24 @@ void Window::set_progress(int progress)
|
|||
ASSERT(m_window_id);
|
||||
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 update_cursor(Badge<Widget>) { update_cursor(); }
|
||||
|
||||
protected:
|
||||
Window(Core::Object* parent = nullptr);
|
||||
virtual void wm_event(WMEvent&);
|
||||
|
@ -203,6 +205,8 @@ protected:
|
|||
private:
|
||||
virtual bool is_window() const override final { return true; }
|
||||
|
||||
void update_cursor();
|
||||
|
||||
void handle_drop_event(DropEvent&);
|
||||
void handle_mouse_event(MouseEvent&);
|
||||
void handle_multi_paint_event(MultiPaintEvent&);
|
||||
|
@ -242,6 +246,7 @@ private:
|
|||
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 };
|
||||
bool m_is_active { false };
|
||||
bool m_is_active_input { false };
|
||||
bool m_has_alpha_channel { false };
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue