summaryrefslogtreecommitdiff
path: root/Libraries
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-02-13 21:43:32 +0100
committerAndreas Kling <kling@serenityos.org>2020-02-13 21:43:32 +0100
commit3ce80bec97551bbcd850ce3e457fca1c06c48439 (patch)
tree5723f47ec0204e8b891d14ec67f272899fd4558f /Libraries
parent7590270e138b38960d6f71f1c120808270bf3794 (diff)
downloadserenity-3ce80bec97551bbcd850ce3e457fca1c06c48439.zip
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.
Diffstat (limited to 'Libraries')
-rw-r--r--Libraries/LibGUI/Event.h18
-rw-r--r--Libraries/LibGUI/Widget.cpp12
-rw-r--r--Libraries/LibGUI/Widget.h1
-rw-r--r--Libraries/LibGUI/Window.cpp10
-rw-r--r--Libraries/LibGUI/WindowServerConnection.cpp12
5 files changed, 47 insertions, 6 deletions
diff --git a/Libraries/LibGUI/Event.h b/Libraries/LibGUI/Event.h
index 7b6b472176..c518a694a1 100644
--- a/Libraries/LibGUI/Event.h
+++ b/Libraries/LibGUI/Event.h
@@ -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)
diff --git a/Libraries/LibGUI/Widget.cpp b/Libraries/LibGUI/Widget.cpp
index b4b2ccc084..0997b52773 100644
--- a/Libraries/LibGUI/Widget.cpp
+++ b/Libraries/LibGUI/Widget.cpp
@@ -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() << "'";
diff --git a/Libraries/LibGUI/Widget.h b/Libraries/LibGUI/Widget.h
index 9ecb8fe8c1..d294673dca 100644
--- a/Libraries/LibGUI/Widget.h
+++ b/Libraries/LibGUI/Widget.h
@@ -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:
diff --git a/Libraries/LibGUI/Window.cpp b/Libraries/LibGUI/Window.cpp
index c93e9d00e8..a0b5dc87c2 100644
--- a/Libraries/LibGUI/Window.cpp
+++ b/Libraries/LibGUI/Window.cpp
@@ -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);
}
diff --git a/Libraries/LibGUI/WindowServerConnection.cpp b/Libraries/LibGUI/WindowServerConnection.cpp
index 3ea6a6a572..bfcc000f2e 100644
--- a/Libraries/LibGUI/WindowServerConnection.cpp
+++ b/Libraries/LibGUI/WindowServerConnection.cpp
@@ -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)