1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-25 18:37:35 +00:00

WindowServer+LibGUI: Add a "drag move" event

This allows windows/widgets to learn when something is being dragged
over them. They can then repaint themselves somehow to indicate that
they are willing to accept a drop.

Currently this is piggybacking somewhat on the mouse event mechanism
in WindowServer. I'm not sure that's the best design but it seemed
easier to do it this way right now.
This commit is contained in:
Andreas Kling 2020-02-13 21:43:32 +01:00
parent 7590270e13
commit 3ce80bec97
9 changed files with 71 additions and 8 deletions

View file

@ -60,6 +60,7 @@ public:
WindowCloseRequest,
ContextMenu,
EnabledChange,
DragMove,
Drop,
__Begin_WM_Events,
@ -306,6 +307,23 @@ private:
int m_wheel_delta { 0 };
};
class DragEvent final : public Event {
public:
DragEvent(Type type, const Gfx::Point& position, const String& data_type)
: Event(type)
, m_position(position)
, m_data_type(data_type)
{
}
const Gfx::Point& position() const { return m_position; }
const String& data_type() const { return m_data_type; }
private:
Gfx::Point m_position;
String m_data_type;
};
class DropEvent final : public Event {
public:
DropEvent(const Gfx::Point& position, const String& text, const String& data_type, const String& data)

View file

@ -26,8 +26,6 @@
#include <AK/Assertions.h>
#include <AK/JsonObject.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/Palette.h>
#include <LibGUI/Action.h>
#include <LibGUI/Application.h>
#include <LibGUI/Button.h>
@ -46,6 +44,8 @@
#include <LibGUI/Widget.h>
#include <LibGUI/Window.h>
#include <LibGUI/WindowServerConnection.h>
#include <LibGfx/Bitmap.h>
#include <LibGfx/Palette.h>
#include <unistd.h>
namespace GUI {
@ -182,6 +182,8 @@ void Widget::event(Core::Event& event)
return handle_mouseup_event(static_cast<MouseEvent&>(event));
case Event::MouseWheel:
return mousewheel_event(static_cast<MouseEvent&>(event));
case Event::DragMove:
return drag_move_event(static_cast<DragEvent&>(event));
case Event::Drop:
return drop_event(static_cast<DropEvent&>(event));
case Event::Enter:
@ -379,6 +381,12 @@ void Widget::change_event(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::drop_event(DropEvent& event)
{
dbg() << class_name() << "{" << this << "} DROP position: " << event.position() << ", text: '" << event.text() << "'";

View file

@ -303,6 +303,7 @@ protected:
virtual void leave_event(Core::Event&);
virtual void child_event(Core::ChildEvent&) override;
virtual void change_event(Event&);
virtual void drag_move_event(DragEvent&);
virtual void drop_event(DropEvent&);
private:

View file

@ -319,6 +319,16 @@ void Window::event(Core::Event& event)
if (event.type() > Event::__Begin_WM_Events && event.type() < Event::__End_WM_Events)
return wm_event(static_cast<WMEvent&>(event));
if (event.type() == Event::DragMove) {
if (!m_main_widget)
return;
auto& drag_event = static_cast<DragEvent&>(event);
auto result = m_main_widget->hit_test(drag_event.position());
auto local_event = make<DragEvent>(static_cast<Event::Type>(drag_event.type()), result.local_position, drag_event.data_type());
ASSERT(result.widget);
return result.widget->dispatch_event(*local_event, this);
}
Core::Object::event(event);
}

View file

@ -24,8 +24,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <LibGfx/Palette.h>
#include <LibGfx/SystemTheme.h>
#include <LibGUI/Action.h>
#include <LibGUI/Application.h>
#include <LibGUI/Clipboard.h>
@ -36,6 +34,8 @@
#include <LibGUI/Widget.h>
#include <LibGUI/Window.h>
#include <LibGUI/WindowServerConnection.h>
#include <LibGfx/Palette.h>
#include <LibGfx/SystemTheme.h>
//#define GEVENTLOOP_DEBUG
@ -217,8 +217,12 @@ void WindowServerConnection::handle(const Messages::WindowClient::MouseMove& mes
dbgprintf("WID=%d MouseMove %d,%d,%d\n", message.window_id(), message.mouse_position().x(), message.mouse_position().y(), message.wheel_delta();
#endif
if (auto* window = Window::from_window_id(message.window_id()))
Core::EventLoop::current().post_event(*window, make<MouseEvent>(Event::MouseMove, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta()));
if (auto* window = Window::from_window_id(message.window_id())) {
if (message.is_drag())
Core::EventLoop::current().post_event(*window, make<DragEvent>(Event::DragMove, message.mouse_position(), message.drag_data_type()));
else
Core::EventLoop::current().post_event(*window, make<MouseEvent>(Event::MouseMove, message.mouse_position(), message.buttons(), to_gmousebutton(message.button()), message.modifiers(), message.wheel_delta()));
}
}
void WindowServerConnection::handle(const Messages::WindowClient::MouseDoubleClick& message)