mirror of
https://github.com/SerenityOS/serenity
synced 2024-10-15 04:13:11 +00:00
LibGUI: Add a way for models to update without invalidating indexes
This is really just a workaround to keep SystemMonitor's process table working right wrt selection retention during resorts (while also doing full index invalidation on things like ProfileViewer inversion.) It's starting to feel like the model abstraction is not super great and we'll need a better approach if we want to actually build some more dynamic functionality into our views.
This commit is contained in:
parent
93f2a4edd3
commit
8e4751a963
|
@ -412,5 +412,5 @@ void ProcessModel::update()
|
|||
if (on_new_cpu_data_point)
|
||||
on_new_cpu_data_point(total_cpu_percent);
|
||||
|
||||
did_update();
|
||||
did_update(GUI::Model::UpdateFlag::DontInvalidateIndexes);
|
||||
}
|
||||
|
|
|
@ -146,5 +146,5 @@ GUI::Variant ProfileModel::data(const GUI::ModelIndex& index, Role role) const
|
|||
|
||||
void ProfileModel::update()
|
||||
{
|
||||
did_update();
|
||||
did_update(Model::InvalidateAllIndexes);
|
||||
}
|
||||
|
|
|
@ -566,9 +566,9 @@ Gfx::Point AbstractTableView::adjusted_position(const Gfx::Point& position) cons
|
|||
return position.translated(horizontal_scrollbar().value() - frame_thickness(), vertical_scrollbar().value() - frame_thickness());
|
||||
}
|
||||
|
||||
void AbstractTableView::did_update_model()
|
||||
void AbstractTableView::did_update_model(unsigned flags)
|
||||
{
|
||||
AbstractView::did_update_model();
|
||||
AbstractView::did_update_model(flags);
|
||||
update_column_sizes();
|
||||
update_content_size();
|
||||
update();
|
||||
|
|
|
@ -75,7 +75,7 @@ protected:
|
|||
virtual ~AbstractTableView() override;
|
||||
AbstractTableView();
|
||||
|
||||
virtual void did_update_model() override;
|
||||
virtual void did_update_model(unsigned flags) override;
|
||||
virtual void mouseup_event(MouseEvent&) override;
|
||||
virtual void mousedown_event(MouseEvent&) override;
|
||||
virtual void mousemove_event(MouseEvent&) override;
|
||||
|
|
|
@ -55,19 +55,22 @@ void AbstractView::set_model(RefPtr<Model> model)
|
|||
m_model = move(model);
|
||||
if (m_model)
|
||||
m_model->register_view({}, *this);
|
||||
did_update_model();
|
||||
did_update_model(GUI::Model::InvalidateAllIndexes);
|
||||
}
|
||||
|
||||
void AbstractView::did_update_model()
|
||||
void AbstractView::did_update_model(unsigned flags)
|
||||
{
|
||||
// FIXME: It's unfortunate that we lose so much view state when the model updates in any way.
|
||||
stop_editing();
|
||||
m_edit_index = {};
|
||||
m_hovered_index = {};
|
||||
if (model()) {
|
||||
selection().remove_matching([this](auto& index) { return !model()->is_valid(index); });
|
||||
} else {
|
||||
|
||||
dbg() << "did_update_model, flags=" << flags;
|
||||
dump_backtrace();
|
||||
if (!model() || (flags & GUI::Model::InvalidateAllIndexes)) {
|
||||
selection().clear();
|
||||
} else {
|
||||
selection().remove_matching([this](auto& index) { return !model()->is_valid(index); });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ public:
|
|||
void set_editable(bool editable) { m_editable = editable; }
|
||||
|
||||
virtual bool accepts_focus() const override { return true; }
|
||||
virtual void did_update_model();
|
||||
virtual void did_update_model(unsigned flags);
|
||||
virtual void did_update_selection();
|
||||
|
||||
virtual Gfx::Rect content_rect(const ModelIndex&) const { return {}; }
|
||||
|
|
|
@ -259,9 +259,9 @@ void ColumnsView::mousedown_event(MouseEvent& event)
|
|||
}
|
||||
}
|
||||
|
||||
void ColumnsView::did_update_model()
|
||||
void ColumnsView::did_update_model(unsigned flags)
|
||||
{
|
||||
AbstractView::did_update_model();
|
||||
AbstractView::did_update_model(flags);
|
||||
|
||||
// FIXME: Don't drop the columns on minor updates.
|
||||
dbg() << "Model was updated; dropping columns :(";
|
||||
|
|
|
@ -50,7 +50,7 @@ private:
|
|||
int icon_spacing() const { return 2; }
|
||||
int text_padding() const { return 2; }
|
||||
|
||||
virtual void did_update_model() override;
|
||||
virtual void did_update_model(unsigned flags) override;
|
||||
virtual void paint_event(PaintEvent&) override;
|
||||
virtual void mousedown_event(MouseEvent& event) override;
|
||||
virtual void keydown_event(KeyEvent& event) override;
|
||||
|
|
|
@ -68,9 +68,9 @@ void ItemView::resize_event(ResizeEvent& event)
|
|||
update_content_size();
|
||||
}
|
||||
|
||||
void ItemView::did_update_model()
|
||||
void ItemView::did_update_model(unsigned flags)
|
||||
{
|
||||
AbstractView::did_update_model();
|
||||
AbstractView::did_update_model(flags);
|
||||
update_content_size();
|
||||
update();
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
private:
|
||||
ItemView();
|
||||
|
||||
virtual void did_update_model() override;
|
||||
virtual void did_update_model(unsigned flags) override;
|
||||
virtual void paint_event(PaintEvent&) override;
|
||||
virtual void second_paint_event(PaintEvent&) override;
|
||||
virtual void resize_event(ResizeEvent&) override;
|
||||
|
|
|
@ -75,9 +75,9 @@ void ListView::resize_event(ResizeEvent& event)
|
|||
AbstractView::resize_event(event);
|
||||
}
|
||||
|
||||
void ListView::did_update_model()
|
||||
void ListView::did_update_model(unsigned flags)
|
||||
{
|
||||
AbstractView::did_update_model();
|
||||
AbstractView::did_update_model(flags);
|
||||
update_content_size();
|
||||
update();
|
||||
}
|
||||
|
|
|
@ -56,7 +56,7 @@ public:
|
|||
private:
|
||||
ListView();
|
||||
|
||||
virtual void did_update_model() override;
|
||||
virtual void did_update_model(unsigned flags) override;
|
||||
virtual void paint_event(PaintEvent&) override;
|
||||
virtual void doubleclick_event(MouseEvent&) override;
|
||||
virtual void keydown_event(KeyEvent&) override;
|
||||
|
|
|
@ -53,12 +53,12 @@ void Model::for_each_view(Function<void(AbstractView&)> callback)
|
|||
callback(*view);
|
||||
}
|
||||
|
||||
void Model::did_update()
|
||||
void Model::did_update(unsigned flags)
|
||||
{
|
||||
if (on_update)
|
||||
on_update();
|
||||
for_each_view([](auto& view) {
|
||||
view.did_update_model();
|
||||
for_each_view([&](auto& view) {
|
||||
view.did_update_model(flags);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,11 @@ public:
|
|||
Sortable sortable { Sortable::True };
|
||||
};
|
||||
|
||||
enum UpdateFlag {
|
||||
DontInvalidateIndexes = 0,
|
||||
InvalidateAllIndexes = 1 << 0,
|
||||
};
|
||||
|
||||
enum class Role {
|
||||
Display,
|
||||
Sort,
|
||||
|
@ -106,7 +111,7 @@ protected:
|
|||
Model();
|
||||
|
||||
void for_each_view(Function<void(AbstractView&)>);
|
||||
void did_update();
|
||||
void did_update(unsigned flags = UpdateFlag::InvalidateAllIndexes);
|
||||
|
||||
ModelIndex create_index(int row, int column, const void* data = nullptr) const;
|
||||
|
||||
|
|
|
@ -118,7 +118,7 @@ void SortingProxyModel::resort()
|
|||
for (int i = 0; i < row_count; ++i)
|
||||
m_row_mappings[i] = i;
|
||||
if (m_key_column == -1) {
|
||||
did_update();
|
||||
did_update(Model::UpdateFlag::DontInvalidateIndexes);
|
||||
return;
|
||||
}
|
||||
quick_sort(m_row_mappings, [&](auto row1, auto row2) -> bool {
|
||||
|
@ -133,7 +133,7 @@ void SortingProxyModel::resort()
|
|||
is_less_than = data1 < data2;
|
||||
return m_sort_order == SortOrder::Ascending ? is_less_than : !is_less_than;
|
||||
});
|
||||
did_update();
|
||||
did_update(Model::UpdateFlag::DontInvalidateIndexes);
|
||||
for_each_view([&](AbstractView& view) {
|
||||
auto& selection = view.selection();
|
||||
Vector<ModelIndex> selected_indexes_in_target;
|
||||
|
|
|
@ -326,10 +326,10 @@ void TreeView::scroll_into_view(const ModelIndex& a_index, Orientation orientati
|
|||
ScrollableWidget::scroll_into_view(found_rect, orientation);
|
||||
}
|
||||
|
||||
void TreeView::did_update_model()
|
||||
void TreeView::did_update_model(unsigned flags)
|
||||
{
|
||||
m_view_metadata.clear();
|
||||
AbstractTableView::did_update_model();
|
||||
AbstractTableView::did_update_model(flags);
|
||||
}
|
||||
|
||||
void TreeView::did_update_selection()
|
||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
|||
virtual void doubleclick_event(MouseEvent&) override;
|
||||
virtual void keydown_event(KeyEvent&) override;
|
||||
virtual void did_update_selection() override;
|
||||
virtual void did_update_model() override;
|
||||
virtual void did_update_model(unsigned flags) override;
|
||||
|
||||
private:
|
||||
virtual ModelIndex index_at_event_position(const Gfx::Point&, bool& is_toggle) const override;
|
||||
|
|
Loading…
Reference in a new issue