mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:38:11 +00:00
LibGUI: Make AbstractView accept drags (and delegate to model)
This commit is contained in:
parent
7baaa34490
commit
b08ed1b560
4 changed files with 50 additions and 21 deletions
|
@ -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.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* 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_edit_index = {};
|
||||||
m_hovered_index = {};
|
m_hovered_index = {};
|
||||||
m_cursor_index = {};
|
m_cursor_index = {};
|
||||||
|
m_drop_candidate_index = {};
|
||||||
clear_selection();
|
clear_selection();
|
||||||
} else {
|
} else {
|
||||||
// FIXME: These may no longer point to whatever they did before,
|
// 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 = {};
|
m_hovered_index = {};
|
||||||
if (!model()->is_valid(m_cursor_index))
|
if (!model()->is_valid(m_cursor_index))
|
||||||
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); });
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -153,6 +153,9 @@ protected:
|
||||||
virtual void mouseup_event(MouseEvent&) override;
|
virtual void mouseup_event(MouseEvent&) override;
|
||||||
virtual void doubleclick_event(MouseEvent&) override;
|
virtual void doubleclick_event(MouseEvent&) override;
|
||||||
virtual void context_menu_event(ContextMenuEvent&) 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 drop_event(DropEvent&) override;
|
||||||
virtual void leave_event(Core::Event&) override;
|
virtual void leave_event(Core::Event&) override;
|
||||||
virtual void hide_event(HideEvent&) override;
|
virtual void hide_event(HideEvent&) override;
|
||||||
|
@ -180,6 +183,8 @@ protected:
|
||||||
void do_search(String&&);
|
void do_search(String&&);
|
||||||
bool is_highlighting_searching(const ModelIndex&) const;
|
bool is_highlighting_searching(const ModelIndex&) const;
|
||||||
|
|
||||||
|
ModelIndex drop_candidate_index() const { return m_drop_candidate_index; }
|
||||||
|
|
||||||
bool m_editable { false };
|
bool m_editable { false };
|
||||||
bool m_searchable { true };
|
bool m_searchable { true };
|
||||||
ModelIndex m_edit_index;
|
ModelIndex m_edit_index;
|
||||||
|
@ -202,6 +207,7 @@ private:
|
||||||
String m_searching;
|
String m_searching;
|
||||||
RefPtr<Core::Timer> m_searching_timer;
|
RefPtr<Core::Timer> m_searching_timer;
|
||||||
ModelIndex m_cursor_index;
|
ModelIndex m_cursor_index;
|
||||||
|
ModelIndex m_drop_candidate_index;
|
||||||
SelectionBehavior m_selection_behavior { SelectionBehavior::SelectItems };
|
SelectionBehavior m_selection_behavior { SelectionBehavior::SelectItems };
|
||||||
SelectionMode m_selection_mode { SelectionMode::SingleSelection };
|
SelectionMode m_selection_mode { SelectionMode::SingleSelection };
|
||||||
unsigned m_edit_triggers { EditTrigger::DoubleClicked | EditTrigger::EditKeyPressed };
|
unsigned m_edit_triggers { EditTrigger::DoubleClicked | EditTrigger::EditKeyPressed };
|
||||||
|
|
|
@ -265,22 +265,6 @@ void IconView::mouseup_event(MouseEvent& event)
|
||||||
AbstractView::mouseup_event(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)
|
bool IconView::update_rubber_banding(const Gfx::IntPoint& position)
|
||||||
{
|
{
|
||||||
auto adjusted_position = to_content_position(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);
|
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..
|
// 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);
|
painter.draw_rect(item_data.icon_rect.inflated(8, 8), palette().selection(), true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -71,7 +71,6 @@ private:
|
||||||
virtual void mousedown_event(MouseEvent&) override;
|
virtual void mousedown_event(MouseEvent&) override;
|
||||||
virtual void mousemove_event(MouseEvent&) override;
|
virtual void mousemove_event(MouseEvent&) override;
|
||||||
virtual void mouseup_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_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;
|
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_origin;
|
||||||
Gfx::IntPoint m_rubber_band_current;
|
Gfx::IntPoint m_rubber_band_current;
|
||||||
|
|
||||||
ModelIndex m_drop_candidate_index;
|
|
||||||
|
|
||||||
FlowDirection m_flow_direction { FlowDirection::LeftToRight };
|
FlowDirection m_flow_direction { FlowDirection::LeftToRight };
|
||||||
|
|
||||||
mutable Vector<ItemData> m_item_data_cache;
|
mutable Vector<ItemData> m_item_data_cache;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue