slint
slint copied to clipboard
Introduce undefined values for properties and struct fields
I have the following use case:
export struct Style {
border-radius: length,
border-top-left-radius: length,
background: brush
}
component StyledRectangle {
in property <Style> style;
Rectangle {
background: style.background;
border-radius: style.border-radius;
border-top-left-radius: style.border-top-left-radius;
}
}
export component MyExample inherits Window {
width: 600px;
height: 400px;
StyledRectangle {
style: {
background: #000000;
border-top-left-radius: 8px;
}
}
}
The following example does not work as expected, because the top left border radius of inner Rectangle
will not be rendered with 8px
but instead with 0
. The problem is, that if the border-radius
field on Style
is not explicit set it will defaults to 0
and it overwrites the setting of border-top-left-radius
. What could help to solve this problem is to introduce undefined
for values and use this as default e.g. for border-radius
instead of 0
, so that is handled like there is no value set on the property border-radius
.
We could have default value for struct like propose in https://github.com/slint-ui/slint/issues/2936 , you could do something like:
export struct Style {
border-radius: length,
border-top-left-radius: length = -1px,
background: brush
}
component StyledRectangle {
in property <Style> style;
Rectangle {
background: style.background;
border-radius: style.border-radius;
border-top-left-radius: style.border-top-left-radius >= 0 ? style.border-top-left-radius : style.border-radius;
}
}
export component MyExample inherits Window {
width: 600px;
height: 400px;
StyledRectangle {
style: {
background: #000000;
border-top-left-radius: 8px;
}
}
}
But in general, we might want to have option<...>
types.
border-top-left-radius: style.border-top-left-radius >= 0 ? style.border-top-left-radius : style.border-radius;
I think from user perspective that looks more like a workaround. As user I want to do something like on the Rectangle
directly, if I do not define a value for border-radius
it should be ignored and it should not override values like border-top-left-radius
.
Right, for the general case, we would need to introduced a new type like option<length>
or length?
or something like that.
Somehow related: https://github.com/slint-ui/slint/issues/615
If we had say option
like this:
property <option<length>> maybe-length;
We could either do it like typescript and say the compiler requires an earlier check:
clicked => {
width = self.maybe-length; // ERROR
if (self.maybe-length) {
width = self.maybe-length; // OK, control-flow before reaching this checks if value is not none
}
}
or we could have Rust like syntax:
clicked => {
width = self.maybe-length; // ERROR
if let Some(length) = self.maybe-length {
width = length;
}
}
but this requires the introduction of local variables....
I think the typescript approach is fine.
We can also make it work with ||
so that self.maybe-length || 0
works.
And other operators such as ?.