/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** GNU Free Documentation License
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms
** and conditions contained in a signed written agreement between you
** and Nokia.
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

/*!
\example examples/native/scalability/separatelayouts
\ingroup qt-components-example
\title Scalability: Loading Separate Layouts Based on Screen Configuration
\brief Using separate top level layout files for different resolutions.

The Using Separate Layouts example shows how to use separate top level layout
definitions to support different screen configurations or device form factors
with QML Components.

\image example-scalability-separatelayouts-landscape.jpg

\section1 Selecting The Top-Level Layout According to Resolution and Dots Per Inch (DPI)

The example uses the file MainView.qml as its top-level layout definition.
There are several versions of MainView.qml in a directory structure where the
paths follow the pattern <path>/<resolution>/<DPI>/<fileName>.
The loading of the MainView.qml is handled by the CustomLoader component,
which inherits from \l{Loader}.
The <path> is the root directory of the structure, the
CustomLoader property \c path defines the value of <path>,
in the example the directory is named \c layouts. The part <fileName>
represents the file that should be loaded, the CustomLoader
property \c fileName stores this value, which is set to MainView.qml
in example code.

The <resolution> part of the path can be expressed in two ways.
The most specific way to express <resolution> is to follow the pattern
<max(width,height)>x<min(width,height)>, which uses
properties \c screen.displayWidth and \c screen.displayHeight to parse a
directory name. Note that the larger of the two values is always used
first, the CustomLoader does not support loading different files for
different orientations. The alternative way to define <resolution> is to
use one of the screen size categories Small, Normal, Large, or
ExtraLarge. The CustomLoader defines the screen size categories in the
function \c displayCategory() by using display size category information
provided by \c screen.displayCategory and Screen.

\snippet examples/native/scalability/separatelayouts/CustomLoader.qml Display Categories

The <DPI> part of the path represents the dots per inch value of the display,
the <DPI> can be an integer DPI value or one of the
density categories defined in the CustomLoader function
\c densityCategory(). Similarly to the display size category, the
\c screen.density property and the Screen object provides DPI
information.

\snippet examples/native/scalability/separatelayouts/CustomLoader.qml Density Categories

The path that the CustomLoader is trying to load
is maintained in the property \c mySource. Note that the
CustomLoader rounds the DPI value that it obtains from \c screen.dpi to
the nearest 10 and stores the value in \c roundedDpi.

\snippet examples/native/scalability/separatelayouts/CustomLoader.qml Properties

The actual loading starts when the \c onMySourceChanged signal handler
is triggered as the CustomLoader component is initialized.
The CustomLoader tries first to create an object from the most
specific path. If the path does not exist, then CustomLoader starts to
generalize the path by first replacing screen dimension and DPI information
with corresponding categories, then by dropping DPI information,
and finally the resolution part of the path, see \c onStatusChanged
in the following snippet.

\snippet examples/native/scalability/separatelayouts/CustomLoader.qml Loading

If the CustomLoader would look for the file
MainView.qml with the \c path value set to "layouts" in an
environment with the resolution 800x600 at 103 DPI it would attempt to
create the object from files in the following places.

\list 1
    \o layouts/800x600/100/MainView.qml
    \o layouts/800x600/MainView.qml
    \o layouts/Large/Low/MainView.qml
    \o layouts/Large/MainView.qml
    \o layouts/MainView.qml
\endlist

The purpose of the search pattern is to enable specific layout
definitions, layouts for broader screen categories, and
catch-all layouts.

The CustomLoader will emit the signal
\c loaded if the loading of the specified file succeeds, this
functionality is inherited from \l{Loader}.
If the CustomLoader fails to load the specified file, then it
emits the signal \c loadError. There is an
handler for the \c loadError signal in separatelayouts.qml,
which displays an error message.

\snippet examples/native/scalability/separatelayouts/separatelayouts.qml 0

\section1 Reusing Components in Top Level Layouts

The top level layout files, named MainView.qml, use the component
GradientRectangle. The MainView.qml files define the location of
where the file GradientRectangle.qml resides as Root, and then
simply refer to the corresponding component as Root.GradientRectangle.

\snippet examples/native/scalability/separatelayouts/layouts/MainView.qml 0

\section1 Reacting to Orientation Changes

The algorithm that selects the correct top-level layout does not
take orientation to account. Therefore, the top-level layout file
has to specify if/how orientation is a factor in the layout.

The default layout in the example, layouts/MainView.qml does not react
to orientation changes, but the layout for the category Normal/High has
different states for landscape and portrait. Note the use of AnchorChanges.

\snippet examples/native/scalability/separatelayouts/layouts/Normal/High/MainView.qml 0

\section1 Discussion

It is possible to combine the idea of loading different configuration
files with the selection of different top-level layouts based on screen
size,
see \l{examples/native/scalability/scalableconfiguration}{Scalable Configuration}.
*/

