Closed matklad closed 8 months ago
Thanks for the report. We have some basic documentation for the layouts there, in case you missed it. https://sixtyfps.io/docs/rust/sixtyfps/docs/builtin_elements/index.html#verticallayout--horizontallayout But we clearly need to improve our documentation. It is true a specific layout.md documentation is probably in order to document all the special case.
Hey, I've just hit an interesting case of fighting with layout. I wanted to draw a main content in the center of the screen, and some auxilary content in center of the area above the main content.
I've started with this:
VerticalLayout {
Rectangle {
color: steelblue;
}
Rectangle {
height: ...;
width: ...;
...
}
Rectangle {
color: steelblue;
}
}
So far so good -- the explicitly sized content in the center, two identically sized rectangles fill the space.
Let's add some content:
VerticalLayout {
Rectangle {
color: steelblue;
Text { text: "120 wpm, no errors"; font_size: 22px; }
}
Rectangle {
height: ...;
width: ...;
...
}
Rectangle {
color: steelblue;
}
}
Still good -- as expected, the layout is the same, we only see new text. Now, let's try to center the text in the top rectangle...
VerticalLayout {
Rectangle {
color: steelblue;
VerticalLayout {
alignment: center;
Text { text: "120 wpm, no errors"; font_size: 22px; }
}
}
Rectangle {
height: ...;
width: ...;
...
}
Rectangle {
color: steelblue;
}
}
...
...
What is especially annoying here is action at the distance -- I had a perfect layout and a seemingly unrelated change in one of the components changed the whole thing.
I think the underlying issue here is that some components has a fixed size -- either an explicit one, or computer from the children. And other components have the size determined by the parent (like the window who's size is determined by the user dragging the corners), no matter what you do inside the component, it won't affect layout outside. And I think what happens here is that the rectangle silently flips from the second mode (asking the parent about the size) into the first mode (telling the parent it's size). I wonder if there can be some way to surface this in the .60
language, a-la width: set-by-parent
.
The Text { } try to limit itself to the size of its content. When in a layout, this will try to adjust the whole UI to fit this contraint which can easily be done because the down rectangle can grow.
The solution could be to
Text { vertical-stretch: 1; vertical_alignment: align-center; }
VerticalLayout {
Rectangle {}
Text { text: "120 wpm, no errors"; font_size: 22px; }
Rectangle {}
}
I see how this can be confusing, but i believe this is the right behavior. I guess I should improve the doc with more example to make this easier to understand.
I ended up doing a much simpler thing:
Rectangle {
Text {
height: 100%;
width: 100%;
vertical_alignment: align_center;
horizontal_alignment: align_center;
text: stats;
font_size: 30px;
color: #7F9F7F;
}
}
Still, I must admit I currently lack a mental model to explain the nested layouts behavior.
If just Rectangle { Text {} }
shrunk to fit the text, that'd make sense to me. If neither Rectangle { Text { }}
nor Rectangle { Layout { Text { } } }
shrunk that'd also make sense. But why Text
doesn't affect the behavior of outer rectangle, while Layout { Text }
does is unclear. Additional docs would be appreciated!
Aha! I've found an example which completely shatters my wrong mental model to pieces:
VerticalLayout {
Rectangle { color:black; }
VerticalLayout {
Rectangle { color:red; }
Rectangle { color:yellow; }
}
}
Here, all three rectangles will have the same height (while I wrongly assumed that the black one will be twice as large).
Why are the three rectangles the same height? I also thought the black one will be twice as tall compared to the red and yellow.
Why are the three rectangles the same height? I also thought the black one will be twice as tall compared to the red and yellow.
Because each rectangle has a default vertical-stretch
of 1.0
And the layout sums the stretch of its children in the directon of the layout.
so the inner VerticalLayout has a stretch of 2.0.
It is possible to override that:
VerticalLayout {
Rectangle { color:black; }
VerticalLayout {
vertical-stretch: 1;
Rectangle { color:red; }
Rectangle { color:yellow; }
}
}
Or like so:
VerticalLayout {
Rectangle { color:black; vertical-stretch: 2; }
VerticalLayout {
Rectangle { color:red; }
Rectangle { color:yellow; }
}
}
Just curious: What's the behavior with QML?
We have this documented now: https://slint.dev/releases/1.3.2/docs/slint/src/language/concepts/layouting#
We need to have more specialized issues for anything still missing.
Hi! This is going to be a bit of a whiney issue :)
I don't go gui on a daily basis, but I wrote a fair share of swing and html. The common problem with gui toolkits for me is that I don't understand how the final layout is computed from the properties I give. Specifically, I usually can specify sizes of everything, but sometimes they don't add up. In this case, the toolkit applies some algorithm to infer a consistent set of positions from my messy input. The user-visible behavior is that some user-specified constraints are ignored. As an end user, this is frustrating, because there's no mental model I can use to predict this things.
Today's case was like this: I had an 800x400 window, with 800x400 vertical layout in
.60
. The rendered window was tiny however. The reason for that was that my vertical layout contained a single element with explicitly specified dimensions. So size of a single child overrode the size of the parent.This is a reasonable behavior if you know it, but i didn't :[
I wish 60fps included "layout algorithm" section in the docs, which specified such things.