How do you prevent labels and buttons scaling? - scale

I am testing a godot app, where there is a text heading along the top, and there are buttons along the bottom. For now I have a spacer in the middle to keep the heading at the top and the buttons at the bottom.
If I set Project Settings -> Display -> Stretch to disabled, then I can set a font and button size that looks reasonable for my laptop, and the font size for the heading and button doesnt shrink smaller and larger when the window is adjusted.
How do I guarantee and/or test that the size will be appropriate when the application is exported to iOS and Android? Is there some kind of guide that will help choose appropriate (non scaleable) button sizes for all devices?

How Controls are positioned
There are three intended ways to position a Control in Godot:
Placed in a Container. In this case the Container will control position and sizing of the child Control, taking into account "Size Flags".
See also Using Containers, and Containers.
By anchors (anchor_*) and margins (margin_*). They determine the position of the edges of the Control. The anchors are factors, and the margins are offsets.
For example, the leftmost part of the Control will be positioned at anchor_left * parent_width + margin_left, relative to the parent Control.
You will find presets in the "Layout" menu that appears in the tool bar when you have a Control selected.
See also Size and anchors.
By rect_position and rect_size. These are relative to the top left corner of the parent Control.
Ultimately the other ways to position the Control are changing these. And you can also change these even if you positioned the Control by other means… Which is not intended, but supported (because it is useful to add animations to the UI among other things).
Regardless of which one you use, Godot will respect rect_min_size. And yes, there is also rect_rotation and rect_scale which throw a wrench on the above explanation, but they works as you would expect.
And yes, it is not the easier to use system. Because of that, the designer is being improved for Godot 4 (currently on Alpha 3 at the time of writing).
To answer the question the title: If your stretch mode is set to disabled, and your UI is anchored to the top left (which is the default), you would resize the window and the UI would not scale or adapt to that change. I don't think you don't want the UI to adapt.
Making a top and bottom bars with containers
You can use a VBoxContainer, since we will have three bars stacked one on top of the other, vertically. And yes, the second one is a spacer.
First of all, you want the VBoxContainer to take the whole screen. So set it to the Layout preset "Full Rect". So, yes, we are placing the Container by anchors and margins.
And second, we want the spacer to take as much space as possible. To archive this we set "Expand" flag on size_flags_vertical of the spacer. This is what Size Flags are for.
And, of course, what you place inside the Container might or might not be more Containers.
Making a top and bottom bars with anchors and margins
Give the top bar the "Top Wide" preset. It will set the margins and anchors to have it stay at the top, take the full width, and take its minimum height.
And give the bottom bar the "Bottom Wide" preset. It will set the margins and anchors to have it stay at the bottom, take the full width, and take its minimum height.
You would need no spacer.
And, by the way, I remind you that anchors are margins are relative to the parent. So you can nest this approach. And yes, Controls that are not containers can also have children Controls
About stretch modes
As you know you have a choice between:
viewport: All the sizes will be computed with the original resolution, and then the resulting sizes are scaled to the resolution of the device.
2D: will also compute all the sizes with the original resolution, but instead of scaling the resulting sizes, it renders at that size and scales the image.
disabled: It will compute all the sizes with the actual resolution of the device. No scaling will happen.
Since both viewport and 2D, the size of the UI will not be computed with the actual resolution of the device. This makes the approaches I described to have the UI adapt less effective (less useful or less necessary, depending how you look at it). And thus, if we want to use those approaches effectively we will want the stretch mode set to disabled.
And, of course, there is also the aspect setting.
See also Multiple resolutions and Support multiple form factors and screen sizes.
Designing for small resolution
You can test on the editor how the UI adapts to the resolution, either by resizing the window, or by setting the Test Width and Test Height in Project Settings. You can, of course, also test on an actual smartphone. For instance, I often launch the game in my Android from the Godot editor when developing mobile games.
Circling back to the stretch modes, this is what happens with the text:
disabled: The text stays the same size. This means that the UI can become too small for the text.
viewport: the text scales. This means that the text can become too small to be legible.
2d: the text scales too… except since it is a image scaling it can become blurry, even harder to read.
If we only consider the text, there is no good option. Now, either design the UI for the specific target resolution… Or make one that can adapt. And for one that can adapt, I believe disabled is the best stretch mode as I was arguing above.
And of course you can script it
If you need to run some code when the resolution changes, you can connect to the "size_changed" signal of the root Viewport. And if you need to figure out if the device is in landscape or portrait mode you OS.screen_orientation, and if you really have to, you can create a custom Container.