/*!
\example examples/native/scalability/millimeters
\ingroup qt-components-example
\title Scalability: Using Millimeters as Device Independent Measurement Units
\brief Using device independent measurement units.

This example demonstrates how to use device independent measurement units. In this example
we are using millimeters for as an device independent measurement unit.

\image example-scalability-millimeters-portrait.jpg

For more details, see: \l {Scalable Measurements and Rounding}

\section1 Walkthrough

Firstly, we define a helper function for calculating pixels per millimeters
from dots per inch (dpi) of the screen. We apply rounding to ensure that the
calculated value is an integer number of pixels, see the \l {Rounding of
Measurements} example for more information.

\snippet examples/native/scalability/millimeters/ScalableUI.js 0

Then, define font size for the example in millimeters.

\snippet examples/native/scalability/millimeters/ScalableUI.js 1

And same thing for image width.

\snippet examples/native/scalability/millimeters/ScalableUI.js 2

The snippet below scales the \l{Image} element with defined image size.

\snippet examples/native/scalability/millimeters/millimeters.qml 0

Similarly we scale font size of the \l{Text} element.

\snippet examples/native/scalability/millimeters/millimeters.qml 1
*/

/*!

\example examples/native/scalability/anchors
\ingroup qt-components-example
\title Scalability: Using Anchors for Layouting
\brief Using anchors for layouting items.

This example demonstrates how to use anchors for layouting items on orientation
change. Similar logic could also be used for selecting layout for different resolutions.

\image example-scalability-anchors-portrait.jpg

\section1 Walkthrough

Firstly, we have three Box elements anchored to an initial layout.

\snippet examples/native/scalability/anchors/anchors.qml 0

Secondly, we have layouts defined for portrait (\c "portraitLayout" state) and
landscape (\c "landscapeLayout" state). The \c window.inPortrait is bound to the \c when
property of the \c "portraitLayout" state. Similarly \c !window.inPortrait is bound to
the \c when property of the \c "landscapeLayout" state. When orientation condition is met
anchoring of the items is changed accordingly.

\snippet examples/native/scalability/anchors/anchors.qml 1

*/

/*!
\example examples/native/scalability/positioners/column-layout
\ingroup qt-components-example
\title Scalability: Using Column for Layouting
\brief Creating scalable layouts with the Column element.

This example demonstrates how Column element can be used for creating a scalable layout.
In this example number of items shown in the Column changes on orientation change.

\image example-scalability-column-portrait.jpg

\section1 Walkthrough

The number of visible Rectangle elements (\c itemCount) shown in the Column changes
when \c window.inPortrait changes.
In addition, the height (\c rectangleHeight) of a Rectangle item shown in the Column
changes when number of \c itemCount changes.

\snippet examples/native/scalability/positioners/column-layout/column-layout.qml 0

Repeater instantiates four Rectangle elements in the Column.

\snippet examples/native/scalability/positioners/column-layout/column-layout.qml 1

*/

/*!
\example examples/native/scalability/positioners/row-layout
\ingroup qt-components-example
\title Scalability: Using Row for Layouting
\brief Using Row for creating scalable layouts.

This example demonstrates how Row element can be used for creating a scalable layout.
In this example number of items shown in the Row changes on orientation change.

\image example-scalability-row-portrait.jpg

\section1 Walkthrough

The number of visible Rectangle elements (\c itemCount) shown in the Row changes
when \c window.inPortrait changes.
In addition, the width (\c rectangleWidth) of a Rectangle item shown in the Column
changes when number of \c itemCount changes.

\snippet examples/native/scalability/positioners/row-layout/row-layout.qml 0

Repeater instantiates four Rectangle elements in the Row.

\snippet examples/native/scalability/positioners/row-layout/row-layout.qml 1

*/

