Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions internal/compiler/generator/cpp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2218,11 +2218,11 @@ fn generate_sub_component(
));

let ensure_updated = if let Some(listview) = &repeated.listview {
let vp_y = access_local_member(&listview.viewport_y, &ctx);
let vp_h = access_local_member(&listview.viewport_height, &ctx);
let lv_h = access_local_member(&listview.listview_height, &ctx);
let vp_w = access_local_member(&listview.viewport_width, &ctx);
let lv_w = access_local_member(&listview.listview_width, &ctx);
let vp_y = access_member(&listview.viewport_y, &ctx).unwrap();
let vp_h = access_member(&listview.viewport_height, &ctx).unwrap();
let lv_h = access_member(&listview.listview_height, &ctx).unwrap();
let vp_w = access_member(&listview.viewport_width, &ctx).unwrap();
let lv_w = access_member(&listview.listview_width, &ctx).unwrap();

format!(
"self->{repeater_id}.ensure_updated_listview(self, &{vp_w}, &{vp_h}, &{vp_y}, {lv_w}.get(), {lv_h}.get());"
Expand Down
10 changes: 5 additions & 5 deletions internal/compiler/generator/rust.rs
Original file line number Diff line number Diff line change
Expand Up @@ -974,11 +974,11 @@ fn generate_sub_component(
});
});
let ensure_updated = if let Some(listview) = &repeated.listview {
let vp_y = access_local_member(&listview.viewport_y, &ctx);
let vp_h = access_local_member(&listview.viewport_height, &ctx);
let lv_h = access_local_member(&listview.listview_height, &ctx);
let vp_w = access_local_member(&listview.viewport_width, &ctx);
let lv_w = access_local_member(&listview.listview_width, &ctx);
let vp_y = access_member(&listview.viewport_y, &ctx).unwrap();
let vp_h = access_member(&listview.viewport_height, &ctx).unwrap();
let lv_h = access_member(&listview.listview_height, &ctx).unwrap();
let vp_w = access_member(&listview.viewport_width, &ctx).unwrap();
let lv_w = access_member(&listview.listview_width, &ctx).unwrap();

quote! {
#inner_component_id::FIELD_OFFSETS.#repeater_id.apply_pin(_self).ensure_updated_listview(
Expand Down
10 changes: 5 additions & 5 deletions internal/compiler/llr/item_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -268,13 +268,13 @@ pub struct Function {
/// The property references might be either in the parent context, or in the
/// repeated's component context
pub struct ListViewInfo {
pub viewport_y: LocalMemberReference,
pub viewport_height: LocalMemberReference,
pub viewport_width: LocalMemberReference,
pub viewport_y: MemberReference,
pub viewport_height: MemberReference,
pub viewport_width: MemberReference,
/// The ListView's inner visible height (not counting eventual scrollbar)
pub listview_height: LocalMemberReference,
pub listview_height: MemberReference,
/// The ListView's inner visible width (not counting eventual scrollbar)
pub listview_width: LocalMemberReference,
pub listview_width: MemberReference,

// In the repeated component context
pub prop_y: MemberReference,
Expand Down
10 changes: 5 additions & 5 deletions internal/compiler/llr/lower_to_item_tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -783,11 +783,11 @@ fn lower_repeated_component(
let listview = repeated.is_listview.as_ref().map(|lv| {
let geom = component.root_element.borrow().geometry_props.clone().unwrap();
ListViewInfo {
viewport_y: ctx.map_property_reference(&lv.viewport_y).local().clone(),
viewport_height: ctx.map_property_reference(&lv.viewport_height).local().clone(),
viewport_width: ctx.map_property_reference(&lv.viewport_width).local().clone(),
listview_height: ctx.map_property_reference(&lv.listview_height).local().clone(),
listview_width: ctx.map_property_reference(&lv.listview_width).local().clone(),
viewport_y: ctx.map_property_reference(&lv.viewport_y),
viewport_height: ctx.map_property_reference(&lv.viewport_height),
viewport_width: ctx.map_property_reference(&lv.viewport_width),
listview_height: ctx.map_property_reference(&lv.listview_height),
listview_width: ctx.map_property_reference(&lv.listview_width),
prop_y: sc.mapping.map_property_reference(&geom.y, ctx.state),
prop_height: sc.mapping.map_property_reference(&geom.height, ctx.state),
}
Expand Down
10 changes: 5 additions & 5 deletions internal/compiler/llr/optim_passes/count_property_use.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ pub fn count_property_use(root: &CompilationUnit) {
for (idx, r) in sc.repeated.iter_enumerated() {
r.model.borrow().visit_property_references(ctx, &mut visit_property);
if let Some(lv) = &r.listview {
visit_property(&lv.viewport_y.clone().into(), ctx);
visit_property(&lv.viewport_width.clone().into(), ctx);
visit_property(&lv.viewport_height.clone().into(), ctx);
visit_property(&lv.listview_width.clone().into(), ctx);
visit_property(&lv.listview_height.clone().into(), ctx);
visit_property(&lv.viewport_y, ctx);
visit_property(&lv.viewport_width, ctx);
visit_property(&lv.viewport_height, ctx);
visit_property(&lv.listview_width, ctx);
visit_property(&lv.listview_height, ctx);

let parent_ctx = ParentScope::new(ctx, Some(idx));
let rep_ctx = EvaluationContext::new_sub_component(
Expand Down
10 changes: 5 additions & 5 deletions internal/compiler/llr/optim_passes/remove_unused.rs
Original file line number Diff line number Diff line change
Expand Up @@ -333,11 +333,11 @@ mod visitor {
}

if let Some(listview) = listview {
visit_local_member_reference(&mut listview.viewport_y, &scope, state, visitor);
visit_local_member_reference(&mut listview.viewport_height, &scope, state, visitor);
visit_local_member_reference(&mut listview.viewport_width, &scope, state, visitor);
visit_local_member_reference(&mut listview.listview_width, &scope, state, visitor);
visit_local_member_reference(&mut listview.listview_height, &scope, state, visitor);
visit_member_reference(&mut listview.viewport_y, &scope, state, visitor);
visit_member_reference(&mut listview.viewport_height, &scope, state, visitor);
visit_member_reference(&mut listview.viewport_width, &scope, state, visitor);
visit_member_reference(&mut listview.listview_width, &scope, state, visitor);
visit_member_reference(&mut listview.listview_height, &scope, state, visitor);

visit_member_reference(&mut listview.prop_y, &inner_scope, state, visitor);
visit_member_reference(&mut listview.prop_height, &inner_scope, state, visitor);
Expand Down
61 changes: 61 additions & 0 deletions tests/cases/issues/issue_11095_listview_twoway_global.slint
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0

// Test that two-way binding between a ListView's viewport-y and a global property
// compiles and works correctly (issue #11095).

import { ListView } from "std-widgets.slint";

export global GlobalInfo {
in-out property <length> saved-viewport-y;
}

export component TestCase inherits Window {
width: 300px;
height: 200px;

in-out property <length> test-viewport-y <=> GlobalInfo.saved-viewport-y;

lv := ListView {
viewport-y <=> GlobalInfo.saved-viewport-y;
for i in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]: Rectangle {
height: 100px;
background: mod(i, 2) == 0 ? blue : red;
}
}
}

/*
```rust
let instance = TestCase::new().unwrap();

// Initially viewport-y should be 0
assert_eq!(instance.get_test_viewport_y(), 0.);

// Set the global property and verify it propagates to the ListView
instance.set_test_viewport_y(-150.0);
slint_testing::mock_elapsed_time(100);
assert_eq!(instance.get_test_viewport_y(), -150.);
```

```cpp
auto handle = TestCase::create();
const TestCase &instance = *handle;

// Initially viewport-y should be 0
assert_eq(instance.get_test_viewport_y(), 0.);

// Set the global property and verify it propagates to the ListView
instance.set_test_viewport_y(-150.0);
slint_testing::mock_elapsed_time(100);
assert_eq(instance.get_test_viewport_y(), -150.);
```

```js
var instance = new slint.TestCase();
assert.equal(instance.test_viewport_y, 0.);
instance.test_viewport_y = -150.0;
slintlib.private_api.mock_elapsed_time(100);
assert.equal(instance.test_viewport_y, -150.);
```
*/
Loading