File indexing completed on 2024-04-14 03:53:46

0001 /*
0002  *  SPDX-FileCopyrightText: 2017 Marco Martin <mart@kde.org>
0003  *
0004  *  SPDX-License-Identifier: LGPL-2.0-or-later
0005  */
0006 
0007 #ifndef FORMLAYOUTATTACHED_H
0008 #define FORMLAYOUTATTACHED_H
0009 
0010 #include <QObject>
0011 #include <QQmlEngine>
0012 
0013 class QQuickItem;
0014 
0015 /**
0016  * This attached property contains the information for decorating a org::kde::kirigami::FormLayout:
0017  *
0018  * It contains the text labels of fields and information about sections.
0019  *
0020  * Some of its properties can be used with other <a href="https://doc.qt.io/qt-6/qml-qtquick-layouts-layout.html">Layout</a> types.
0021  * @code
0022  * import org.kde.kirigami 2.3 as Kirigami
0023  * Kirigami.FormLayout {
0024  *    TextField {
0025  *       Kirigami.FormData.label: "Label:"
0026  *    }
0027  *    TextField {
0028  *       Kirigami.FormData.label: "Label:"
0029  *    }
0030  * }
0031  * @endcode
0032  * @see org::kde::kirigami::FormLayout
0033  * @since 2.3
0034  */
0035 class FormLayoutAttached : public QObject
0036 {
0037     Q_OBJECT
0038     QML_NAMED_ELEMENT(FormData)
0039     QML_ATTACHED(FormLayoutAttached)
0040     QML_UNCREATABLE("")
0041     /**
0042      * The label for a org::kde::kirigami::FormLayout field
0043      */
0044     Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged FINAL)
0045     /**
0046      * The alignment for the label of a org::kde::kirigami::FormLayout field
0047      */
0048     Q_PROPERTY(int labelAlignment READ labelAlignment WRITE setLabelAlignment NOTIFY labelAlignmentChanged FINAL)
0049     /**
0050      * If true, the child item of a org::kde::kirigami::FormLayout becomes a section separator, and
0051      * may have different looks:
0052      * * To make it just a space between two fields, just put an empty item with FormData.isSection:
0053      * @code
0054      * TextField {
0055      *     Kirigami.FormData.label: "Label:"
0056      * }
0057      * Item {
0058      *     Kirigami.FormData.isSection: true
0059      * }
0060      * TextField {
0061      *     Kirigami.FormData.label: "Label:"
0062      * }
0063      * @endcode
0064      *
0065      * * To make it a space with a section title:
0066      * @code
0067      * TextField {
0068      *     Kirigami.FormData.label: "Label:"
0069      * }
0070      * Item {
0071      *     Kirigami.FormData.label: "Section Title"
0072      *     Kirigami.FormData.isSection: true
0073      * }
0074      * TextField {
0075      *     Kirigami.FormData.label: "Label:"
0076      * }
0077      * @endcode
0078      *
0079      * * To make it a space with a section title and a separator line:
0080      * @code
0081      * TextField {
0082      *     Kirigami.FormData.label: "Label:"
0083      * }
0084      * Kirigami.Separator {
0085      *     Kirigami.FormData.label: "Section Title"
0086      *     Kirigami.FormData.isSection: true
0087      * }
0088      * TextField {
0089      *     Kirigami.FormData.label: "Label:"
0090      * }
0091      * @endcode
0092      * @see org::kde::kirigami::FormLayout
0093      */
0094     Q_PROPERTY(bool isSection READ isSection WRITE setIsSection NOTIFY isSectionChanged FINAL)
0095 
0096     /**
0097      * This property can only be used
0098      * in conjunction with a Kirigami.FormData.label,
0099      * often in a layout that is a child of a org::kde::kirigami::FormLayout.
0100      *
0101      * It then turns the item specified into a "buddy"
0102      * of the label, making it work as if it were
0103      * a child of the org::kde::kirigami::FormLayout.
0104      *
0105      * A buddy item is useful for instance when the label has a keyboard accelerator,
0106      * which when triggered provides active keyboard focus to the buddy item.
0107      *
0108      * By default buddy is the item that Kirigami.FormData is attached to.
0109      * Custom buddy can only be a direct child of that item; nested components
0110      * are not supported at the moment.
0111      *
0112      * @code
0113      * Kirigami.FormLayout {
0114      *     Layouts.ColumnLayout {
0115      *         // If the accelerator is in the letter S,
0116      *         // pressing Alt+S gives focus to the slider.
0117      *         Kirigami.FormData.label: "Slider label:"
0118      *         Kirigami.FormData.buddyFor: slider
0119      *
0120      *         QQC2.Slider {
0121      *             id: slider
0122      *             from: 0
0123      *             to: 100
0124      *             value: 50
0125      *         }
0126      *     }
0127      * }
0128      * @endcode
0129      */
0130     Q_PROPERTY(QQuickItem *buddyFor READ buddyFor WRITE setBuddyFor NOTIFY buddyForChanged FINAL)
0131 
0132 public:
0133     explicit FormLayoutAttached(QObject *parent = nullptr);
0134     ~FormLayoutAttached() override;
0135 
0136     void setLabel(const QString &text);
0137     QString label() const;
0138 
0139     void setIsSection(bool section);
0140     bool isSection() const;
0141 
0142     QQuickItem *buddyFor() const;
0143     void setBuddyFor(QQuickItem *aBuddyFor);
0144 
0145     int labelAlignment() const;
0146     void setLabelAlignment(int alignment);
0147 
0148     // QML attached property
0149     static FormLayoutAttached *qmlAttachedProperties(QObject *object);
0150 
0151 Q_SIGNALS:
0152     void labelChanged();
0153     void isSectionChanged();
0154     void buddyForChanged();
0155     void labelAlignmentChanged();
0156 
0157 private:
0158     void resetBuddyFor();
0159 
0160     QString m_label;
0161     QString m_actualDecoratedLabel;
0162     QString m_decoratedLabel;
0163     QPointer<QQuickItem> m_buddyFor;
0164     bool m_isSection = false;
0165     int m_labelAlignment = 0;
0166 };
0167 
0168 QML_DECLARE_TYPEINFO(FormLayoutAttached, QML_HAS_ATTACHED_PROPERTIES)
0169 
0170 #endif // FORMLAYOUTATTACHED_H