Related

Grid Layout Widget Sizing Problems

I use a Grid Layout inside my app. The grid layout I set to some fixed sizes.
myBootGridLayout->setContentsMargins(3,0,0,0);
myBootGridLayout->setRowMinimumHeight(0,25);
myBootGridLayout->setRowMinimumHeight(1,25);
myBootGridLayout->setRowMinimumHeight(2,25);
wdgBootFeatues->setFixedHeight(80);
For the QPushButton I use a size rule:
btnSelBootImagePath->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
But as you can see on the image, the ComboBox and Buttons have the same size but the LineEdit field is smaller. What I do wrong? Is there a trick to bring them on the common same size (Height) like in the QT documentation?
In case your question is to understand how to make sure that elements will have the same height, we should consider the following:
Layout might not necessarily ensure that some elements will have same height you would like, since it also relies on the size (horizontal and vertical) policy of the element in layout itself. In case you want to have QLineEdit and QPushButton instances to have the same height, you should set minimum height for each of them. Probably, it would even make sense to make the height fixed (i.e. set both minimum and maximum height to be the same values) for such elements to fit your needs, since both of these elements by default have fixed vertical size policy. This is for the reason, since most apps treat buttons and one line text fields in the same way.
In most cases, combining QVBoxLayout, QHBoxLayout and then QGridLayout is not necessary at all, since QGridLayout is much more flexible, and combines QVBoxLayout and QHBoxLayout features in a single layout under the hood at the first place, this it will probably satisfy all your needs (i.e. to represent you elements in a grid manner). Also, construction of UI elements will be slightly faster if less elements will be used.
Qt documentation might have such an effect because of the following reason - elements were tested on a different device. Qt does not try to make identical style sheets for widgets' elements across all platforms, thus visual differences will be everywhere. On some operating systems, button height is smaller than text field height by default, and this is completely normal.
One approach to make sure that size will get bigger than by default is to change size policy (vertical in your case). Code snippet changing size policy is correct basically. However, size policy is different thing than fixed height across elements. However, if your button and line edit would be in the same row, and both would have minimum expanding vertical policy, probably these elements would have the same height in that row.
Thus, probably to make sure the height of your elements remains the same is to set some minimum (and maximum as well in case vertical size policy is fixed) height through code or Qt Creator. This would be the easiest and least painful from thinking perspective approach. I am not sure if I have answered the question (it looks like that you answered yourself in your own way), but I am sure that I have introduced some thoughts that might come in handy when understanding Qt layouts.

Have horizontally aligned WKInterface elements fill view

I am trying to place 2 WKInterfaceButton items side by side on an Apple watch app.
I have a WKInterfaceGroup which I set its layout to horizontal. This allows me to position the buttons next to each other. The issue is having them both fit exactly side by side and fill the screens width and auto adjusting regardless of watch size (38 or 42mm) . Currently I align one left the other right. Then to adjust the widths i have to manually adjust the widths until it looks correct. This seems a bit too hard coded as it doesn't allow for any future watch screen size changes.
What I need is a way to set a WKInterface element (in this case a button) to be half the available size of the watch. In a normal app you can use
uiElementWidth = [UIScreen mainScreen].bounds.size.width/2
Is there an equivalent in WatchKit?
You can rely on the storyboard to do this. Select the button and make its width to be relative to the container like the following:
use Group as container and inside it align your buttons as left, center, right and Yah! use relative to container as told by Ashraf Tawfeeq

Preventing layouts from expanding beyond the window size

