mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 14:28:12 +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:
parent
af7cb7ce1b
commit
cfcb38dff1
13 changed files with 50 additions and 15 deletions
|
@ -247,6 +247,15 @@ GVariant GDirectoryModel::data(const GModelIndex& index, Role role) const
|
||||||
ASSERT(index.column() == Column::Name);
|
ASSERT(index.column() == Column::Name);
|
||||||
return entry.full_path(*this);
|
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) {
|
if (role == Role::Sort) {
|
||||||
switch (index.column()) {
|
switch (index.column()) {
|
||||||
case Column::Icon:
|
case Column::Icon:
|
||||||
|
|
|
@ -28,7 +28,7 @@ GDragOperation::Outcome GDragOperation::exec()
|
||||||
bitmap_size = shared_bitmap->size();
|
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()) {
|
if (!response->started()) {
|
||||||
m_outcome = Outcome::Cancelled;
|
m_outcome = Outcome::Cancelled;
|
||||||
return m_outcome;
|
return m_outcome;
|
||||||
|
|
|
@ -19,6 +19,11 @@ public:
|
||||||
|
|
||||||
void set_text(const String& text) { m_text = text; }
|
void set_text(const String& text) { m_text = text; }
|
||||||
void set_bitmap(const GraphicsBitmap* bitmap) { m_bitmap = bitmap; }
|
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 exec();
|
||||||
Outcome outcome() const { return m_outcome; }
|
Outcome outcome() const { return m_outcome; }
|
||||||
|
@ -35,5 +40,7 @@ private:
|
||||||
OwnPtr<CEventLoop> m_event_loop;
|
OwnPtr<CEventLoop> m_event_loop;
|
||||||
Outcome m_outcome { Outcome::None };
|
Outcome m_outcome { Outcome::None };
|
||||||
String m_text;
|
String m_text;
|
||||||
|
String m_data_type;
|
||||||
|
String m_data;
|
||||||
RefPtr<GraphicsBitmap> m_bitmap;
|
RefPtr<GraphicsBitmap> m_bitmap;
|
||||||
};
|
};
|
||||||
|
|
|
@ -282,17 +282,23 @@ private:
|
||||||
|
|
||||||
class GDropEvent final : public GEvent {
|
class GDropEvent final : public GEvent {
|
||||||
public:
|
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)
|
: GEvent(GEvent::Drop)
|
||||||
, m_position(position)
|
, m_position(position)
|
||||||
, m_text(text)
|
, m_text(text)
|
||||||
|
, m_data_type(data_type)
|
||||||
|
, m_data(data)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
const Point& position() const { return m_position; }
|
const Point& position() const { return m_position; }
|
||||||
const String& text() const { return m_text; }
|
const String& text() const { return m_text; }
|
||||||
|
const String& data_type() const { return m_data_type; }
|
||||||
|
const String& data() const { return m_data; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Point m_position;
|
Point m_position;
|
||||||
String m_text;
|
String m_text;
|
||||||
|
String m_data_type;
|
||||||
|
String m_data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -115,11 +115,16 @@ void GItemView::mousemove_event(GMouseEvent& event)
|
||||||
|
|
||||||
RefPtr<GraphicsBitmap> bitmap;
|
RefPtr<GraphicsBitmap> bitmap;
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder text_builder;
|
||||||
|
StringBuilder data_builder;
|
||||||
selection().for_each_index([&](auto& index) {
|
selection().for_each_index([&](auto& index) {
|
||||||
auto data = model()->data(index);
|
auto text_data = model()->data(index);
|
||||||
builder.append(data.to_string());
|
text_builder.append(text_data.to_string());
|
||||||
builder.append(" ");
|
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) {
|
if (!bitmap) {
|
||||||
GVariant icon_data = model()->data(index, GModel::Role::Icon);
|
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_bitmap(bitmap);
|
||||||
|
drag_operation->set_data("url-list", data_builder.to_string());
|
||||||
auto outcome = drag_operation->exec();
|
auto outcome = drag_operation->exec();
|
||||||
switch (outcome) {
|
switch (outcome) {
|
||||||
case GDragOperation::Outcome::Accepted:
|
case GDragOperation::Outcome::Accepted:
|
||||||
|
|
|
@ -36,6 +36,7 @@ public:
|
||||||
BackgroundColor,
|
BackgroundColor,
|
||||||
Icon,
|
Icon,
|
||||||
Font,
|
Font,
|
||||||
|
DragData,
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~GModel();
|
virtual ~GModel();
|
||||||
|
|
|
@ -159,7 +159,7 @@ void GWindow::event(CEvent& event)
|
||||||
if (!m_main_widget)
|
if (!m_main_widget)
|
||||||
return;
|
return;
|
||||||
auto result = m_main_widget->hit_test(drop_event.position());
|
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);
|
ASSERT(result.widget);
|
||||||
return result.widget->dispatch_event(*local_event, this);
|
return result.widget->dispatch_event(*local_event, this);
|
||||||
}
|
}
|
||||||
|
|
|
@ -266,7 +266,7 @@ void GWindowServerConnection::handle(const WindowClient::AsyncSetWallpaperFinish
|
||||||
void GWindowServerConnection::handle(const WindowClient::DragDropped& message)
|
void GWindowServerConnection::handle(const WindowClient::DragDropped& message)
|
||||||
{
|
{
|
||||||
if (auto* window = GWindow::from_window_id(message.window_id()))
|
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&)
|
void GWindowServerConnection::handle(const WindowClient::DragAccepted&)
|
||||||
|
|
|
@ -651,6 +651,6 @@ OwnPtr<WindowServer::StartDragResponse> WSClientConnection::handle(const WindowS
|
||||||
bitmap = GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *shared_buffer, message.bitmap_size());
|
bitmap = GraphicsBitmap::create_with_shared_buffer(GraphicsBitmap::Format::RGBA32, *shared_buffer, message.bitmap_size());
|
||||||
}
|
}
|
||||||
|
|
||||||
wm.start_dnd_drag(*this, message.text(), bitmap);
|
wm.start_dnd_drag(*this, message.text(), bitmap, message.data_type(), message.data());
|
||||||
return make<WindowServer::StartDragResponse>(true);
|
return make<WindowServer::StartDragResponse>(true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -649,7 +649,7 @@ bool WSWindowManager::process_ongoing_drag(WSMouseEvent& event, WSWindow*& hover
|
||||||
m_dnd_client->post_message(WindowClient::DragAccepted());
|
m_dnd_client->post_message(WindowClient::DragAccepted());
|
||||||
if (hovered_window->client()) {
|
if (hovered_window->client()) {
|
||||||
auto translated_event = event.translated(-hovered_window->position());
|
auto translated_event = event.translated(-hovered_window->position());
|
||||||
hovered_window->client()->post_message(WindowClient::DragDropped(hovered_window->window_id(), translated_event.position(), m_dnd_text));
|
hovered_window->client()->post_message(WindowClient::DragDropped(hovered_window->window_id(), translated_event.position(), m_dnd_text, m_dnd_data_type, m_dnd_data));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
m_dnd_client->post_message(WindowClient::DragCancelled());
|
m_dnd_client->post_message(WindowClient::DragCancelled());
|
||||||
|
@ -1190,12 +1190,14 @@ WSMenu* WSWindowManager::find_internal_menu_by_id(int menu_id)
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WSWindowManager::start_dnd_drag(WSClientConnection& client, const String& text, GraphicsBitmap* bitmap)
|
void WSWindowManager::start_dnd_drag(WSClientConnection& client, const String& text, GraphicsBitmap* bitmap, const String& data_type, const String& data)
|
||||||
{
|
{
|
||||||
ASSERT(!m_dnd_client);
|
ASSERT(!m_dnd_client);
|
||||||
m_dnd_client = client.make_weak_ptr();
|
m_dnd_client = client.make_weak_ptr();
|
||||||
m_dnd_text = text;
|
m_dnd_text = text;
|
||||||
m_dnd_bitmap = bitmap;
|
m_dnd_bitmap = bitmap;
|
||||||
|
m_dnd_data_type = data_type;
|
||||||
|
m_dnd_data = data;
|
||||||
WSCompositor::the().invalidate_cursor();
|
WSCompositor::the().invalidate_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -68,10 +68,12 @@ public:
|
||||||
|
|
||||||
WSClientConnection* dnd_client() { return m_dnd_client.ptr(); }
|
WSClientConnection* dnd_client() { return m_dnd_client.ptr(); }
|
||||||
const String& dnd_text() const { return m_dnd_text; }
|
const String& dnd_text() const { return m_dnd_text; }
|
||||||
|
const String& dnd_data_type() const { return m_dnd_data_type; }
|
||||||
|
const String& dnd_data() const { return m_dnd_data; }
|
||||||
const GraphicsBitmap* dnd_bitmap() const { return m_dnd_bitmap; }
|
const GraphicsBitmap* dnd_bitmap() const { return m_dnd_bitmap; }
|
||||||
Rect dnd_rect() const;
|
Rect dnd_rect() const;
|
||||||
|
|
||||||
void start_dnd_drag(WSClientConnection&, const String& text, GraphicsBitmap*);
|
void start_dnd_drag(WSClientConnection&, const String& text, GraphicsBitmap*, const String& data_type, const String& data);
|
||||||
void end_dnd_drag();
|
void end_dnd_drag();
|
||||||
|
|
||||||
WSWindow* active_window() { return m_active_window.ptr(); }
|
WSWindow* active_window() { return m_active_window.ptr(); }
|
||||||
|
@ -283,6 +285,8 @@ private:
|
||||||
|
|
||||||
WeakPtr<WSClientConnection> m_dnd_client;
|
WeakPtr<WSClientConnection> m_dnd_client;
|
||||||
String m_dnd_text;
|
String m_dnd_text;
|
||||||
|
String m_dnd_data_type;
|
||||||
|
String m_dnd_data;
|
||||||
RefPtr<GraphicsBitmap> m_dnd_bitmap;
|
RefPtr<GraphicsBitmap> m_dnd_bitmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,5 +31,5 @@ endpoint WindowClient = 4
|
||||||
DragAccepted() =|
|
DragAccepted() =|
|
||||||
DragCancelled() =|
|
DragCancelled() =|
|
||||||
|
|
||||||
DragDropped(i32 window_id, Point mouse_position, String text) =|
|
DragDropped(i32 window_id, Point mouse_position, String text, String data_type, String data) =|
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,5 +67,5 @@ endpoint WindowServer = 2
|
||||||
GetWallpaper() => (String path)
|
GetWallpaper() => (String path)
|
||||||
SetWindowOverrideCursor(i32 window_id, i32 cursor_type) => ()
|
SetWindowOverrideCursor(i32 window_id, i32 cursor_type) => ()
|
||||||
|
|
||||||
StartDrag(String text, i32 bitmap_id, Size bitmap_size) => (bool started)
|
StartDrag(String text, String data_type, String data, i32 bitmap_id, Size bitmap_size) => (bool started)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue