// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \page qtquick-positioning.html
    \previouspage qtquick-properties.html
    \nextpage qtquick-annotations.html

    \title Scalable layouts

    The position of a \l{glossary-component}{component} in a UI is either
    absolute or relative to other components. The visual components exist at a
    particular location in the screen coordinate system at any instant in time.
    The x and y coordinates of a visual component are relative to those of its
    visual parent, with the top-left corner having the coordinate (0, 0).

    If you are designing a static UI,
    \l{Important Concepts In Qt Quick - Positioning#manual-positioning}
    {manual positioning} provides the most efficient form of positioning
    components. For a dynamic UI, use the following positioning
    methods:

    \table
        \header
            \li Action
            \li Purpose
        \row
            \li \l{Setting bindings}
            \li To connect the properties of components.
        \row
            \li \l{Setting anchors and margins}
            \li To set the rules for attaching the component to other components. You can define
                the distance between the components and add margins on the components.
        \row
            \li \l{Aligning and distributing components}
            \li To align the unanchored components left, right, vertical, horizontal, top, and
                bottom with respect to each other.
        \row
            \li \l{Using positioners}
            \li To arrange components in rows, columns, grids, or flows.
        \row
            \li \l{Using layouts}
            \li To place the components in columns, grids, rows and stacks in layouts.
                The layouts adept the nature of dynamic and resizable UI.
        \row
            \li \l {Organizing components}
            \li To keep the components or controls collected with frames, groups,
                group boxes, pages, and panes.
    \endtable

    \section2 Setting bindings

    Using \e {Property Binding}, you can connect the properties of components. So, change in
    one can affect another. Once the binding is set, the property value is automatically
    kept up to date if the other properties or data values change.

    To set \e {Property Binding} to a component property:
    \list 1
        \li Go to the \uicontrol Properties view and select \imageactionicon
        (\uicontrol Actions) menu next to a property, and then select
        \uicontrol {Set Binding}.

        \image qmldesigner-set-expression.png "Actions menu"

        \li In \uicontrol {Binding Editor}, select a component and a property from
        lists of available components and their properties.

        \image qmldesigner-binding-editor.png "Binding Editor"
    \endlist

    When a binding is set, the \uicontrol Actions menu icon changes to
    \imageactioniconbinding.
    To remove bindings, select \uicontrol Actions > \uicontrol Reset.

   See \l {Adding bindings between properties} to learn how to set bindings using
   the \uicontrol Bindings tab in the \l Connections view.

    \note For better performance, set anchors and margins for binding
    components. For example, instead of setting \c {parent.width} for a
    component, anchor the component to its sibling components on the
    left and the right.

    \section2 Setting anchors and margins

    In an \l{Important Concepts In Qt Quick - Positioning#anchors}
    {anchor-based} layout, each component has a set of
    invisible \e anchor lines: top, bottom, left, right, fill, horizontal
    center, vertical center, and baseline. Use anchors to place a component either
    adjacent to or inside of another component by attaching one or more of the
    component's anchor lines to the anchor lines of the other component. If a
    component changes, the components that are anchored to it will adjust
    automatically to maintain the anchoring.

    To set anchors and margins for components:

    \list 1
        \li Go to \l Properties > \uicontrol Layout > \uicontrol Anchors.
        \li Select the corresponding button for the anchor you want for the component.
            You can combine multiple anchors. For each selected button, you can
            choose the target component of that anchor from the corresponding dropdown.
        \li To apply fill anchors to a component, select
            \imageanchorfill (\uicontrol {Fill to Parent}).
        \li To reset the anchors to their saved state, select
            \imageqtcreatoranchorsreseticon (\uicontrol {Reset Anchors}).
    \endlist

    \image qmldesigner-anchor-buttons.png "Anchor buttons"

    For performance reasons, you can only anchor a component to its siblings
    or direct parent. By default, a component is anchored to its parent when
    you use the anchor buttons. To anchor to a sibling of the component, select
    the sibling component as \uicontrol Target.

    Arbitrary anchoring is not supported. For example, don't select:
    \c {anchor.left: parent.right}. Select:
    \c {anchor.left: parent.left}. When you use the anchor buttons, anchors to
    the parent component are always set to the same side. However, anchors
    to sibling components are set to the opposite side:
    \c {anchor.left: sibling.right}. This allows you to keep sibling components
    together.

    In the following image, the left edge of \e rectangle2 is anchored to the
    right edge of the sibling on its left side, \e rectangle1, while its top
    edge is anchored to the top of its parent.

    \image studio-qmldesigner-anchors.webp "Anchoring sibling components"

    The anchors are set as follows in code:

    \qml
        Rectangle {
            id: rectangle2
            width: 84
            height: 84
            color: "#967de7"
            anchors.left: rectangle1.right
            anchors.top: parent.top
            anchors.leftMargin: 51
            anchors.topMargin: 56
        }
    \endqml

    To define the empty space outside of a component, set the
    \uicontrol Margin. Margins work for anchors. They do not take any
    effect when using layouts or absolute positioning.

    \section2 Aligning and distributing components

    For a group of components, select them to align
    and distribute them evenly. As the positions of the components are fixed,
    you cannot apply these functions to anchored components. For scalability,
    anchor the aligned and distributed components when your design is
    ready.

    \image qmldesigner-alignment.png "Aligning sibling components"

    Select the buttons in the \uicontrol Alignment field to align the top/bottom
    or left/right edges of a group of components to the one farthest away
    from the center of the group. For example, when left-aligning, the
    components are aligned to the leftmost component. You can also align the
    horizontal/vertical centers of components, or both.

    In the \uicontrol {Align to} field, select whether to align the components
    in respect to the selection, the root component, or a \e {key component}
    that you select in the \uicontrol {Key object} field. The key component must
    be a part of the selection.

    Distribute either \e components or the \e spacing between them.
    If the components or spacing cannot be distributed to equal pixel values
    without ending up with half pixels, you receive a notification.
    Either allow \QDS to distribute components or spacing using the closest
    values possible or tweak your design so that the components and spacing
    is distributed perfectly.

    When distributing components, select the buttons in the
    \uicontrol {Distribute objects} field to determine whether the
    distance between components is calculated from their top/bottom
    or left/right edges or their horizontal/vertical center.

    When distributing spacing, select the buttons in the
    \uicontrol {Distribute spacing} field to determine whether
    it is distributed evenly within a target area or at
    specified distances, calculated from a starting point.
    Select the orientation in which the components are distributed
    evenly within the target area: horizontally along the x axis or vertically
    along the y axis.

    Alternatively, distribute spacing in pixels by selecting one of the
    starting point buttons: top/left or bottom/right edge of the target area or
    item, or its center. The edge to use depends on whether the items are
    distributed horizontally or vertically:

    \list
        \li Select \imagedistributeorigintopleft
            and \imagedistributespacinghorizontal
            to use the left edge of the target area or item as the starting
            point.
        \li Select \imagedistributeorigintopleft
            and \imagedistributespacingvertical
            to use the top edge.
        \li Select \imagedistributeoriginbottomright
            and \imagedistributespacinghorizontal
            to use the right edge.
        \li Select \imagedistributeoriginbottomright
            and \imagedistributespacingvertical
            to use the bottom edge.
    \endlist

    \note Some components might end up outside the target area.

    In the \uicontrol {Pixel spacing} field, set the space between
    components in pixels. To disable the distribution of spacing in
    pixels, select \imagedistributeoriginnone
    button.

    \section2 Using positioners

    Positioner components are containers that manage the positions of their
    child components. For many use cases, the best positioner to use is a simple
    column, row, flow, or grid. Use the components available in
    \uicontrol Components > \uicontrol {Default Components} >
    \uicontrol Positioner to position the children of a component in these
    formations in the most efficient manner possible.

    To position several components in a
    \uicontrol Column \imagecolumnpositionericon16px,
    \uicontrol Row \imagerowpositionericon16px,
    \uicontrol Grid \imagegridpositionericon16px,
    or \uicontrol Flow \imageflowpositionericon16px :

    \list 1
        \li Select the components in the \l {2D} view.
        \li Right-click anywhere in the \uicontrol 2D view and
            select \uicontrol Positioner > \uicontrol Row,
            \uicontrol Column, \uicontrol Grid or \uicontrol {Flow Positioner}.
    \endlist

    \section3 Column positioner

    A \uicontrol Column positions its child components along a single column.
    It is used as a convenient way to vertically position a series of
    components without using anchors.

    \image qtquick-positioner-column-properties.png "Column properties"

    For all positioners, set the spacing between the child
    components in the \uicontrol Spacing field.

    In addition, set the vertical and horizontal padding between
    content and the left, right, top, and bottom edges of components
    in the \l Padding section.

    \section3 Row and the Flow positioners

    A \uicontrol Row positions its child components along a single row. It is
    used as a convenient way to horizontally position a series of components
    without using anchors.

    The \uicontrol Flow component positions its child components like words on a
    page, wrapping them to create rows or columns of components.

    \image qtquick-positioner-flow-properties.png "The Flow properties"

    For flow and row positioners, also set the direction of a flow to
    either left-to-right or top-to-bottom in the \uicontrol Flow field.
    Components are positioned next to to each other according to the value you
    set in the \uicontrol {Layout direction} field until the width or height of
    the \uicontrol Flow component is exceeded, then wrapped to the next row or
    column.

    Set the layout direction to either \uicontrol LeftToRight or
    \uicontrol RightToLeft in the \uicontrol {Layout direction} field. If
    the width of the row is explicitly set, the left anchor remains to the
    left of the row and the right anchor remains to the right of it.

    \section3 Grid positioner

    A \uicontrol Grid creates a grid of cells that is large enough to hold all
    of its child components, and places these components in the cells from left
    to right and top to bottom. Each component is positioned at the top-left
    corner of its cell with position (0, 0).

    \QDS generates the grid based on the positions of the child components in
    the \l {2D} view. You can modify the number of rows and columns in the
    \uicontrol Rows and \uicontrol Columns fields.

    \image qtquick-positioner-grid-properties.png "Grid properties"

    In addition to the flow and layout direction, you can set the horizontal
    and vertical alignment of grid components. By default, grid components are
    vertically aligned to the top. Horizontal alignment follows the value of the
    \uicontrol {Layout direction} field. For example, when layout direction is
    set to \uicontrol LeftToRight, the components are aligned on the left.

    To mirror the layout, set the layout direction to \uicontrol RightToLeft.
    To also mirror the horizontal alignment of components, select
    \uicontrol AlignRight in the \uicontrol {Alignment H} field.

    \section2 Using layouts

    Use the components available in \uicontrol Components
    > \uicontrol {Qt Quick Layouts} to arrange components in UIs.

    Unlike positioners, layouts manage both the positions and sizes of their
    child components, and are therefore well suited for dynamic and resizable
    UIs. However, do not select fixed positions and
    sizes for the child components in the \l{2D Geometry}{Geometry - 2D} section
    in \l Properties, unless their implicit sizes are not satisfactory.

    Use anchors or the width and height properties of the layout itself
    to select its size in respect to its non-layout parent component. However,
    do not anchor the child components within layouts.

    To put components in \uicontrol {Grid Layout}:

    \list 1
        \li Select all the components and right-click on one of them.
        \li From the context menu, select \uicontrol Layout > \uicontrol {Grid Layout}.
            \image qtquick-layout-context-menu.webp "Grid Layout in the context-menu"
        \li After you assign them to \uicontrol {Grid Layout}, the components are arranged
            in rows and columns.
            \image qtquick-layout-in-grid.webp "Components in grid rows and columns"

    \endlist

    To make the components adept the width and height within the grid, follow these steps:
    \list 1
        \li Select a \uicontrol Rectangle component in the \l {2D} view
            and go to \uicontrol Layout in the \l {Properties} view.
        \li In the \uicontrol {Fill layout}, select both the \uicontrol Width and
            \uicontrol Height checkboxes.
            \image qtquick-layout-grid-layout-properties.webp "Layout properties for the component"
            \note Manipulate the \uicontrol {Row span} and the \uicontrol {Column span}
                  to allow the components to take more row and column spaces within the
                  \uicontrol {Grid Layout}.
        \li Repeat the previous steps for all the \uicontrol Rectangle components.
        \li Select \uicontrol {Grid Layout} in the \uicontrol Navigator view.
        \li Go to \uicontrol {Geometry-2D} in the \uicontrol Properties view. In
            \uicontrol Size, increase the \uicontrol Width and \uicontrol Height.
        \li All the \uicontrol Rectangle components follow the change accordingly.
            \image qtquick-layout-in-grid-enlarged.webp "Components follow the change in grid size"
    \endlist

    \section3 Stack Layout

    To stack components on top of each other you can use \uicontrol {Stack Layout}.

    To use \uicontrol {Stack Layout}:
    \list 1
        \li Drag the \uicontrol {Stack Layout} component to the \uicontrol 2D view
            or \uicontrol Navigator view.
        \li Drag the components you want to stack from the \uicontrol Components view to
            the \uicontrol 2D view or \uicontrol Navigator view, and place on the top of
            the \uicontrol {Stack Layout} component.
            \note Alternatively, you can add components to the \uicontrol {Stack Layout} by
                selecting the \imageplus button next to the
                \uicontrol {Stack Layout} component name in the \l {2D} view.
        \li To move between components of \uicontrol {Stack Layout},
            select the \uicontrol {Stack Layout} component in the \uicontrol 2D view. Then
            select the \imageprev
            (\uicontrol Previous) and \imagenext
            (\uicontrol Next) buttons. This updates the \uicontrol {Current index} of the
            \uicontrol {Stack Layout} and brings the \uicontrol {Current index}
            component on top of the stack.
            \note Alternatively, select the \uicontrol {Stack Layout} component, then
            go to the \uicontrol Properties view > \uicontrol {Stack Layout}, and
            update the \uicontrol {Current index}. The index starts from "0" (zero).
    \endlist

    Follow the example below to understand how the \uicontrol {Stack Layout} works:

    \list 1
        \li Drag a \uicontrol {Stack Layout} from the \uicontrol Component view to
            the \uicontrol Navigator or \uicontrol 2D view.
        \li Drag three \uicontrol Rectangle components to the \uicontrol {Stack Layout} component
            in the \uicontrol Navigator view.

            \image studio-stack-layout-components.webp "Components in the Stack Layout"

        \li Select a rectangle component and go to the \uicontrol Properties view > Rectangle >
            \uicontrol {Fill color}, and change it to "#ff0000".
        \li For the second rectangle, follow the previous process and change the
            \uicontrol {Fill color} to "0000ff".
        \li For the third rectangle, follow the previous process and change the
            \uicontrol {Fill color} to "00ff00".
        \li Drag a \uicontrol Slider component from the \uicontrol Components view to the
            \uicontrol 2D view.
        \li Select the \uicontrol Slider component and go to the \uicontrol Properties view
            > \uicontrol Slider. Set the \uicontrol Value to "0", \uicontrol From to "0",
            \uicontrol To to "2", and \uicontrol {Step size} to "1".

            \image studio-slider-setup-for-stack-layout-components.webp "Adjusting the Slider"

        \li Go to the \uicontrol Navigator view and select the \uicontrol {Stack Layout} component.
        \li Go to the \uicontrol Properties view > \uicontrol {Stack Layout}. Select
            \imageactionicon to access the context menu, then select
            \uicontrol {Set Binding}.

            \image studio-stack-layout-add-binding.webp "Getting the context menu to bind components"

        \li In the \uicontrol {Binding Editor}, in the left dropdown, select \uicontrol Slider;
            in the right dropdown, select \uicontrol Value. Select \uicontrol OK to accept
            the binding.

            \image studio-stack-layout-binding-setup.webp "Setting binding rules"

        \li Select \uicontrol {Live Preview} or \uicontrol {Run Project} to run the application.
        \li Drag the slider to change the color in the rectangle.

            \image studio-stack-layout-example-output.webp "Stack Layout example output"
    \endlist

    \section2 Organizing components

    You can use the \uicontrol Frame and \uicontrol {Group Box} controls to
    draw frames around groups of controls.

    If you don't want a frame, use the \uicontrol Group component instead.

    The following table lists the UI controls that you can use to organize
    components in UIs (since Qt 5.7). The \e Location column indicates the
    location of the component in \uicontrol Components.

    \table
    \header
        \li Icon
        \li Name
        \li Location
        \li Purpose
    \row
        \li \imageframeicon16
        \li \l [QtQuickControls]{Frame}
        \li Qt Quick Controls
        \li A visual frame around a group of controls.
    \row
        \li \imagegroup16px
        \li Group
        \li Qt Quick Studio Components
        \li Enables handling the selected components as a group.
    \row
        \li \imagegroupboxicon16
        \li \l [QtQuickControls]{GroupBox}{Group Box}
        \li Qt Quick Controls
        \li A titled visual frame around a group of controls.
    \row
        \li \imagepageicon16
        \li \l [QtQuickControls]{Page}
        \li Qt Quick Controls
        \li A styled page control with support for a header and footer.
    \row
        \li \imagepaneicon16
        \li \l [QtQuickControls]{Pane}
        \li Qt Quick Controls
        \li A background that matches the application style and theme.
    \endtable

    \note
        \br
        To access \uicontrol Frame, \uicontrol {Group Box}, \uicontrol Pane, and
        \uicontrol Page controls, go to \uicontrol Components >
        \uicontrol {Qt Quick Controls}.
        \br
        To access \uicontrol Group control,
        go to \uicontrol Components > \uicontrol {Qt Quick Studio Components}.
*/