/*!
\example examples/native/scalability/positioners/grid-layout
\ingroup qt-components-example
\title Using Grid for Layouting
\brief Using Grid element for creating scalable layouts.

This example demonstrates how Grid element can be used for creating a scalable layout.
In this example number of columns and rows of the Grid changes on orientation change.

\image example-scalability-grid-landscape.jpg

\section1 Walkthrough

The width (\c itemWidth) and the height (\c itemHeight) of the GridItem when
number of columns and rows are changed.

\snippet examples/native/scalability/positioners/grid-layout/grid-layout.qml 0

The number of \c columns and \c rows shown in the Grid changes when \c window.inPortrait changes.

\snippet examples/native/scalability/positioners/grid-layout/grid-layout.qml 1

Repeater instantiates six GridItem elements in the Grid.

\snippet examples/native/scalability/positioners/grid-layout/grid-layout.qml 2

*/

/*!
\example examples/native/scalability/scalableconfiguration
\ingroup qt-components-example
\title Scalable Configuration
\brief Loading configuration files based on screen configuration

This example demonstrates how to load different configuration files
that modify UI layout and app logic depending on the DPI and screen
resolution.

The example application implements a simple game, where four different
colored "buttons" flash in random order. The player must push the
buttons in the same sequence that the buttons flash. Each correct
button press yields one point, but pressing the buttons in the wrong
sequence ends the game.

\image example-scalability-scalableconfiguration-landscape.jpg

\section1 Loading Configuration Data According to Resolution and Dots Per Inch (DPI)

This example uses two loaders to initialize the application.
First, the main file scalableconfiguration.qml loads one of
several alternative configuration objects, selecting the
appropriate file to load by the DPI and screen dimensions of
the application runtime. Then the example
loads the GameView object that uses the data in the configuration
object to layout the UI and adjust game settings.

\snippet examples/native/scalability/scalableconfiguration/scalableconfiguration.qml 0

In this setup it is important to first load the configuration object,
and only then create any objects that use data in the configuration
object; any attempt to create an object that relies on non-existent
configuration information will fail.

The loading sequence starts when the application starts and
the CustomLoader element is intialized.
The CustomLoader inherits from \l{Loader}, it is an element that
encapsulates the logic for loading different files for different resolutions.

The configuration objects are implemented by the files named Configuration.qml,
the file name is assigned to CustomLoader property \c fileName in
scalableconfiguration.qml.

The different versions of Configuration.qml exist in a directory structure
where the paths follow the pattern <path>/<resolution>/<DPI>/<fileName>.
The <path> is the root directory of the structure, the
CustomLoader property \c path defines the value of <path>,
in the example the directory is named \c layouts. The part <fileName>
represents the file that should be loaded, the CustomLoader
property \c fileName stores this value, which is set to Configuration.qml
in example code.

The <resolution> part of the path can be expressed in two ways.
The most specific way to express <resolution> is to follow the pattern
<max(width,height)>x<min(width,height)>, which uses
properties \c screen.displayWidth and \c screen.displayHeight to parse a
directory name. Note that the larger of the two values is always used
first, the CustomLoader does not support loading different files for
different orientations. The alternative way to define <resolution> is to
use one of the screen size categories Small, Normal, Large, or
ExtraLarge. The CustomLoader defines the screen size categories in the
function \c displayCategory() by using display size category information
provided by \c screen.displayCategory and Screen.

\snippet examples/native/scalability/scalableconfiguration/CustomLoader.qml Display Categories

The <DPI> part of the path represents the dots per inch value of the display,
the <DPI> can be an integer DPI value or one of the
density categories defined in the CustomLoader function
\c densityCategory(). Similarly to the display size category, the
\c screen.density property and the Screen object provides DPI
information.

\snippet examples/native/scalability/scalableconfiguration/CustomLoader.qml Density Categories

The path that the CustomLoader is trying to load
is maintained in the property \c mySource. Note that the
CustomLoader rounds the DPI value that it obtains from \c screen.dpi to
the nearest 10 and stores the value in \c roundedDpi.

\snippet examples/native/scalability/scalableconfiguration/CustomLoader.qml Properties

The actual loading starts when the \c onMySourceChanged signal handler
is triggered as the CustomLoader component is initialized.
The CustomLoader tries first to create an object from the most
specific path. If the path does not exist, then CustomLoader starts to
generalize the path by first replacing screen dimension and DPI information
with corresponding categories, then by dropping DPI information,
and finally the resolution part of the path, see \c onStatusChanged
in the following snippet.

\snippet examples/native/scalability/scalableconfiguration/CustomLoader.qml Loading


If the CustomLoader would look for the configuration file
Configuration.qml with the \c pathPrefix "configurations" in an
environment with the resolution 800x600 at 103 DPI it would attempt to
create the object from files in the following places.

\list 1
    \o configurations/800x600/100/Configuration.qml
    \o configurations/800x600/Configuration.qml
    \o configurations/Large/Low/Configuration.qml
    \o configurations/Large/Configuration.qml
    \o configurations/Configuration.qml
\endlist

The purpose of the search pattern is to enable specific configurations
definitions, configurations for broader screen categories, and
catch-all configurations.

The CustomLoader will emit the signal
\c loaded if the loading of the specified file succeeds, this
functionality is inherited from \l{Loader}. The signal handler
\c onLoaded is used in scalableconfiguration.qml to initailize
the loading of the GameView element with a regular \l{Loader}.

If the CustomLoader fails to load the specified file, then it
emits the signal \c loadError. There is an
handler for the \c loadError signal in separatelayouts.qml,
which displays an error message.

\section1 Using Data Defined in the Configuration

The data in the Configuration.qml files store information such as
about how many rows and columns of game controls to use, font
specifications, and game speed information. The following snippet is from
the configuration file configurations/640x360/Configuration.qml.

\snippet examples/native/scalability/scalableconfiguration/configurations/640x360/Configuration.qml 0

The GameView element gets the access to the Configuration object from
the assignment \c customLoader.item to its \c configuration property.
In GameView.qml the property is referred to as root.configuration, it
is  used in various locations. The function \c startGame() sets the
interval of a Timer to \c root.configuration.interval.

\snippet examples/native/scalability/scalableconfiguration/GameView.qml startGame

The Timer uses the property \c root.configuration.intervalDecrease to
speed up the game incrementally.

\snippet examples/native/scalability/scalableconfiguration/GameView.qml gameTimer

The GameView element lays out game controls in a Grid, whose column and
row setup is defined in the configuration object.

\snippet examples/native/scalability/scalableconfiguration/GameView.qml grid

The colored "buttons" are defined in GradientRectangle.qml,
\c window.config is used to control the radius of the buttons.

\snippet examples/native/scalability/scalableconfiguration/GameView.qml greenButton

The GameView element has a Text element that displays status
messages in a font defined by the configuration object.

\snippet examples/native/scalability/scalableconfiguration/GameView.qml statusText

\section1 Discussion

It is possible to combine the idea of  selecting different top-level
layouts with the loading of different configuration files based on
screen size, see \l{examples/native/scalability/separatelayouts}{Loading Separate Layouts Based on Screen Configuration}.
*/

