mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 12:38:12 +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
17 changed files with 37 additions and 29 deletions
|
@ -412,5 +412,5 @@ void ProcessModel::update()
|
||||||
if (on_new_cpu_data_point)
|
if (on_new_cpu_data_point)
|
||||||
on_new_cpu_data_point(total_cpu_percent);
|
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()
|
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());
|
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_column_sizes();
|
||||||
update_content_size();
|
update_content_size();
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -75,7 +75,7 @@ protected:
|
||||||
virtual ~AbstractTableView() override;
|
virtual ~AbstractTableView() override;
|
||||||
AbstractTableView();
|
AbstractTableView();
|
||||||
|
|
||||||
virtual void did_update_model() override;
|
virtual void did_update_model(unsigned flags) override;
|
||||||
virtual void mouseup_event(MouseEvent&) override;
|
virtual void mouseup_event(MouseEvent&) override;
|
||||||
virtual void mousedown_event(MouseEvent&) override;
|
virtual void mousedown_event(MouseEvent&) override;
|
||||||
virtual void mousemove_event(MouseEvent&) override;
|
virtual void mousemove_event(MouseEvent&) override;
|
||||||
|
|
|
@ -55,19 +55,22 @@ void AbstractView::set_model(RefPtr<Model> model)
|
||||||
m_model = move(model);
|
m_model = move(model);
|
||||||
if (m_model)
|
if (m_model)
|
||||||
m_model->register_view({}, *this);
|
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.
|
// FIXME: It's unfortunate that we lose so much view state when the model updates in any way.
|
||||||
stop_editing();
|
stop_editing();
|
||||||
m_edit_index = {};
|
m_edit_index = {};
|
||||||
m_hovered_index = {};
|
m_hovered_index = {};
|
||||||
if (model()) {
|
|
||||||
selection().remove_matching([this](auto& index) { return !model()->is_valid(index); });
|
dbg() << "did_update_model, flags=" << flags;
|
||||||
} else {
|
dump_backtrace();
|
||||||
|
if (!model() || (flags & GUI::Model::InvalidateAllIndexes)) {
|
||||||
selection().clear();
|
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; }
|
void set_editable(bool editable) { m_editable = editable; }
|
||||||
|
|
||||||
virtual bool accepts_focus() const override { return true; }
|
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 void did_update_selection();
|
||||||
|
|
||||||
virtual Gfx::Rect content_rect(const ModelIndex&) const { return {}; }
|
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.
|
// FIXME: Don't drop the columns on minor updates.
|
||||||
dbg() << "Model was updated; dropping columns :(";
|
dbg() << "Model was updated; dropping columns :(";
|
||||||
|
|
|
@ -50,7 +50,7 @@ private:
|
||||||
int icon_spacing() const { return 2; }
|
int icon_spacing() const { return 2; }
|
||||||
int text_padding() 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 paint_event(PaintEvent&) override;
|
||||||
virtual void mousedown_event(MouseEvent& event) override;
|
virtual void mousedown_event(MouseEvent& event) override;
|
||||||
virtual void keydown_event(KeyEvent& event) override;
|
virtual void keydown_event(KeyEvent& event) override;
|
||||||
|
|
|
@ -68,9 +68,9 @@ void ItemView::resize_event(ResizeEvent& event)
|
||||||
update_content_size();
|
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_content_size();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ public:
|
||||||
private:
|
private:
|
||||||
ItemView();
|
ItemView();
|
||||||
|
|
||||||
virtual void did_update_model() override;
|
virtual void did_update_model(unsigned flags) override;
|
||||||
virtual void paint_event(PaintEvent&) override;
|
virtual void paint_event(PaintEvent&) override;
|
||||||
virtual void second_paint_event(PaintEvent&) override;
|
virtual void second_paint_event(PaintEvent&) override;
|
||||||
virtual void resize_event(ResizeEvent&) override;
|
virtual void resize_event(ResizeEvent&) override;
|
||||||
|
|
|
@ -75,9 +75,9 @@ void ListView::resize_event(ResizeEvent& event)
|
||||||
AbstractView::resize_event(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_content_size();
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ public:
|
||||||
private:
|
private:
|
||||||
ListView();
|
ListView();
|
||||||
|
|
||||||
virtual void did_update_model() override;
|
virtual void did_update_model(unsigned flags) override;
|
||||||
virtual void paint_event(PaintEvent&) override;
|
virtual void paint_event(PaintEvent&) override;
|
||||||
virtual void doubleclick_event(MouseEvent&) override;
|
virtual void doubleclick_event(MouseEvent&) override;
|
||||||
virtual void keydown_event(KeyEvent&) override;
|
virtual void keydown_event(KeyEvent&) override;
|
||||||
|
|
|
@ -53,12 +53,12 @@ void Model::for_each_view(Function<void(AbstractView&)> callback)
|
||||||
callback(*view);
|
callback(*view);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Model::did_update()
|
void Model::did_update(unsigned flags)
|
||||||
{
|
{
|
||||||
if (on_update)
|
if (on_update)
|
||||||
on_update();
|
on_update();
|
||||||
for_each_view([](auto& view) {
|
for_each_view([&](auto& view) {
|
||||||
view.did_update_model();
|
view.did_update_model(flags);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,11 @@ public:
|
||||||
Sortable sortable { Sortable::True };
|
Sortable sortable { Sortable::True };
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum UpdateFlag {
|
||||||
|
DontInvalidateIndexes = 0,
|
||||||
|
InvalidateAllIndexes = 1 << 0,
|
||||||
|
};
|
||||||
|
|
||||||
enum class Role {
|
enum class Role {
|
||||||
Display,
|
Display,
|
||||||
Sort,
|
Sort,
|
||||||
|
@ -106,7 +111,7 @@ protected:
|
||||||
Model();
|
Model();
|
||||||
|
|
||||||
void for_each_view(Function<void(AbstractView&)>);
|
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;
|
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)
|
for (int i = 0; i < row_count; ++i)
|
||||||
m_row_mappings[i] = i;
|
m_row_mappings[i] = i;
|
||||||
if (m_key_column == -1) {
|
if (m_key_column == -1) {
|
||||||
did_update();
|
did_update(Model::UpdateFlag::DontInvalidateIndexes);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
quick_sort(m_row_mappings, [&](auto row1, auto row2) -> bool {
|
quick_sort(m_row_mappings, [&](auto row1, auto row2) -> bool {
|
||||||
|
@ -133,7 +133,7 @@ void SortingProxyModel::resort()
|
||||||
is_less_than = data1 < data2;
|
is_less_than = data1 < data2;
|
||||||
return m_sort_order == SortOrder::Ascending ? is_less_than : !is_less_than;
|
return m_sort_order == SortOrder::Ascending ? is_less_than : !is_less_than;
|
||||||
});
|
});
|
||||||
did_update();
|
did_update(Model::UpdateFlag::DontInvalidateIndexes);
|
||||||
for_each_view([&](AbstractView& view) {
|
for_each_view([&](AbstractView& view) {
|
||||||
auto& selection = view.selection();
|
auto& selection = view.selection();
|
||||||
Vector<ModelIndex> selected_indexes_in_target;
|
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);
|
ScrollableWidget::scroll_into_view(found_rect, orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeView::did_update_model()
|
void TreeView::did_update_model(unsigned flags)
|
||||||
{
|
{
|
||||||
m_view_metadata.clear();
|
m_view_metadata.clear();
|
||||||
AbstractTableView::did_update_model();
|
AbstractTableView::did_update_model(flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TreeView::did_update_selection()
|
void TreeView::did_update_selection()
|
||||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
||||||
virtual void doubleclick_event(MouseEvent&) override;
|
virtual void doubleclick_event(MouseEvent&) override;
|
||||||
virtual void keydown_event(KeyEvent&) override;
|
virtual void keydown_event(KeyEvent&) override;
|
||||||
virtual void did_update_selection() override;
|
virtual void did_update_selection() override;
|
||||||
virtual void did_update_model() override;
|
virtual void did_update_model(unsigned flags) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual ModelIndex index_at_event_position(const Gfx::Point&, bool& is_toggle) const override;
|
virtual ModelIndex index_at_event_position(const Gfx::Point&, bool& is_toggle) const override;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue