UI scaling
We’ve focused a lot on responsive UI in this book, using anchors and relative positioning where possible so that when the user resizes the window, the contents scale and adjust themselves appropriately. We’ve also pulled all the “hard-coded” properties like sizes and colors into a centralized Style object.
If we pick a property concerned with sizing, for example, sizeScreenMargin, it currently has a fixed value of 20. If we decide to increase the starting size of our Window element in MasterView, this screen margin size will remain the same. Now, it’s really easy to increase the screen margin too, thanks to the Style object, but it would be nice if all the hard-coded properties could scale up and down dynamically along with our Window element. That way, we can try out different window sizes without having to update Style each time.
As we’ve already seen, the flexibility of QML is extended even further with the built-in JavaScript support, and we can do just that.
First, let’s create new width and height properties for the window in Style:
readonly property real widthWindow: 1920 readonly property real heightWindow: 1080
Use these new properties in MasterView:
Window { width: Style.widthWindow height: Style.heightWindow ….
}
All the size properties in Style that we’ve created so far are relevant to this window size of 1920 x 1080, so let’s record that as new properties in Style:
readonly property real widthWindowReference: 1920 readonly property real heightWindowReference: 1080
We can then use the reference sizes and the actual sizes to calculate scaling factors in the horizontal and vertical axes. So in simple terms, if we design everything with a window width of 1,000 in mind and then we set the window to be 2,000 wide, we want everything to scale horizontally by a factor of 2. Add the following functions to Style:
function hscale(size) { return Math.round(size * (widthWindow / widthWindowReference)) } function vscale(size) { return Math.round(size * (heightWindow / heightWindowReference)) } function tscale(size) { return Math.round((hscale(size) + vscale(size)) / 2) }
The hscale and vscale functions calculate the horizontal and vertical scaling factors respectively. For certain size properties like pixel size for fonts, there is no independent width and height, so we can calculate an average of the horizontal and vertical scales using the tscale function.
We can then wrap any properties we want to scale in the appropriate function. For example, our screen margin can use the tscale function:
readonly property real sizeScreenMargin: tscale(20)
Now, not only can you increase the initial size of the window in Style, but your selected properties will automatically scale to the new size.