summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2021-01-09 11:36:49 +0100
committerAndreas Kling <kling@serenityos.org>2021-01-09 12:02:07 +0100
commitb08ed1b5602c8f1dd28d8b1782605bf04624be74 (patch)
tree6533f51867b93dcd33e9fb41ac1ede52cb83aea9
parent7baaa34490585740c4500efcc5cc033932f04d26 (diff)
downloadserenity-b08ed1b5602c8f1dd28d8b1782605bf04624be74.zip
LibGUI: Make AbstractView accept drags (and delegate to model)
-rw-r--r--Libraries/LibGUI/AbstractView.cpp44
-rw-r--r--Libraries/LibGUI/AbstractView.h6
-rw-r--r--Libraries/LibGUI/IconView.cpp18
-rw-r--r--Libraries/LibGUI/IconView.h3
4 files changed, 50 insertions, 21 deletions
diff --git a/Libraries/LibGUI/AbstractView.cpp b/Libraries/LibGUI/AbstractView.cpp
index 8a4f0618fd..d74e630cd1 100644
--- a/Libraries/LibGUI/AbstractView.cpp
+++ b/Libraries/LibGUI/AbstractView.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
+ * Copyright (c) 2018-2021, Andreas Kling <kling@serenityos.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -74,6 +74,7 @@ void AbstractView::model_did_update(unsigned int flags)
m_edit_index = {};
m_hovered_index = {};
m_cursor_index = {};
+ m_drop_candidate_index = {};
clear_selection();
} else {
// FIXME: These may no longer point to whatever they did before,
@@ -86,6 +87,8 @@ void AbstractView::model_did_update(unsigned int flags)
m_hovered_index = {};
if (!model()->is_valid(m_cursor_index))
m_cursor_index = {};
+ if (!model()->is_valid(m_drop_candidate_index))
+ m_drop_candidate_index = {};
selection().remove_matching([this](auto& index) { return !model()->is_valid(index); });
}
}
@@ -720,4 +723,43 @@ void AbstractView::focusin_event(FocusEvent& event)
}
}
+void AbstractView::drag_enter_event(DragEvent& event)
+{
+ if (!model())
+ return;
+ // NOTE: Right now, AbstractView always accepts drags since we won't get "drag move" events
+ // unless we accept the "drag enter" event.
+ // We might be able to reduce event traffic by communicating the set of drag-accepting
+ // rects in this widget to the windowing system somehow.
+ event.accept();
+ dbgln("accepting drag of {}", event.mime_types().first());
+}
+
+void AbstractView::drag_move_event(DragEvent& event)
+{
+ if (!model())
+ return;
+ auto index = index_at_event_position(event.position());
+ ModelIndex new_drop_candidate_index;
+ if (index.is_valid()) {
+ bool acceptable = model()->accepts_drag(index, event.mime_types());
+ if (acceptable)
+ new_drop_candidate_index = index;
+ }
+ if (m_drop_candidate_index != new_drop_candidate_index) {
+ m_drop_candidate_index = new_drop_candidate_index;
+ update();
+ }
+ if (m_drop_candidate_index.is_valid())
+ event.accept();
+}
+
+void AbstractView::drag_leave_event(Event&)
+{
+ if (m_drop_candidate_index.is_valid()) {
+ m_drop_candidate_index = {};
+ update();
+ }
+}
+
}
diff --git a/Libraries/LibGUI/AbstractView.h b/Libraries/LibGUI/AbstractView.h
index c543b39247..e8ce1f0114 100644
--- a/Libraries/LibGUI/AbstractView.h
+++ b/Libraries/LibGUI/AbstractView.h
@@ -153,6 +153,9 @@ protected:
virtual void mouseup_event(MouseEvent&) override;
virtual void doubleclick_event(MouseEvent&) override;
virtual void context_menu_event(ContextMenuEvent&) override;
+ virtual void drag_enter_event(DragEvent&) override;
+ virtual void drag_move_event(DragEvent&) override;
+ virtual void drag_leave_event(Event&) override;
virtual void drop_event(DropEvent&) override;
virtual void leave_event(Core::Event&) override;
virtual void hide_event(HideEvent&) override;
@@ -180,6 +183,8 @@ protected:
void do_search(String&&);
bool is_highlighting_searching(const ModelIndex&) const;
+ ModelIndex drop_candidate_index() const { return m_drop_candidate_index; }
+
bool m_editable { false };
bool m_searchable { true };
ModelIndex m_edit_index;
@@ -202,6 +207,7 @@ private:
String m_searching;
RefPtr<Core::Timer> m_searching_timer;
ModelIndex m_cursor_index;
+ ModelIndex m_drop_candidate_index;
SelectionBehavior m_selection_behavior { SelectionBehavior::SelectItems };
SelectionMode m_selection_mode { SelectionMode::SingleSelection };
unsigned m_edit_triggers { EditTrigger::DoubleClicked | EditTrigger::EditKeyPressed };
diff --git a/Libraries/LibGUI/IconView.cpp b/Libraries/LibGUI/IconView.cpp
index 51c3801c0f..a034cc3f55 100644
--- a/Libraries/LibGUI/IconView.cpp
+++ b/Libraries/LibGUI/IconView.cpp
@@ -265,22 +265,6 @@ void IconView::mouseup_event(MouseEvent& event)
AbstractView::mouseup_event(event);
}
-void IconView::drag_move_event(DragEvent& event)
-{
- auto index = index_at_event_position(event.position());
- ModelIndex new_drop_candidate_index;
- if (index.is_valid()) {
- bool acceptable = model()->accepts_drag(index, event.mime_types());
- if (acceptable)
- new_drop_candidate_index = index;
- }
- if (m_drop_candidate_index != new_drop_candidate_index) {
- m_drop_candidate_index = new_drop_candidate_index;
- update();
- }
- event.accept();
-}
-
bool IconView::update_rubber_banding(const Gfx::IntPoint& position)
{
auto adjusted_position = to_content_position(position);
@@ -577,7 +561,7 @@ void IconView::paint_event(PaintEvent& event)
draw_item_text(painter, item_data.index, item_data.selected, item_data.text_rect, item_data.text, font, Gfx::TextAlignment::Center, Gfx::TextElision::Right);
}
- if (item_data.index == m_drop_candidate_index) {
+ if (item_data.index == drop_candidate_index()) {
// FIXME: This visualization is not great, as it's also possible to drop things on the text label..
painter.draw_rect(item_data.icon_rect.inflated(8, 8), palette().selection(), true);
}
diff --git a/Libraries/LibGUI/IconView.h b/Libraries/LibGUI/IconView.h
index 72409d2997..c36960a1e2 100644
--- a/Libraries/LibGUI/IconView.h
+++ b/Libraries/LibGUI/IconView.h
@@ -71,7 +71,6 @@ private:
virtual void mousedown_event(MouseEvent&) override;
virtual void mousemove_event(MouseEvent&) override;
virtual void mouseup_event(MouseEvent&) override;
- virtual void drag_move_event(DragEvent&) override;
virtual void did_change_hovered_index(const ModelIndex& old_index, const ModelIndex& new_index) override;
virtual void did_change_cursor_index(const ModelIndex& old_index, const ModelIndex& new_index) override;
@@ -165,8 +164,6 @@ private:
Gfx::IntPoint m_rubber_band_origin;
Gfx::IntPoint m_rubber_band_current;
- ModelIndex m_drop_candidate_index;
-
FlowDirection m_flow_direction { FlowDirection::LeftToRight };
mutable Vector<ItemData> m_item_data_cache;