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 ?.