Kirigami-addons

FormComboBoxDelegate.qml
1/*
2 * Copyright 2022 Devin Lin <devin@kde.org>
3 * SPDX-License-Identifier: LGPL-2.0-or-later
4 */
5
6import QtQuick 2.15
7import QtQuick.Controls 2.15 as QQC2
8import QtQuick.Layouts 1.15
9
10import org.kde.kirigami 2.19 as Kirigami
11import org.kde.kirigamiaddons.delegates as Delegates
12
13/**
14 * @brief A Form delegate that corresponds to a combobox.
15 *
16 * This component is used for individual settings that can have multiple
17 * possible values shown in a vertical list, typically defined in a ::model.
18 *
19 * Many of its properties require familiarity with QtQuick.Controls.ComboBox.
20 *
21 * Use the inherited QtQuick.Controls.AbstractButton.text property to define
22 * the main text of the combobox.
23 *
24 * If you need a purely on/off toggle, use a FormSwitchDelegate instead.
25 *
26 * If you need an on/off/tristate toggle, use a FormCheckDelegate instead.
27 *
28 * If you need multiple toggles instead of multiple values for the same
29 * setting, consider using a FormRadioDelegate.
30 *
31 * @since KirigamiAddons 0.11.0
32 *
33 * @see QtQuick.Controls.AbstractButton
34 * @see FormSwitchDelegate
35 * @see FormCheckDelegate
36 * @see FormRadioDelegate
37 *
38 * @inherit AbstractFormDelegate
39 */
40AbstractFormDelegate {
41 id: controlRoot
42
43 /**
44 * @brief This signal is emitted when the item at @p index is activated
45 * by the user.
46 */
47 signal activated(int index)
48
49 /**
50 * @brief This signal is emitted when the Return or Enter key is pressed
51 * while an editable combo box is focused.
52 *
53 * @see editable
54 */
55 signal accepted()
56
57 /**
58 * @brief A label that contains secondary text that appears under the
59 * inherited text property.
60 *
61 * This provides additional information shown in a faint gray color.
62 *
63 * This is supposed to be a short text and the API user should avoid
64 * making it longer than two lines.
65 */
66 property string description: ""
67
68 /**
69 * @brief This property holds the value of the current item in the combobox.
70 */
71 property alias currentValue: combobox.currentValue
72
73 /**
74 * @brief This property holds the text of the current item in the combobox.
75 *
76 * @see displayText
77 */
78 property alias currentText: combobox.currentText
79
80 /**
81 * @brief This property holds the model providing data for the combobox.
82 *
83 * @see displayText
84 * @see QtQuick.Controls.ComboBox.model
85 * @see <a href="https://doc.qt.io/qt-6/qtquick-modelviewsdata-modelview.html">Models and Views in QtQuick</a>
86 */
87 property var model
88
89 /**
90 * @brief This property holds the `textRole` of the internal combobox.
91 *
92 * @see QtQuick.Controls.ComboBox.textRole
93 */
94 property alias textRole: combobox.textRole
95
96 /**
97 * @brief This property holds the `valueRole` of the internal combobox.
98 *
99 * @see QtQuick.Controls.ComboBox.valueRole
100 */
101 property alias valueRole: combobox.valueRole
102
103 /**
104 * @brief This property holds the `currentIndex` of the internal combobox.
105 *
106 * default: `-1` when the ::model has no data, `0` otherwise
107 *
108 * @see QtQuick.Controls.ComboBox.currentIndex
109 */
110 property alias currentIndex: combobox.currentIndex
111
112 /**
113 * @brief This property holds the `highlightedIndex` of the internal combobox.
114 *
115 * @see QtQuick.Controls.ComboBox.highlightedIndex
116 */
117 property alias highlightedIndex: combobox.highlightedIndex
118
119 /**
120 * @brief This property holds the `displayText` of the internal combobox.
121 *
122 * This can be used to slightly modify the text to be displayed in the combobox, for instance, by adding a string with the ::currentText.
123 *
124 * @see QtQuick.Controls.ComboBox.displayText
125 */
126 property alias displayText: combobox.displayText
127
128 /**
129 * @brief This property holds the `editable` property of the internal combobox.
131 * This turns the combobox editable, allowing the user to specify
132 * existing values or add new ones.
133 *
134 * Use this only when ::displayMode is set to
135 * FormComboBoxDelegate.ComboBox.
136 *
137 * @see QtQuick.Controls.ComboBox.editable
138 */
139 property alias editable: combobox.editable
140
141 /**
142 * @brief This property holds the `editText` property of the internal combobox.
143 *
144 * @see QtQuick.Controls.ComboBox.editText
145 */
146 property alias editText: combobox.editText
147
148 /** @brief The enum used to determine the ::displayMode. **/
149 enum DisplayMode {
150 /**
151 * A standard combobox component containing a vertical list of values.
152 */
153 ComboBox,
154 /**
155 * A button with similar appearance to a combobox that, when clicked,
156 * shows a Kirigami.OverlaySheet at the middle of the window
157 * containing a vertical list of values.
158 */
159 Dialog,
160 /**
161 * A button with similar appearance to a combobox that, when clicked,
162 * shows a Kirigami.ScrollablePage in a new window containing a
163 * vertical list of values.
164 */
165 Page
166 }
168 /**
169 * @brief This property holds what display mode the delegate should show as.
170 *
171 * Set this property to the desired ::DisplayMode.
172 *
173 * default: `FormComboBoxDelegate.ComboBox`
174 *
175 * @see DisplayMode
176 */
177 property int displayMode: Kirigami.Settings.isMobile ? FormComboBoxDelegate.Dialog : FormComboBoxDelegate.ComboBox
178
179 /**
180 * @brief The delegate component to use as entries in the combobox display mode.
181 */
182 property Component comboBoxDelegate: Delegates.RoundedItemDelegate {
183 implicitWidth: ListView.view ? ListView.view.width : Kirigami.Units.gridUnit * 16
184 text: controlRoot.textRole ? (Array.isArray(controlRoot.model) ? modelData[controlRoot.textRole] : model[controlRoot.textRole]) : modelData
185 highlighted: controlRoot.currentIndex === index
186 }
187
188 /**
189 * @brief The delegate component to use as entries for each value in the dialog and page display mode.
190 */
191 property Component dialogDelegate: Delegates.RoundedItemDelegate {
192 implicitWidth: ListView.view ? ListView.view.width : Kirigami.Units.gridUnit * 16
193 text: controlRoot.textRole ? (Array.isArray(controlRoot.model) ? modelData[controlRoot.textRole] : model[controlRoot.textRole]) : modelData
194 checked: controlRoot.currentIndex === index
195
196 Layout.topMargin: index == 0 ? Math.round(Kirigami.Units.smallSpacing / 2) : 0
197
198 onClicked: {
199 controlRoot.currentIndex = index;
200 controlRoot.activated(index);
201 controlRoot.closeDialog();
202 }
203 }
204
205 /**
206 * @brief Closes the dialog or layer.
207 *
208 * This function can be used when reimplementing the ::page or ::dialog.
209 */
210 function closeDialog() {
211 if (_selectionPageItem) {
212 _selectionPageItem.closeDialog();
213 _selectionPageItem = null;
214 }
215
216 if (dialog) {
217 dialog.close();
218 }
219 }
220
221 property var _selectionPageItem: null
222 property real __indicatorMargin: controlRoot.indicator && controlRoot.indicator.visible && controlRoot.indicator.width > 0 ? controlRoot.spacing + indicator.width + controlRoot.spacing : 0
223
224 leftPadding: horizontalPadding + (!controlRoot.mirrored ? 0 : __indicatorMargin)
225 rightPadding: horizontalPadding + (controlRoot.mirrored ? 0 : __indicatorMargin)
226
227
228 // use connections instead of onClicked on root, so that users can supply
229 // their own behaviour.
230 Connections {
231 target: controlRoot
232 function onClicked() {
233 if (controlRoot.displayMode === FormComboBoxDelegate.Dialog) {
234 controlRoot.dialog.open();
235 } else if (controlRoot.displayMode === FormComboBoxDelegate.Page) {
236 controlRoot._selectionPageItem = applicationWindow().pageStack.pushDialogLayer(page)
237 } else {
238 combobox.popup.open();
239 }
240 }
241 }
242
243 /**
244 * @brief The dialog component used for the combobox.
245 *
246 * This property allows to override the internal dialog
247 * with a custom component.
248 */
249 property var dialog: Kirigami.Dialog {
250 id: dialog
251 showCloseButton: false
252 title: controlRoot.text
253 preferredWidth: Kirigami.Units.gridUnit * 16
254 parent: QQC2.Overlay.overlay
255
256 ColumnLayout {
257 spacing: 0
258
259 Repeater {
260 model: controlRoot.model
261 delegate: controlRoot.dialogDelegate
262 }
263
264 QQC2.TextField {
265 visible: controlRoot.editable
266 onTextChanged: controlRoot.editText = text;
267 Layout.fillWidth: true
268 }
269 }
270 }
271
272 /**
273 * @brief The page component used for the combobox, if applicable.
274 *
275 * This property allows to override the internal
276 * Kirigami.ScrollablePage with a custom component.
277 */
278 property Component page: Kirigami.ScrollablePage {
279 title: controlRoot.text
280
281 ListView {
282 spacing: 0
283 model: controlRoot.model
284 delegate: controlRoot.dialogDelegate
285
286 footer: QQC2.TextField {
287 visible: controlRoot.editable
288 onTextChanged: controlRoot.editText = text;
289 Layout.fillWidth: true
290 }
291 }
292 }
293
294 function indexOfValue(value) {
295 return combobox.indexOfValue(value);
296 }
297
298 focusPolicy: Qt.StrongFocus
299 Accessible.description: description
300 Accessible.onPressAction: controlRoot.clicked()
301
302 contentItem: ColumnLayout {
303 spacing: Kirigami.Units.smallSpacing
304
305 RowLayout {
306 Layout.fillWidth: true
307 spacing: Kirigami.Units.smallSpacing
308
309 QQC2.Label {
310 Layout.fillWidth: true
311 text: controlRoot.text
312 elide: Text.ElideRight
313 color: controlRoot.enabled ? Kirigami.Theme.textColor : Kirigami.Theme.disabledTextColor
314 wrapMode: Text.Wrap
315 maximumLineCount: 2
316 Accessible.ignored: true
317 }
318
319 QQC2.Label {
320 Layout.alignment: Qt.AlignRight
321 Layout.rightMargin: Kirigami.Units.smallSpacing
322 color: Kirigami.Theme.disabledTextColor
323 text: controlRoot.displayText
324 visible: controlRoot.displayMode === FormComboBoxDelegate.Dialog || controlRoot.displayMode === FormComboBoxDelegate.Page
325 }
326
327 QQC2.ComboBox {
328 id: combobox
329 focusPolicy: Qt.NoFocus // provided by parent
330 model: controlRoot.model
331 visible: controlRoot.displayMode == FormComboBoxDelegate.ComboBox
332 delegate: controlRoot.comboBoxDelegate
333 currentIndex: controlRoot.currentIndex
334 onActivated: index => controlRoot.activated(index)
335 onAccepted: controlRoot.accepted()
336 popup.contentItem.clip: true
337 }
338
339 FormArrow {
340 Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
341 direction: Qt.DownArrow
342 visible: controlRoot.displayMode === FormComboBoxDelegate.Dialog || controlRoot.displayMode === FormComboBoxDelegate.Page
343 }
344 }
345
346 QQC2.Label {
347 visible: controlRoot.description !== ""
348 Layout.fillWidth: true
349 text: controlRoot.description
350 color: Kirigami.Theme.disabledTextColor
351 wrapMode: Text.Wrap
352 Accessible.ignored: true
353 }
354 }
355}
356
An arrow UI component used in Form delegates.
Definition FormArrow.qml:22
A Form delegate that corresponds to a combobox.
string description
A label that contains secondary text that appears under the inherited text property.
Component comboBoxDelegate
The delegate component to use as entries in the combobox display mode.
int displayMode
This property holds what display mode the delegate should show as.
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 3 2024 11:46:57 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.