I'm trying to make my UI content expand nicely when the user resizes the window. I'm doing this in Qt Designer and learning about layouts and size policies.
Seems that everything is working fine for now: one layout stays within its maximum size, while another expands with the window resize, and they all stay above their minimum sizes. That's great and all, but the problem is that if I have a list with a lot of items, or if I am displaying a very large image, it will expand beyond the available window space and cause the window to be huge.
How can I specify something along the lines of "do not expand beyond the available window space"? I've played around with the size policies, but I couldn't get it to work. Is this something I need to set for the form itself rather than the layouts it contains?
I should specify this is the desired behavior: Display the widget as large as the available window, even if the widget content is too small. Expand/Shrink the widget to fill the window when the window is resized. Do not expand beyond the available window space. The widgets in question are 2 images (labels) and 1 list view.
I set the size policy to "ignored" for the respective widgets. That fixed it.
Or you can set the window maximum size.

Resizing the superview according to the subviews

I have 3 subviews(UILabel, UIImageview, UIButton) to be laid out on a container view. All the subviews are laid out using visual format language (VFL). The subview have padding from the leading , top edges etc. The content of the subview are dynamic so their sizes changes all the time. i want to resize the superview(container view) to exactly fit all the subviews. Is this possible by auto layout? i have seen some of the link here which suggest intrinsic size which i am not able to understand. can someone suggest a better way to achieve this.
Yes, it's possible. If you plan to resize the superview according to subview content, then intrinsic content size is the way to go.
The ever excellent Ray Wenderlich site has a tutorial that covers this well. It's Beginning Auto Layout in iOS 6: Part 2/2:
Intrinsic Content Size
Before Auto Layout, you always had to tell buttons and other controls
how big they should be, either by setting their frame or bounds
properties or by resizing them in Interface Builder. But it turns out
that most controls are perfectly capable of determining how much space
they need, based on their content.
A label knows how wide and tall it is because it knows the length of
the text that has been set on it, as well as the font size for that
text. Likewise for a button, which might combine the text with a
background image and some padding for the rounded corners.
The same is true for segmented controls, progress bars, and most other
controls, although some may only have a predetermined height but an
unknown width.
This is known as the intrinsic content size, and it is an important
concept in Auto Layout. You have already seen it in action with the
buttons. Auto Layout asks your controls how big they need to be and
lays out the screen based on that information.
It is possible.
In my case, I wanted to give rounded corners to segmented control. For that, I embedded segmented control in UIView. Now I was required to resize that container view as per size of segmented control.
I gave only following constraint and everything was taken care itself.
(1) Chose container view and give it X and Y constraints.
Leading space to Super view.
Top space to Super view.
(2) Chose container view and give Leading | Trailing | Top | Bottom constraint.
Leading space to segmented control.
Top space to segmented control.
Trailing space to segmented control.
Bottom space to segmented control.
(3) Chose segmented control and give it Height and Width constraints.
Height : 30 // Whatever
Width : 250 // Whatever
Now if I change the height and width of my segmented control, it automatically adjust container view's size (super-view of segmented control).

qt unexpandable layout?

Ok, here is my problem:
I have a vertical layout which contains a QPlainTextEdit and a horizontal layout (containing 2 QPushButtons) below the text edit.
The vertical layout is just a part of GUI, and gets resized depending on screen resolution. Btw. it is a mobile app, so I don't have a lot of space on screen.
Push buttons have some text which is dynamically set, I don't know it from the beginning to code it manually.
My problem occurs when the text in push buttons is big, and my whole vertical layout is expanded to fit the buttons.
How can I make the vertical layout unexpandable? note, that this is different from "fixed" because of different screen resoulutions.
I'd just like the clip the buttons if they do not fit, but keep the layout width untouched.
Anyway to do this?
You'll need to set the maximum width for the buttons, not the layout, which is only widening to fit the wider buttons. Check out the docs on QPushButton and look for QWidget inherited functions called setMaximumSize or setMaximumWidth.
You can always GetWidth() on the button when it is an appropriate size, then setMaximumWidth using that value since you wouldn't ordinarily know this. Pick an appropriate default text size/val and use that to create your "dynamic" default since this is going on screens of varying size.

Resources