/*!
\example examples/native/scalability/rounding
\ingroup qt-components-example
\title Rounding of Measurements
\brief Using Rounding to Ensure Integer Pixel Measurements.

\section1 Introduction

This example demonstrates how rounding in Javascript expressions can be used to
ensure that all layout measurements are ultimately rendered using integer
values. The example demonstrates the same layout scenarios with and without the
application of rounding. This gives a direct comparison between the outcomes,
in order to demonstrate the importance of using rounding correctly.

In most cases, layouts are defined using the built in layout managers available
in QML. These managers are responsible for ensuring that layouts look good, but
this is based on the assumption that all measurements and component sizes will
be defined in integer pixel measurements. Therefore, in order to get the best
visual performance, it is important to enforce the rule that all measurements
must eventually be calculated as an integer value.

This includes:

    \list

        \o Declared Item height and width measurements
        \o Declared margin and spacing sizes
        \o Declared Image sizes
        \o Item x and y coordinate positions relative to a container
        \o Conversion of device independent measurement units into pixels
        \o Sharing available space between a number of items
        \o Distributing items within a parent, with equally sized gaps

    \endlist

Note that any non-integer item positions will result in automatic rounding of
the final drawing of both Text and Image elements. However, when resizing or
scrolling items, the effect of rounding can be different, and hence
inconsistent. If there are any non-integer measurements or positions, in any
container all the way down the containment hierarchy from the screen, this
could effect the visual quality of any other items at that level or below in
the hierarchy.

Also note that clipping can occur in a way that means the edge of a non-integer
sized item might not be visible, This could potentially create visual drawing
artefacts.

Therefore, it is highly recommended that every calculation that results in a
measurement value should be rounded, either rounded up or down according to the
exact needs of the layout. This means every occasion that division occurs; in
particular when converting device independent measurements into pixels, and
also when sharing some available space between a variable number of items.


\section1 Walkthrough of Even Distribution Example

This example page demonstrates how to distribute a number of items within a
container. The items might be of equal size, or they might be of variable size.
In this example, the items are all different sizes to demonstrate the point.

The page definition includes two copies of the "rounder" component in a column.
The first instance has rounding disabled, while the second instance has
rounding enabled. The slider can be used to resize the column.

Each rounder generates a number of children, where the width depends on the
index in the repeater. This is just an example, but it could be that an
arbitrary set of child items are declared with different widths, or the child
items could all be identical with the same width; the gap rounding issue would
apply in each case.

\snippet examples/native/scalability/rounding/GapsPage.qml page_a
\dots 4
\snippet examples/native/scalability/rounding/GapsPage.qml column_a
\dots 8
\snippet examples/native/scalability/rounding/GapsPage.qml loaders
\dots 4
\snippet examples/native/scalability/rounding/GapsPage.qml column_b
\snippet examples/native/scalability/rounding/GapsPage.qml page_b

The rounder contains a number of Rectangle children. It performs the role of a
layout manager, and therefore must update its layout when its parent or
children configuration changes.

\snippet examples/native/scalability/rounding/GapsPage.qml rounder_a
\snippet examples/native/scalability/rounding/GapsPage.qml repeater
\snippet examples/native/scalability/rounding/GapsPage.qml rounder_b

Finally the layoutChildren method calculates the x positions of each child.
Notice that the evenlyDistributed property is used to determine whether to
apply the rounding.

\snippet examples/native/scalability/rounding/GapsPage.qml layoutChildren

In the image, you can see that the gaps on the first row are not consistent.
However, note that if the gaps are larger, it becomes increasingly difficult to
notice the visual artefacts.

\image example-scalability-rounding-gaps.png

\section1 Walkthrough of ListView Example

This example shows the effect of using rounding when using a ListView. We
declare two ListView instances; each ListView instance uses the same delegate,
but the rounding property is set to false for the first list, and true for the
second list.

Note that the width of each list is calculated by dividing the container size. In
the first case this is not rounded, and in the second case it is rounded.

\snippet examples/native/scalability/rounding/ListsPage.qml page_a
\dots 4
\snippet examples/native/scalability/rounding/ListsPage.qml row_a
\dots 8
\snippet examples/native/scalability/rounding/ListsPage.qml row_b
\dots 4
\snippet examples/native/scalability/rounding/ListsPage.qml page_b

This is the list delegate, which checks the rounding property of the list.
In this case, the item height is a fixed pixel value.

\snippet examples/native/scalability/rounding/ListsPage.qml listitem_a
\snippet examples/native/scalability/rounding/ListsPage.qml listitem_b


As the slider is moved, you can see that the width of the boundary of the list
items is shown as a different width depending on the exact ratio of the
container size. However, in the right hand example, the rounding means that the
appearance is consistent whatever the container size.

\image example-scalability-rounding-lists.png

In practice, with more subtle list item separators, these artefacts would not
be as visible to the user.

\section1 Conclusion

All measurements, sizes, gaps, margins, spacings, items, must all be either
defined as, or eventually calcuated as integer pixel values. This applies to
the entire layout containment hierarchy. All division operators should be
followed by either rounding, floor, or ceiling operations.

In practice, if the platform style uses subtle highlights and list item
separators, then many of these symptoms will remain un-noticed. However, it is
recommended that the rounding rules are still applied to provide future-proof
layout definitions, and to ensure that the user interface is consistent throughout.

*/
