mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 05:07:34 +00:00
LibGUI: Add "drag enter" and "drag leave" events
These events allow widgets to react when a drag enters/leaves their rectangle. The enter event carries position + mime type, while the leave event has no information.
This commit is contained in:
parent
4728d0dd6a
commit
9acb72e804
7 changed files with 60 additions and 3 deletions
|
@ -247,4 +247,27 @@ void Application::window_did_become_inactive(Badge<Window>, Window& window)
|
||||||
m_active_window = nullptr;
|
m_active_window = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::set_drag_hovered_widget_impl(Widget* widget, const Gfx::IntPoint& position, const String& mime_type)
|
||||||
|
{
|
||||||
|
if (widget == m_drag_hovered_widget)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (m_drag_hovered_widget) {
|
||||||
|
m_drag_hovered_widget->update();
|
||||||
|
Core::EventLoop::current().post_event(*m_drag_hovered_widget, make<Event>(Event::DragLeave));
|
||||||
|
}
|
||||||
|
|
||||||
|
m_drag_hovered_widget = widget;
|
||||||
|
|
||||||
|
if (m_drag_hovered_widget) {
|
||||||
|
m_drag_hovered_widget->update();
|
||||||
|
Core::EventLoop::current().post_event(*m_drag_hovered_widget, make<DragEvent>(Event::DragEnter, position, mime_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::notify_drag_cancelled(Badge<WindowServerConnection>)
|
||||||
|
{
|
||||||
|
set_drag_hovered_widget_impl(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,7 +34,7 @@
|
||||||
#include <LibGUI/Forward.h>
|
#include <LibGUI/Forward.h>
|
||||||
#include <LibGUI/Shortcut.h>
|
#include <LibGUI/Shortcut.h>
|
||||||
#include <LibGUI/Widget.h>
|
#include <LibGUI/Widget.h>
|
||||||
#include <LibGfx/Forward.h>
|
#include <LibGfx/Point.h>
|
||||||
|
|
||||||
namespace GUI {
|
namespace GUI {
|
||||||
|
|
||||||
|
@ -83,12 +83,23 @@ public:
|
||||||
void window_did_become_active(Badge<Window>, Window&);
|
void window_did_become_active(Badge<Window>, Window&);
|
||||||
void window_did_become_inactive(Badge<Window>, Window&);
|
void window_did_become_inactive(Badge<Window>, Window&);
|
||||||
|
|
||||||
|
Widget* drag_hovered_widget() { return m_drag_hovered_widget.ptr(); }
|
||||||
|
const Widget* drag_hovered_widget() const { return m_drag_hovered_widget.ptr(); }
|
||||||
|
|
||||||
|
void set_drag_hovered_widget(Badge<Window>, Widget* widget, const Gfx::IntPoint& position = {}, const String& mime_type = {})
|
||||||
|
{
|
||||||
|
set_drag_hovered_widget_impl(widget, position, mime_type);
|
||||||
|
}
|
||||||
|
void notify_drag_cancelled(Badge<WindowServerConnection>);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Application(int argc, char** argv);
|
Application(int argc, char** argv);
|
||||||
|
|
||||||
void tooltip_show_timer_did_fire();
|
void tooltip_show_timer_did_fire();
|
||||||
void tooltip_hide_timer_did_fire();
|
void tooltip_hide_timer_did_fire();
|
||||||
|
|
||||||
|
void set_drag_hovered_widget_impl(Widget*, const Gfx::IntPoint& = {}, const String& = {});
|
||||||
|
|
||||||
OwnPtr<Core::EventLoop> m_event_loop;
|
OwnPtr<Core::EventLoop> m_event_loop;
|
||||||
RefPtr<MenuBar> m_menubar;
|
RefPtr<MenuBar> m_menubar;
|
||||||
RefPtr<Gfx::PaletteImpl> m_palette;
|
RefPtr<Gfx::PaletteImpl> m_palette;
|
||||||
|
@ -104,6 +115,7 @@ private:
|
||||||
bool m_focus_debugging_enabled { false };
|
bool m_focus_debugging_enabled { false };
|
||||||
String m_invoked_as;
|
String m_invoked_as;
|
||||||
Vector<String> m_args;
|
Vector<String> m_args;
|
||||||
|
WeakPtr<Widget> m_drag_hovered_widget;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,8 @@ public:
|
||||||
WindowCloseRequest,
|
WindowCloseRequest,
|
||||||
ContextMenu,
|
ContextMenu,
|
||||||
EnabledChange,
|
EnabledChange,
|
||||||
|
DragEnter,
|
||||||
|
DragLeave,
|
||||||
DragMove,
|
DragMove,
|
||||||
Drop,
|
Drop,
|
||||||
ThemeChange,
|
ThemeChange,
|
||||||
|
|
|
@ -273,8 +273,12 @@ void Widget::event(Core::Event& event)
|
||||||
return handle_mouseup_event(static_cast<MouseEvent&>(event));
|
return handle_mouseup_event(static_cast<MouseEvent&>(event));
|
||||||
case Event::MouseWheel:
|
case Event::MouseWheel:
|
||||||
return mousewheel_event(static_cast<MouseEvent&>(event));
|
return mousewheel_event(static_cast<MouseEvent&>(event));
|
||||||
|
case Event::DragEnter:
|
||||||
|
return drag_enter_event(static_cast<DragEvent&>(event));
|
||||||
case Event::DragMove:
|
case Event::DragMove:
|
||||||
return drag_move_event(static_cast<DragEvent&>(event));
|
return drag_move_event(static_cast<DragEvent&>(event));
|
||||||
|
case Event::DragLeave:
|
||||||
|
return drag_leave_event(static_cast<Event&>(event));
|
||||||
case Event::Drop:
|
case Event::Drop:
|
||||||
return drop_event(static_cast<DropEvent&>(event));
|
return drop_event(static_cast<DropEvent&>(event));
|
||||||
case Event::ThemeChange:
|
case Event::ThemeChange:
|
||||||
|
@ -497,13 +501,24 @@ void Widget::change_event(Event&)
|
||||||
|
|
||||||
void Widget::drag_move_event(DragEvent& event)
|
void Widget::drag_move_event(DragEvent& event)
|
||||||
{
|
{
|
||||||
dbg() << class_name() << "{" << this << "} DRAG MOVE position: " << event.position() << ", data_type: '" << event.data_type() << "'";
|
event.ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::drag_enter_event(DragEvent& event)
|
||||||
|
{
|
||||||
|
dbgln("{} {:p} DRAG ENTER @ {}, {}", class_name(), this, event.position(), event.data_type());
|
||||||
|
event.ignore();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Widget::drag_leave_event(Event& event)
|
||||||
|
{
|
||||||
|
dbgln("{} {:p} DRAG LEAVE", class_name(), this);
|
||||||
event.ignore();
|
event.ignore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Widget::drop_event(DropEvent& event)
|
void Widget::drop_event(DropEvent& event)
|
||||||
{
|
{
|
||||||
dbg() << class_name() << "{" << this << "} DROP position: " << event.position() << ", text: '" << event.text() << "'";
|
dbgln("{} {:p} DROP @ {}, '{}'", class_name(), this, event.position(), event.text());
|
||||||
event.ignore();
|
event.ignore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -324,7 +324,9 @@ protected:
|
||||||
virtual void leave_event(Core::Event&);
|
virtual void leave_event(Core::Event&);
|
||||||
virtual void child_event(Core::ChildEvent&) override;
|
virtual void child_event(Core::ChildEvent&) override;
|
||||||
virtual void change_event(Event&);
|
virtual void change_event(Event&);
|
||||||
|
virtual void drag_enter_event(DragEvent&);
|
||||||
virtual void drag_move_event(DragEvent&);
|
virtual void drag_move_event(DragEvent&);
|
||||||
|
virtual void drag_leave_event(Event&);
|
||||||
virtual void drop_event(DropEvent&);
|
virtual void drop_event(DropEvent&);
|
||||||
virtual void theme_change_event(ThemeChangeEvent&);
|
virtual void theme_change_event(ThemeChangeEvent&);
|
||||||
|
|
||||||
|
|
|
@ -446,12 +446,14 @@ void Window::handle_drag_move_event(DragEvent& event)
|
||||||
auto result = m_main_widget->hit_test(event.position());
|
auto result = m_main_widget->hit_test(event.position());
|
||||||
auto local_event = make<DragEvent>(static_cast<Event::Type>(event.type()), result.local_position, event.data_type());
|
auto local_event = make<DragEvent>(static_cast<Event::Type>(event.type()), result.local_position, event.data_type());
|
||||||
ASSERT(result.widget);
|
ASSERT(result.widget);
|
||||||
|
Application::the()->set_drag_hovered_widget({}, result.widget, result.local_position, event.data_type());
|
||||||
return result.widget->dispatch_event(*local_event, this);
|
return result.widget->dispatch_event(*local_event, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::handle_left_event()
|
void Window::handle_left_event()
|
||||||
{
|
{
|
||||||
set_hovered_widget(nullptr);
|
set_hovered_widget(nullptr);
|
||||||
|
Application::the()->set_drag_hovered_widget({}, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Window::event(Core::Event& event)
|
void Window::event(Core::Event& event)
|
||||||
|
|
|
@ -325,6 +325,7 @@ void WindowServerConnection::handle(const Messages::WindowClient::DragAccepted&)
|
||||||
void WindowServerConnection::handle(const Messages::WindowClient::DragCancelled&)
|
void WindowServerConnection::handle(const Messages::WindowClient::DragCancelled&)
|
||||||
{
|
{
|
||||||
DragOperation::notify_cancelled({});
|
DragOperation::notify_cancelled({});
|
||||||
|
Application::the()->notify_drag_cancelled({});
|
||||||
}
|
}
|
||||||
|
|
||||||
void WindowServerConnection::handle(const Messages::WindowClient::WindowStateChanged& message)
|
void WindowServerConnection::handle(const Messages::WindowClient::WindowStateChanged& message)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue