1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-26 00:27:43 +00:00

WindowServer+LibGUI: Add data_type and data fields to drag operations

These fields are intended to carry the real meat of a drag operation,
and the "text" is just for what we show on screen (alongside the cursor
during the actual drag.)

The data field is just a String for now, but in the future we should
make it something more flexible.
This commit is contained in:
Andreas Kling 2019-12-19 20:09:31 +01:00
parent af7cb7ce1b
commit cfcb38dff1
13 changed files with 50 additions and 15 deletions

View file

@ -247,6 +247,15 @@ GVariant GDirectoryModel::data(const GModelIndex& index, Role role) const
ASSERT(index.column() == Column::Name);
return entry.full_path(*this);
}
if (role == Role::DragData) {
if (index.column() == Column::Name) {
StringBuilder builder;
builder.append("file://");
builder.append(entry.full_path(*this));
return builder.to_string();
}
return {};
}
if (role == Role::Sort) {
switch (index.column()) {
case Column::Icon:

View file

@ -28,7 +28,7 @@ GDragOperation::Outcome GDragOperation::exec()
bitmap_size = shared_bitmap->size();
}
auto response = GWindowServerConnection::the().send_sync<WindowServer::StartDrag>(m_text, bitmap_id, bitmap_size);
auto response = GWindowServerConnection::the().send_sync<WindowServer::StartDrag>(m_text, m_data_type, m_data, bitmap_id, bitmap_size);
if (!response->started()) {
m_outcome = Outcome::Cancelled;
return m_outcome;

View file

@ -19,6 +19,11 @@ public:
void set_text(const String& text) { m_text = text; }
void set_bitmap(const GraphicsBitmap* bitmap) { m_bitmap = bitmap; }
void set_data(const String& data_type, const String& data)
{
m_data_type = data_type;
m_data = data;
}
Outcome exec();
Outcome outcome() const { return m_outcome; }
@ -35,5 +40,7 @@ private:
OwnPtr<CEventLoop> m_event_loop;
Outcome m_outcome { Outcome::None };
String m_text;
String m_data_type;
String m_data;
RefPtr<GraphicsBitmap> m_bitmap;
};

View file

@ -282,17 +282,23 @@ private:
class GDropEvent final : public GEvent {
public:
GDropEvent(const Point& position, const String& text)
GDropEvent(const Point& position, const String& text, const String& data_type, const String& data)
: GEvent(GEvent::Drop)
, m_position(position)
, m_text(text)
, m_data_type(data_type)
, m_data(data)
{
}
const Point& position() const { return m_position; }
const String& text() const { return m_text; }
const String& data_type() const { return m_data_type; }
const String& data() const { return m_data; }
private:
Point m_position;
String m_text;
String m_data_type;
String m_data;
};

View file

@ -115,11 +115,16 @@ void GItemView::mousemove_event(GMouseEvent& event)
RefPtr<GraphicsBitmap> bitmap;
StringBuilder builder;
StringBuilder text_builder;
StringBuilder data_builder;
selection().for_each_index([&](auto& index) {
auto data = model()->data(index);
builder.append(data.to_string());
builder.append(" ");
auto text_data = model()->data(index);
text_builder.append(text_data.to_string());
text_builder.append(" ");
auto drag_data = model()->data(index, GModel::Role::DragData);
data_builder.append(drag_data.to_string());
data_builder.append('\n');
if (!bitmap) {
GVariant icon_data = model()->data(index, GModel::Role::Icon);
@ -128,8 +133,9 @@ void GItemView::mousemove_event(GMouseEvent& event)
}
});
drag_operation->set_text(builder.to_string());
drag_operation->set_text(text_builder.to_string());
drag_operation->set_bitmap(bitmap);
drag_operation->set_data("url-list", data_builder.to_string());
auto outcome = drag_operation->exec();
switch (outcome) {
case GDragOperation::Outcome::Accepted:

View file

@ -36,6 +36,7 @@ public:
BackgroundColor,
Icon,
Font,
DragData,
};
virtual ~GModel();

View file

@ -159,7 +159,7 @@ void GWindow::event(CEvent& event)
if (!m_main_widget)
return;
auto result = m_main_widget->hit_test(drop_event.position());
auto local_event = make<GDropEvent>(result.local_position, drop_event.text());
auto local_event = make<GDropEvent>(result.local_position, drop_event.text(), drop_event.data_type(), drop_event.data());
ASSERT(result.widget);
return result.widget->dispatch_event(*local_event, this);
}

View file

@ -266,7 +266,7 @@ void GWindowServerConnection::handle(const WindowClient::AsyncSetWallpaperFinish
void GWindowServerConnection::handle(const WindowClient::DragDropped& message)
{
if (auto* window = GWindow::from_window_id(message.window_id()))
CEventLoop::current().post_event(*window, make<GDropEvent>(message.mouse_position(), message.text()));
CEventLoop::current().post_event(*window, make<GDropEvent>(message.mouse_position(), message.text(), message.data_type(), message.data()));
}
void GWindowServerConnection::handle(const WindowClient::DragAccepted&)