diff --git a/examples/gallerydata/contents/ui/gallery/FormLayoutGallery.qml b/examples/gallerydata/contents/ui/gallery/FormLayoutGallery.qml --- a/examples/gallerydata/contents/ui/gallery/FormLayoutGallery.qml +++ b/examples/gallerydata/contents/ui/gallery/FormLayoutGallery.qml @@ -59,6 +59,11 @@ TextField { Kirigami.FormData.label: "Title:" } + TextField { + Kirigami.FormData.label: "Checkable label" + Kirigami.FormData.checkable: true + enabled: Kirigami.FormData.checked + } ColumnLayout { Layout.rowSpan: 3 Kirigami.FormData.label: "Label for radios:" diff --git a/src/controls/templates/FormLayout.qml b/src/controls/templates/FormLayout.qml --- a/src/controls/templates/FormLayout.qml +++ b/src/controls/templates/FormLayout.qml @@ -126,8 +126,12 @@ itemContainer.parent = lay; } - var buddy = buddyComponent.createObject(lay, {"item": item}) - + if (item.Kirigami.FormData.checkable) { + var buddy = checkableBuddyComponent.createObject(lay, {"item": item}) + } else { + var buddy = buddyComponent.createObject(lay, {"item": item}) + } + itemContainer.parent = lay; //if section, wee need another placeholder if (item.Kirigami.FormData.isSection) { @@ -214,4 +218,61 @@ } } } + Component { + id: checkableBuddyComponent + CheckBox { + id: labelItem + property var item + visible: item.visible + Kirigami.MnemonicData.enabled: item.Kirigami.FormData.buddyFor && item.Kirigami.FormData.buddyFor.activeFocusOnTab + Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.FormLabel + Kirigami.MnemonicData.label: item.Kirigami.FormData.label + + Layout.preferredHeight: item.Kirigami.FormData.label.length > 0 ? implicitHeight : Kirigami.Units.smallSpacing + + Layout.alignment: root.wideMode + ? (Qt.AlignRight | (item.Kirigami.FormData.buddyFor.height > height * 2 ? Qt.AlignTop : Qt.AlignVCenter)) + : (Qt.AlignLeft | Qt.AlignBottom) + Layout.topMargin: item.Kirigami.FormData.buddyFor.height > implicitHeight * 2 ? Kirigami.Units.smallSpacing/2 : 0 + + activeFocusOnTab: indicator.visible && indicator.enabled + text: labelItem.Kirigami.MnemonicData.richTextLabel + enabled: labelItem.item.Kirigami.FormData.enabled + checked: labelItem.item.Kirigami.FormData.checked + + onItemChanged: { + if (!item) { + labelItem.destroy(); + } + } + Shortcut { + sequence: labelItem.Kirigami.MnemonicData.sequence + onActivated: { + checked = !checked + item.Kirigami.FormData.buddyFor.forceActiveFocus() + } + } + onCheckedChanged: { + item.Kirigami.FormData.checked = checked + } + contentItem: Kirigami.Heading { + id: labelItemHeading + level: labelItem.item.Kirigami.FormData.isSection ? 3 : 5 + text: labelItem.text + verticalAlignment: root.wideMode ? Text.AlignVCenter : Text.AlignBottom + enabled: labelItem.item.Kirigami.FormData.enabled + leftPadding: parent.indicator.width + } + Rectangle { + enabled: labelItem.indicator.enabled + anchors.left: labelItemHeading.left + anchors.right: labelItemHeading.right + anchors.top: labelItemHeading.bottom + anchors.leftMargin: labelItemHeading.leftPadding + height: 1 * Kirigami.Units.devicePixelRatio + color: Kirigami.Theme.highlightColor + visible: labelItem.activeFocus && labelItem.indicator.visible + } + } + } } diff --git a/src/formlayoutattached.h b/src/formlayoutattached.h --- a/src/formlayoutattached.h +++ b/src/formlayoutattached.h @@ -94,6 +94,21 @@ */ Q_PROPERTY(bool isSection READ isSection WRITE setIsSection NOTIFY isSectionChanged) + /** + * If true a checkbox is prepended to the FormLayout item. + */ + Q_PROPERTY(bool checkable READ checkable WRITE setCheckable NOTIFY checkableChanged) + + /** + * This property is true when the checkbox of the FormLayout item is checked, @see checkable. + */ + Q_PROPERTY(bool checked READ checked WRITE setChecked NOTIFY checkedChanged) + + /** + * This property holds whether the label and the checkbox of the FormLayout item receive mouse and keyboard events. + */ + Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged) + /** * The Item the label will be considered a "Buddy" for, * which will be the parent item the attached property is in. @@ -114,6 +129,15 @@ void setIsSection(bool section); bool isSection() const; + + void setCheckable(bool checkable); + bool checkable() const; + + void setChecked(bool checked); + bool checked() const; + + void setEnabled(bool enabled); + bool enabled() const; QQuickItem *buddyFor() const; @@ -123,13 +147,19 @@ Q_SIGNALS: void labelChanged(); void isSectionChanged(); + void checkableChanged(); + void checkedChanged(); + void enabledChanged(); private: QString m_label; QString m_actualDecoratedLabel; QString m_decoratedLabel; QPointer m_buddyFor; bool m_isSection = false; + bool m_checkable = false; + bool m_checked = false; + bool m_enabled = true; }; QML_DECLARE_TYPEINFO(FormLayoutAttached, QML_HAS_ATTACHED_PROPERTIES) diff --git a/src/formlayoutattached.cpp b/src/formlayoutattached.cpp --- a/src/formlayoutattached.cpp +++ b/src/formlayoutattached.cpp @@ -61,6 +61,51 @@ return m_isSection; } +void FormLayoutAttached::setCheckable(bool checkable) +{ + if (checkable == m_checkable) { + return; + } + + m_checkable = checkable; + emit checkableChanged(); +} + +bool FormLayoutAttached::checkable() const +{ + return m_checkable; +} + +void FormLayoutAttached::setChecked(bool checked) +{ + if (checked == m_checked) { + return; + } + + m_checked = checked; + emit checkedChanged(); +} + +bool FormLayoutAttached::checked() const +{ + return m_checked; +} + +void FormLayoutAttached::setEnabled(bool enabled) +{ + if (enabled == m_enabled) { + return; + } + + m_enabled = enabled; + emit enabledChanged(); +} + +bool FormLayoutAttached::enabled() const +{ + return m_enabled; +} + QQuickItem *FormLayoutAttached::buddyFor() const { return m_buddyFor;