diff options
author | Andreas Kling <kling@serenityos.org> | 2021-01-09 11:36:49 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-01-09 12:02:07 +0100 |
commit | b08ed1b5602c8f1dd28d8b1782605bf04624be74 (patch) | |
tree | 6533f51867b93dcd33e9fb41ac1ede52cb83aea9 | |
parent | 7baaa34490585740c4500efcc5cc033932f04d26 (diff) | |
download | serenity-b08ed1b5602c8f1dd28d8b1782605bf04624be74.zip |
LibGUI: Make AbstractView accept drags (and delegate to model)
-rw-r--r-- | Libraries/LibGUI/AbstractView.cpp | 44 | ||||
-rw-r--r-- | Libraries/LibGUI/AbstractView.h | 6 | ||||
-rw-r--r-- | Libraries/LibGUI/IconView.cpp | 18 | ||||
-rw-r--r-- | Libraries/LibGUI/IconView.h | 3 |
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; |