Closed jturcotte closed 7 months ago
Changing the data in a model will mark the RepeaterTracker::is_dirty
property as dirty. https://github.com/slint-ui/slint/blob/143a1881f1125ad197cf4afe4c5cf74e56f44e06/internal/core/model.rs#L682
And the layout depends on that property, so the layout cache is dirty.
Now, we need the layout to depend on that property because then accessing the layout will have the side effect of updating the properties in the model.
Ideally we shouldn't do that indeed. Instead, each component's model property could be added as a dependency somehow.
This clearly need to be improved.
Workaround for now:
HorizontalLayout{
for idx in 8:
Rectangle {
property<Data> data: model[idx];
border-width: 1px;
border-color: white;
background: data.bg;
TouchArea {
clicked => {
model[idx].bg = data.bg.darker(0.1);
}
}
}
}
But I reallize that the model[idx]
is still marked dirty way too often
We would also need a mechanism for the []
to only mark itself as dirty when the data changes
But I reallize that the model[idx] is still marked dirty way too often
Humm yes, the whole layout isn't affected, but it seems to still invalidates the area covered by all components depending on that model.
I guess I'll try to avoid models and go with something like this for now:
struct Data := {
bg: brush,
}
Col := Rectangle {
property<Data> data;
border-width: 1px;
border-color: white;
background: data.bg;
TouchArea {
clicked => {
data.bg = data.bg.darker(0.1);
}
}
}
MainWindow := Window {
width: 240px;
height: 160px;
property<Data> data0: { bg: Colors.lightpink};
property<Data> data1: { bg: Colors.lightpink};
property<Data> data2: { bg: Colors.lightpink};
property<Data> data3: { bg: Colors.lightpink};
property<Data> data4: { bg: Colors.lightpink};
property<Data> data5: { bg: Colors.lightpink};
property<Data> data6: { bg: Colors.lightpink};
property<Data> data7: { bg: Colors.lightpink};
HorizontalLayout{
Col { data: data0; }
Col { data: data1; }
Col { data: data2; }
Col { data: data3; }
Col { data: data4; }
Col { data: data5; }
Col { data: data6; }
Col { data: data7; }
}
}
I think this is no longer the case: This is even tested in https://github.com/slint-ui/slint/blob/09a5c724bf3ba6e60acfb8ca6c6f3b2f14ee696d/api/rs/slint/tests/partial_renderer.rs#L244-L246
Noticed when using the software renderer, any single set_row_data on a model used on the screen invalidates the whole region of their root layout for some reason.
To reproduce, overwrite
examples/carousel/ui/carousel_demo.slint
with this:And apply this debug output patch:
Then run using:
cargo run -p carousel --no-default-features --features=simulator
Clicking one of the blue rectangles in the top row (the ones not using a model) will output this as expected:
But clicking one of the red rectangles backed by a model of the bottom row I get this, and the whole area of the VerticalLayout is repainted: