mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 11:45:06 +00:00
LibGUI+WindowServer: Start fleshing out drag&drop functionality
This patch enables basic drag&drop between applications. You initiate a drag by creating a GDragOperation object and calling exec() on it. This creates a nested event loop in the calling program that only returns once the drag operation has ended. On the receiving side, you get a call to GWidget::drop_event() with a GDropEvent containing information about the dropped data. The only data passed right now is a piece of text that's also used to visually indicate that a drag is happening (by showing the text in a little box that follows the mouse cursor around.) There are things to fix here, but we're off to a nice start. :^)
This commit is contained in:
parent
e09a02ad3f
commit
a7f414bba7
19 changed files with 318 additions and 3 deletions
|
@ -1,4 +1,6 @@
|
|||
#include <AK/StringBuilder.h>
|
||||
#include <Kernel/KeyCode.h>
|
||||
#include <LibGUI/GDragOperation.h>
|
||||
#include <LibGUI/GItemView.h>
|
||||
#include <LibGUI/GModel.h>
|
||||
#include <LibGUI/GPainter.h>
|
||||
|
@ -83,6 +85,7 @@ void GItemView::mousedown_event(GMouseEvent& event)
|
|||
int item_index = item_at_event_position(event.position());
|
||||
|
||||
if (event.button() == GMouseButton::Left) {
|
||||
m_left_mousedown_position = event.position();
|
||||
if (item_index == -1) {
|
||||
selection().clear();
|
||||
} else {
|
||||
|
@ -97,6 +100,45 @@ void GItemView::mousedown_event(GMouseEvent& event)
|
|||
GAbstractView::mousedown_event(event);
|
||||
}
|
||||
|
||||
void GItemView::mousemove_event(GMouseEvent& event)
|
||||
{
|
||||
if (!model())
|
||||
return GAbstractView::mousemove_event(event);
|
||||
|
||||
if (event.buttons() & GMouseButton::Left && !selection().is_empty()) {
|
||||
auto diff = event.position() - m_left_mousedown_position;
|
||||
auto distance_travelled_squared = diff.x() * diff.x() + diff.y() * diff.y();
|
||||
constexpr int drag_distance_threshold = 5;
|
||||
if (distance_travelled_squared > (drag_distance_threshold)) {
|
||||
dbg() << "Initiate drag!";
|
||||
auto drag_operation = GDragOperation::construct();
|
||||
|
||||
StringBuilder builder;
|
||||
selection().for_each_index([&](auto& index) {
|
||||
auto data = model()->data(index);
|
||||
builder.append(data.to_string());
|
||||
builder.append(" ");
|
||||
});
|
||||
|
||||
drag_operation->set_text(builder.to_string());
|
||||
auto outcome = drag_operation->exec();
|
||||
switch (outcome) {
|
||||
case GDragOperation::Outcome::Accepted:
|
||||
dbg() << "Drag was accepted!";
|
||||
break;
|
||||
case GDragOperation::Outcome::Cancelled:
|
||||
dbg() << "Drag was cancelled!";
|
||||
break;
|
||||
default:
|
||||
ASSERT_NOT_REACHED();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GAbstractView::mousemove_event(event);
|
||||
}
|
||||
|
||||
void GItemView::context_menu_event(GContextMenuEvent& event)
|
||||
{
|
||||
if (!model())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue