Uno-platform: Canvas not in pixel but scaled by something - uno-platform

Uno says it is 'Pixel Perfect Everywhere'.
So I created a canvas with width 320 and height 320 and placed some buttons inside, one in each edge.
Now when I start the app, on Android or IOS, the canvas is bigger than the screen, and the buttons on the right side don't show at all.
But my iPhone8 and my Samsung S9 have a far bigger screen resolution than just 320 by 320.
The whole canvas gets scaled by something, and even the window bounds of the main window are far smaller than my screen resolution.
My questions:
Can I turn off the scaling and use the real resolution?
Is there a property where I can get the scaling factors, so I can resize my canvas and just calculate everything to the scaled size?

Layouting values like Width and Height in Uno/WinUI Xaml are defined in 'logical pixels', as distinct from 'physical pixels'. Since devices with similar physical dimensions may have wildly different physical pixel densities, logical pixels are a better way to specify layout dimensions in most cases.
Make sure you understand Xaml's layouting system - you normally shouldn't hard-code the dimensions at all when you're stretching content to the width of the screen. For example:
<Grid HorizontalAlignment="Stretch"
Height="320">
<Button Content="Button1"
HorizontalAlignment="Left"
VerticalAlignment="Top" />
<Button Content="Button2"
HorizontalAlignment="Right"
VerticalAlignment="Top" />
...
</Grid>
All that said, in the very rare cases that you do need to work with device-dependent physical pixels, you can use the DisplayInformation class and its properties, eg:
var displayInformation = DisplayInformation.GetForCurrentView();
var scaleFactor = displayInformation.RawPixelsPerViewPixel;
...

Related

How do you prevent labels and buttons scaling?

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.

[iOS]; How to leave space for top and bottom status bar

I found that hiding the status bar (at least on latest iPhones) does not make much sense since the space on top is partially consumed e.g. by the camera.
Similar issue at the bottom: there is a 'swipe bar' where some space should be left for.
Hence my question: what's the correct way to leave the right amount of space for the status bar on top of the iPhone screen and the 'swipe bar' at the bottom of an iPhone screen?
Thanks in advance
Indeed, making sure that app content isn't obscured by the 'notch' or the bottom swipe area on current-generation iPhones (and some newer Android devices as well) is an important consideration.
Uno Platform handles this using the VisibleBoundsPadding behavior. You can attach this behavior to any compatible container (eg a Panel or Border) and the content of the container will be padded such that stays within the 'safe' area of the screen.
In general you should place all 'content' in your application (eg text, images, interactive elements) within the VisibleBoundsPadding area, but some visual elements eg a full-screen backdrop might go outside of it.
You can place VisibleBoundsPadding anywhere you wish in your app (including multiple locations), though generally it makes sense to place it on or near a root element. It will adjust automatically to rotations and other layout updates.
Here's a simple example:
<Page x:Class="UnoTestbed20.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UnoTestbed20"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:toolkit="using:Uno.UI.Toolkit"
mc:Ignorable="d">
<Grid Background="LightBlue" toolkit:VisibleBoundsPadding.PaddingMask="All">
<Border Background="LightYellow">
<TextBlock Text="Hello, world!"
Margin="20"
FontSize="30" />
</Border>
</Grid>
</Page>
And the resulting display on an iPhone 11:

How to create responsive layout with react-semantic-ui?

How to create the layout as given below?
The layouts A and B in mobile must stack one after other.
In the bigger screen the layout B must be togglable. Whereas, A adjusts to full screen or half according to the visibility of B.
My code sample
<Grid.Row>
<Grid.Column computer={16} largeScreen={10}>
<A />
</Grid.Column>
{showB && (
<Grid.Column computer={16} largeScreen={6}>
<B />
</Grid.Column>
)}
</Grid>
You would need to declare the column A width in a variable that would change depending on if column B is open or not. A solution for that is here https://codesandbox.io/s/8843zowzj9
As semantic-ui Grid.Row can have a width of 16 units, columns A would start with that width, and it would decrease if you show column B (by the width you desire) or increase once you hide it.
The stackable columns={2} attributes in the Grid tag makes this clever enough to also make them stack once the screen reaches a mobile resolution.

Flex setting visibility based on slider

I have an image gallery app that has a slider to control the width of the thumbnails that ranges from 80 to 1024. As you move the slider the thumbnails width changes to effectively scaling the image between 80px and 1024px. Below the thumbnail is some information about the image such as the name, size, dimensions, etc. There is also a set of icons that do various tasks (delete, edit, copy, etc). All of this information is located within a VBox.
The problem I am having is I would like to have the VBox hide when the width of the thumbnail reaches 150 px or below. This I have been able to accomplish with the following code:
<mx:VBox visible = "{thumbnail.width > 150}">
The issue is that while the information within the VBox is now not visible, the real estate it takes up is not released. In other words, there is now a blank space the exact size of the VBox. What I'd like to do is to be able to release this space.
I know this is probably something simple that I'm overlooking, but today my brain is just not working, so any help will be appreciated.
BTW: I am using the Flex 3.6 SDK.
Try using includeInLayout:
<mx:VBox visible="{thumbnail.width>150}" includeInLayout="{thumbnail.width>150}">

Flex: Why does setting scaleX/Y in mxml effect the components size but setting it in actionscript does not?

I'm playing around with the scaleX/Y in the canvas tag and have noticed some strange behaviour. When I set scale in in mxml the width and height of the canvas are adjusted accordingly. For example if I have a canvas like this:
<mx:Canvas width="1000" height="1000" scaleX="0.1" scaleY="0.1" />
The canvas now appears on screen to have a width and height of 100 and if inside my creationComplete callback I check the width and height property they are indeed 100.
But if I do exactly the same thing except I set the scaleX/Y property from actionscript the canvas on screen appears to have a width and height of 100 as expected, but when I check the width and height property of the canvas they are still at the previous values of 1000.
Could anyone help me understand what is going on and also tell me if there is any method that will refresh the width and height values so that they are correct?
Thanks,
Chris
At what point in the Canvas' lifecycle are you adjusting the scaleX/Y properties in Actionscript? And then, at what point are you re-checking them?
It may be helpful to examine this white paper on Flex component lifecycles (PDF) to pick the right timing for actionscript-based visual component tweaking.

Resources