mirror of
https://github.com/slint-ui/slint.git
synced 2025-09-09 03:50:34 +00:00
Fix ListView panic when setting a new model
.. that has less items and the ListView is scrolled. We should not have an offset that is higher than the current count otherwise we're going to access invalid item in the model Fix #2780
This commit is contained in:
parent
69cec30748
commit
bef2e3617d
2 changed files with 66 additions and 0 deletions
|
@ -962,6 +962,10 @@ impl<C: RepeatedComponent + 'static> Repeater<C> {
|
|||
|
||||
let data = self.data();
|
||||
let mut inner = data.inner.borrow_mut();
|
||||
if inner.offset >= row_count {
|
||||
inner.offset = row_count - 1;
|
||||
}
|
||||
|
||||
let one_and_a_half_screen = listview_height * 3 as Coord / 2 as Coord;
|
||||
let first_item_y = inner.anchor_y;
|
||||
let last_item_bottom = first_item_y + element_height * inner.components.len() as Coord;
|
||||
|
|
62
tests/cases/issues/issue_2780_listview_crash.slint
Normal file
62
tests/cases/issues/issue_2780_listview_crash.slint
Normal file
|
@ -0,0 +1,62 @@
|
|||
// Copyright © SixtyFPS GmbH <info@slint-ui.com>
|
||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-commercial
|
||||
|
||||
// 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 "std-widgets.slint";
|
||||
|
||||
export component TestCase inherits Window {
|
||||
width: 300px;
|
||||
height: 300px;
|
||||
|
||||
in-out property pos <=> lv.viewport-y;
|
||||
out property <int> clicked-idx: -1;
|
||||
in-out property<[color]> the_model: [Colors.red, Colors.blue, Colors.yellow, Colors.pink, Colors.orange, Colors.aliceblue, Colors.limegreen];
|
||||
lv := ListView {
|
||||
for col[idx] in the_model: Rectangle {
|
||||
height: 100px;
|
||||
background: col;
|
||||
TouchArea {
|
||||
clicked => {
|
||||
clicked-idx = idx;
|
||||
the_model = [Colors.gray];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
```cpp
|
||||
auto handle = TestCase::create();
|
||||
const TestCase &instance = *handle;
|
||||
|
||||
|
||||
instance.set_pos(-400.);
|
||||
|
||||
slint_testing::send_mouse_click(&instance, 5., 5.);
|
||||
assert_eq(instance.get_clicked_idx(), 4);
|
||||
|
||||
slint_testing::send_mouse_click(&instance, 5., 5.);
|
||||
```
|
||||
|
||||
```rust
|
||||
let instance = TestCase::new().unwrap();
|
||||
|
||||
instance.set_pos(-400.);
|
||||
|
||||
slint_testing::send_mouse_click(&instance, 5., 5.);
|
||||
assert_eq!(instance.get_clicked_idx(), 4);
|
||||
|
||||
slint_testing::send_mouse_click(&instance, 5., 5.);
|
||||
assert_eq!(instance.get_clicked_idx(), 0);
|
||||
```
|
||||
|
||||
*/
|
Loading…
Add table
Add a link
Reference in a new issue