Font change part 3: Flexible UI layouts

vuorisalmi | 05 January, 2012 13:46

As discussed on 18th November and on 21st December in this blog, the metrics of the default font of Nokia N9, the Nokia Pure Text typeface, have been updated in the Middle East and African variant (PR1.1.1, 22.2011.44-2) and will be changed in all devices in a future software update.

As a result of the update, text will occupy approximately 20% more space vertically in order to accommodate e.g. the Arabic script.

The two previous blog posts discussed two options for fixing text item height (e.g. Qt Quick Component Labels) so that the resulting text renders (almost) exactly the same on the screen, independent of the software release that the device has.

However, in many cases changing the height of the text is not the best idea. Often, it is better to create a flexible UI layout that contain text items of varying height/size and still keep the application UI beautiful and fully usable.

To illustrate potential problems, the following picture shows a UI that was created by anchoring the elements to the top of the page and further to each other. Everything seems to be ok in one specific case (on the left), but when the font height changes (on the right), the "Cancel" button disappears from the visible part of the screen, making the UI unusable.

In this case, a much better option is to anchor the title text to the top and the two buttons to the bottom of the page and then placing the long text item into a container that the user can pan to show the part of text that does not fit to the screen.

In this example, we have used the QML flickable element, but other types of design are possible as well, see e.g. the how a "expand/collapse" button has been used in N9 calendar and contacts application or in the Nokia Store client application to show/hide additional details and longer description text.

Here is how the second example would look like in QML code:

import QtQuick 1.1
import com.nokia.meego 1.0
Page {
    Label {
        id: titleText
        anchors {
            top: parent.top
            left: parent.left
            margins: 10
        }
        text: "Flickable Text"
        font.pixelSize: 42
    }
    Flickable {
        width: 400; height: 180
        contentWidth: longText.width; contentHeight: longText.height
        clip: true
        anchors {
            top: titleText.bottom
            left: parent.left
            margins: 10
        }
        Label {
            id: longText
            font.pixelSize: 24
            width: 400
            wrapMode: Text.WordWrap
            text: "Anchoring UI elements to each other..."
        }
    }
    Button {
        id: okButton
        anchors {
            bottom: cancelButton.top
            left: parent.left
            margins: 10
        }
        text: "OK"
    }
    Button {
        id: cancelButton
        anchors {
            bottom: parent.bottom
            left: parent.left
            margins: 10
        }
        text: "Cancel"
    }
}

Notice that the widths and heights of the elements have been hardcoded for the purposes of this simple example only. Also, it is always a good idea a provide some visual clue which shows that there is more content, but we wanted to keep the example in here to the bare minimum.

Notice that the need for flexible UI layouts does not only come from the change of the font metrics. It also needed whenever you want to provide localizations for your application: the length of text can vary a lot in different languages.

I hope these three blog posts have given you some ideas on how to design robust and at the same time beautiful UIs for your applications.


RSSComments

Fix for PR 1.2 font breakage

apoi | 03/03/2012, 18:25

I struggle to see how changing the font metrics in a firmware update, affecting all applications, could have been perceived as a good idea. As a minimum, I would have expected

a) personal e-mail notification warning about this beforehand, and
b) having the old font available on PR 1.2 devices.

Now all third-party applications striving to achieve pixel-perfect UI have to support two different UIs within one device. One can't even include the old font with an application without violating the font's license.

Anyway, the closest I've been able to get to minimize the damage is to use the following element to display text:

import QtQuick 1.1

// Fix the font in PR 1.2 devices
Text {
lineHeightMode: Text.FixedHeight
lineHeight: Math.floor(1.1 * font.pixelSize)
Component.onCompleted: {
if (!config.isOldFirmware) {
anchors.topMargin -= Math.floor(0.140 * (font.pixelSize < 20 ? 0 : font.pixelSize));
anchors.bottomMargin -= Math.floor(0.125 * (font.pixelSize < 20 ? 0 : font.pixelSize));
anchors.verticalCenterOffset -= Math.floor(0.10 * font.pixelSize);
}
}
}

I only checked that the outcome resembles the original in my own applications; you may have to modify the values a bit. Old firmware can be detected with

QtMobility::QSystemInfo info;
m_isOldFirmware = info.version(QtMobility::QSystemInfo::Firmware).contains("2011");

You must login to post comments. Login
 
Nokia Developer aims to help you create apps and publish them so you can connect with users around the world.

京ICP备05048969号  © Copyright Nokia 2012 All rights reserved