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

/*!
    \example widgets/windowflags
    \title Window Flags Example
    \examplecategory {User Interface Components}
    \ingroup examples-widgets
    \brief The Window Flags example shows how to use the window flags
    available in Qt.

    A window flag is either a type or a hint. A type is used to
    specify various window-system properties for the widget. A widget
    can only have one type, and the default is Qt::Widget. However, a
    widget can have zero or more hints. The hints are used to
    customize the appearance of top-level windows.

    A widget's flags are stored in a Qt::WindowFlags type which stores
    an OR combination of the flags.

    \image windowflags-example.png {Controller window and preview window}
    \caption Screenshot of the Window Flags example

    The example consists of two classes:

    \list
    \li \c ControllerWindow is the main application widget that allows
       the user to choose among the available window flags, and displays
       the effect on a separate preview window.
    \li \c PreviewWindow is a custom widget displaying the name of
       its currently set window flags in a read-only text editor.
    \endlist

    We will start by reviewing the \c ControllerWindow class, then we
    will take a look at the \c PreviewWindow class.

    \section1 ControllerWindow Class Definition

    \snippet widgets/windowflags/controllerwindow.h 0

    The \c ControllerWindow class inherits QWidget. The widget allows
    the user to choose among the available window flags, and displays
    the effect on a separate preview window.

    We declare a private \c updatePreview() slot to refresh the
    preview window whenever the user changes the window flags.

    We also declare several private functions to simplify the
    constructor: We call the \c createTypeGroupBox() function to
    create a radio button for each available window type, using the
    private \c createButton() function, and gather them within a group
    box. In a similar way we use the \c createHintsGroupBox() function
    to create a check box for each available hint, using the private
    \c createCheckBox() function.

    In addition to the various radio buttons and checkboxes, we need
    an associated \c PreviewWindow to show the effect of the currently
    chosen window flags.

    \image windowflags_controllerwindow.png
           {Controller window with the different flag types and hints}

    \section1 ControllerWindow Class Implementation

    \snippet widgets/windowflags/controllerwindow.cpp 0

    In the constructor we first create the preview window. Then we
    create the group boxes containing the available window flags using
    the private \c createTypeGroupBox() and \c createHintsGroupBox()
    functions. In addition we create a \uicontrol Quit button. We put the
    button and a stretchable space in a separate layout to make the
    button appear in the \c WindowFlag widget's right bottom corner.

    Finally, we add the button's layout and the two goup boxes to a
    QVBoxLayout, set the window title and refresh the preview window
    using the \c updatePreview() slot.

    \snippet widgets/windowflags/controllerwindow.cpp 1
    \snippet widgets/windowflags/controllerwindow.cpp 2

    The \c updatePreview() slot is called whenever the user changes
    any of the window flags. First we create an empty Qt::WindowFlags
    \c flags, then we determine which one of the types that is checked
    and add it to \c flags.

    \snippet widgets/windowflags/controllerwindow.cpp 3

    We also determine which of the hints that are checked, and add
    them to \c flags using an OR operator. We use \c flags to set the
    window flags for the preview window.

    \snippet widgets/windowflags/controllerwindow.cpp 4

    We adjust the position of the preview window. The reason we do
    that, is that playing around with the window's frame may on some
    platforms cause the window's position to be changed behind our
    back. If a window is located in the upper left corner of the
    screen, parts of the window may not be visible. So we adjust the
    widget's position to make sure that, if this happens, the window
    is moved within the screen's boundaries. Finally, we call
    QWidget::show() to make sure the preview window is visible.

    \omit
    \skipto pos
    \printuntil /^\}/
    \endomit

    \snippet widgets/windowflags/controllerwindow.cpp 5

    The private \c createTypeGroupBox() function is called from the
    constructor.

    First we create a group box, and then we create a radio button
    (using the private \c createRadioButton() function) for each of
    the available types among the window flags. We make Qt::Window the
    initially applied type. We put the radio buttons into a
    QGridLayout and install the layout on the group box.

    We do not include the default Qt::Widget type. The reason is that
    it behaves somewhat different than the other types. If the type is
    not specified for a widget, and it has no parent, the widget is a
    window. However, if it has a parent, it is a standard child
    widget. The other types are all top-level windows, and since the
    hints only affect top-level windows, we abandon the Qt::Widget
    type.

    \snippet widgets/windowflags/controllerwindow.cpp 6

    The private \c createHintsGroupBox() function is also called from
    the constructor.

    Again, the first thing we do is to create a group box. Then we
    create a checkbox, using the private \c createCheckBox() function,
    for each of the available hints among the window flags. We put the
    checkboxes into a QGridLayout and install the layout on the group
    box.

    \snippet widgets/windowflags/controllerwindow.cpp 7

    The private \c createCheckBox() function is called from \c
    createHintsGroupBox().

    We simply create a QCheckBox with the provided text, connect it to
    the private \c updatePreview() slot, and return a pointer to the
    checkbox.

    \snippet widgets/windowflags/controllerwindow.cpp 8

    In the private \c createRadioButton() function it is a
    QRadioButton we create with the provided text, and connect to the
    private \c updatePreview() slot. The function is called from \c
    createTypeGroupBox(), and returns a pointer to the button.

    \section1 PreviewWindow Class Definition

    \snippet widgets/windowflags/previewwindow.h 0

    The \c PreviewWindow class inherits QWidget. It is a custom widget
    that displays the names of its currently set window flags in a
    read-only text editor. It is also provided with a QPushbutton that
    closes the window.

    We reimplement the constructor to create the \uicontrol Close button and
    the text editor, and the QWidget::setWindowFlags() function to
    display the names of the window flags.

    \image windowflags_previewwindow.png {Preview window showing window flags}

    \section1 PreviewWindow Class Implementation

    \snippet widgets/windowflags/previewwindow.cpp 0

    In the constructor, we first create a QTextEdit and make sure that
    it is read-only.

    We also prohibit any line wrapping in the text editor using the
    QTextEdit::setLineWrapMode() function. The result is that a
    horizontal scrollbar appears when a window flag's name exceeds the
    width of the editor. This is a reasonable solution since we
    construct the displayed text with built-in line breaks. If no line
    breaks were guaranteed, using another QTextEdit::LineWrapMode
    would perhaps make more sense.

    Then we create the \uicontrol Close button, and put both the widgets
    into a QVBoxLayout before we set the window title.

    \snippet widgets/windowflags/previewwindow.cpp 1

    In our reimplementation of the \c setWindowFlags() function, we
    first set the widgets flags using the QWidget::setWindowFlags()
    function. Then we run through the available window flags, creating
    a text that contains the names of the flags that matches the \c
    flags parameter. Finally, we display the text in the widgets text
    editor.
*/
