mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-04 18:58:36 +00:00
Models: fix writing data doesn't update ListView model data property
This fixes a couple of bug: - Bug #3740 happens because `Repeater::model_set_row_data` did not use the inner.offset to get the instance (So that's the `val == 106` part of the test) - But I went ahead and also tested what happenned if you changed the model from the "outside" using the `model[i] = `, and that was not implemented, hence the move of the code from `Repeater::model_set_row_data` to `RepeaterTracker::row_changed`, That does need Pin though, so Pin was added everywhere - C++ is not affected by bug #3740, because because the C++ listview don't do the "allocate only visible" optimization. But the "val == 1106" part of the test would fail so this patch also moces the update from `model_set_row_data` to `row_changed`. But following that we don't set the state as Dirty in `row_changed`, the write_to_model test started filling because the `row_added` function was missing an update of the index on every further items The change in the interpreter prevent a borrow_mut from causing trouble. The Value really don't need to be in a RefCell anyway Fix #3740
This commit is contained in:
parent
924b2c8625
commit
d55803d290
7 changed files with 145 additions and 65 deletions
|
@ -1091,17 +1091,27 @@ class Repeater
|
|||
};
|
||||
std::vector<RepeatedInstanceWithState> data;
|
||||
private_api::Property<bool> is_dirty { true };
|
||||
std::shared_ptr<Model<ModelData>> model;
|
||||
|
||||
void row_added(size_t index, size_t count) override
|
||||
{
|
||||
is_dirty.set(true);
|
||||
data.resize(data.size() + count);
|
||||
std::rotate(data.begin() + index, data.end() - count, data.end());
|
||||
for (std::size_t i = index; i < data.size(); ++i) {
|
||||
// all the indexes are dirty
|
||||
data[i].state = State::Dirty;
|
||||
}
|
||||
}
|
||||
void row_changed(size_t index) override
|
||||
{
|
||||
is_dirty.set(true);
|
||||
data[index].state = State::Dirty;
|
||||
auto &c = data[index];
|
||||
if (model && c.ptr) {
|
||||
(*c.ptr)->update_data(index, *model->row_data(index));
|
||||
c.state = State::Clean;
|
||||
} else {
|
||||
c.state = State::Dirty;
|
||||
}
|
||||
}
|
||||
void row_removed(size_t index, size_t count) override
|
||||
{
|
||||
|
@ -1135,6 +1145,7 @@ public:
|
|||
if (model.is_dirty()) {
|
||||
inner = std::make_shared<RepeaterInner>();
|
||||
if (auto m = model.get()) {
|
||||
inner->model = m;
|
||||
m->attach_peer(inner);
|
||||
}
|
||||
}
|
||||
|
@ -1236,12 +1247,6 @@ public:
|
|||
if (auto m = model.get()) {
|
||||
if (row < m->row_count()) {
|
||||
m->set_row_data(row, data);
|
||||
if (inner && inner->is_dirty.get()) {
|
||||
auto &c = inner->data[row];
|
||||
if (c.state == RepeaterInner::State::Dirty && c.ptr) {
|
||||
(*c.ptr)->update_data(row, *m->row_data(row));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue