mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-02 06:41:14 +00:00
Fix listview not updating its geometry in Rust when the entire model is changed
The geometry tracker did not track the model property itself, so it did not become dirty. Fixes #500
This commit is contained in:
parent
cd5385887b
commit
5742a122ed
2 changed files with 97 additions and 0 deletions
|
@ -618,6 +618,9 @@ impl<C: RepeatedComponent + 'static> Repeater<C> {
|
||||||
|
|
||||||
let geometry_changed = listview_geometry_tracker
|
let geometry_changed = listview_geometry_tracker
|
||||||
.evaluate_if_dirty(|| {
|
.evaluate_if_dirty(|| {
|
||||||
|
// Fetch the model again to make sure that it is a dependency of this geometry tracker.
|
||||||
|
let model = self.model().0.expect("invariant: model existence was checked earlier");
|
||||||
|
|
||||||
let listview_height = listview_height.get();
|
let listview_height = listview_height.get();
|
||||||
// Compute the element height
|
// Compute the element height
|
||||||
let total_height = Cell::new(0.);
|
let total_height = Cell::new(0.);
|
||||||
|
|
94
tests/cases/models/listview_model_change.60
Normal file
94
tests/cases/models/listview_model_change.60
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
/* LICENSE BEGIN
|
||||||
|
This file is part of the SixtyFPS Project -- https://sixtyfps.io
|
||||||
|
Copyright (c) 2021 Olivier Goffart <olivier.goffart@sixtyfps.io>
|
||||||
|
Copyright (c) 2021 Simon Hausmann <simon.hausmann@sixtyfps.io>
|
||||||
|
|
||||||
|
SPDX-License-Identifier: GPL-3.0-only
|
||||||
|
This file is also available under commercial licensing terms.
|
||||||
|
Please contact info@sixtyfps.io for more information.
|
||||||
|
LICENSE END */
|
||||||
|
|
||||||
|
// This test case verifies that the listview updates its layout / geometry when the
|
||||||
|
// entire model changes. This test works by triggering layout updates by simulating
|
||||||
|
// mouse clicks, which results in item tree traversal and ensure_updated_listview
|
||||||
|
// calls, similar to when painting. The actual model change is triggered via simulated
|
||||||
|
// mouse clicks into the touch area further down.
|
||||||
|
// Note: The C++ test uses the same test method, but due to its differing implementation
|
||||||
|
// it's not testing the same code path.
|
||||||
|
|
||||||
|
import { ListView } from "sixtyfps_widgets.60";
|
||||||
|
|
||||||
|
TestCase := Window {
|
||||||
|
width: 100px;
|
||||||
|
height: 100px;
|
||||||
|
|
||||||
|
property<length> viewport-height: lv.viewport-height;
|
||||||
|
property<[length]> fixed-height-model: [100px];
|
||||||
|
|
||||||
|
lv := ListView {
|
||||||
|
for fixed-height in fixed-height-model: Rectangle {
|
||||||
|
background: blue;
|
||||||
|
height: fixed-height;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TouchArea {
|
||||||
|
y: 50px;
|
||||||
|
clicked => {
|
||||||
|
fixed-height-model = [200px];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
```cpp
|
||||||
|
auto handle = TestCase::create();
|
||||||
|
const TestCase &instance = *handle;
|
||||||
|
|
||||||
|
// Send an initial click to traverse the item tree and force a listview
|
||||||
|
// layout.
|
||||||
|
sixtyfps::testing::send_mouse_click(&instance, 5., 5.);
|
||||||
|
assert_eq(instance.get_viewport_height(), 100.);
|
||||||
|
|
||||||
|
// Trigger the mouse area to change the model
|
||||||
|
sixtyfps::testing::send_mouse_click(&instance, 5., 55.);
|
||||||
|
|
||||||
|
// Send a second click to force an item tree traversal and listview update
|
||||||
|
sixtyfps::testing::send_mouse_click(&instance, 5., 5.);
|
||||||
|
assert_eq(instance.get_viewport_height(), 200.);
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
```rust
|
||||||
|
let instance = TestCase::new();
|
||||||
|
|
||||||
|
// Send an initial click to traverse the item tree and force a listview
|
||||||
|
// layout.
|
||||||
|
sixtyfps::testing::send_mouse_click(&instance, 5., 5.);
|
||||||
|
assert_eq!(instance.get_viewport_height(), 100.);
|
||||||
|
|
||||||
|
// Trigger the mouse area to change the model
|
||||||
|
sixtyfps::testing::send_mouse_click(&instance, 5., 55.);
|
||||||
|
|
||||||
|
// Send a second click to force an item tree traversal and listview update
|
||||||
|
sixtyfps::testing::send_mouse_click(&instance, 5., 5.);
|
||||||
|
assert_eq!(instance.get_viewport_height(), 200.);
|
||||||
|
```
|
||||||
|
|
||||||
|
```js
|
||||||
|
var instance = new sixtyfps.TestCase();
|
||||||
|
|
||||||
|
// Send an initial click to traverse the item tree and force a listview
|
||||||
|
// layout.
|
||||||
|
instance.send_mouse_click(5., 5.);
|
||||||
|
assert.equal(instance.viewport_height, 100.);
|
||||||
|
|
||||||
|
// Trigger the mouse area to change the model
|
||||||
|
instance.send_mouse_click(5., 55.);
|
||||||
|
|
||||||
|
// Send a second click to force an item tree traversal and listview update
|
||||||
|
instance.send_mouse_click(5., 5.);
|
||||||
|
assert.equal(instance.viewport_height, 200.);
|
||||||
|
```
|
||||||
|
*/
|
Loading…
Add table
Add a link
Reference in a new issue