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 `count` of the internal combobox.
91 *
92 * @see QtQuick.Controls.ComboBox.count
93 * @since Kirigami Addons 1.4.0
94 */
95 property alias count: combobox.count
96
97 /**
98 * @brief This property holds the `textRole` of the internal combobox.
99 *
100 * @see QtQuick.Controls.ComboBox.textRole
101 */
102 property alias textRole: combobox.textRole
103
104 /**
105 * @brief This property holds the `valueRole` of the internal combobox.
106 *
107 * @see QtQuick.Controls.ComboBox.valueRole
108 */
109 property alias valueRole: combobox.valueRole
110
111 /**
112 * @brief This property holds the `currentIndex` of the internal combobox.
113 *
114 * default: `-1` when the ::model has no data, `0` otherwise
115 *
116 * @see QtQuick.Controls.ComboBox.currentIndex
117 */
118 property alias currentIndex: combobox.currentIndex
120 /**
121 * @brief This property holds the `highlightedIndex` of the internal combobox.
122 *
123 * @see QtQuick.Controls.ComboBox.highlightedIndex
124 */
125 property alias highlightedIndex: combobox.highlightedIndex
126
127 /**
128 * @brief This property holds the `displayText` of the internal combobox.
129 *
130 * This can be used to slightly modify the text to be displayed in the combobox, for instance, by adding a string with the ::currentText.
132 * @see QtQuick.Controls.ComboBox.displayText
133 */
134 property alias displayText: combobox.displayText
135
136 /**
137 * @brief This property holds the `editable` property of the internal combobox.
138 *
139 * This turns the combobox editable, allowing the user to specify
140 * existing values or add new ones.
141 *
142 * Use this only when ::displayMode is set to
143 * FormComboBoxDelegate.ComboBox.
144 *
145 * @see QtQuick.Controls.ComboBox.editable
146 */
147 property alias editable: combobox.editable
148
149 /**
150 * @brief This property holds the `editText` property of the internal combobox.
151 *
152 * @see QtQuick.Controls.ComboBox.editText
153 */
154 property alias editText: combobox.editText
155
156 /** @brief The enum used to determine the ::displayMode. **/
157 enum DisplayMode {
158 /**
159 * A standard combobox component containing a vertical list of values.
160 */
161 ComboBox,
162 /**
163 * A button with similar appearance to a combobox that, when clicked,
164 * shows a Kirigami.OverlaySheet at the middle of the window
165 * containing a vertical list of values.
166 */
167 Dialog,
168 /**
169 * A button with similar appearance to a combobox that, when clicked,
170 * shows a Kirigami.ScrollablePage in a new window containing a
171 * vertical list of values.
172 */
173 Page
175
176 /**
177 * @brief This property holds what display mode the delegate should show as.
178 *
179 * Set this property to the desired ::DisplayMode.
181 * default: `FormComboBoxDelegate.ComboBox`
182 *
183 * @see DisplayMode
184 */
185 property int displayMode: Kirigami.Settings.isMobile ? FormComboBoxDelegate.Dialog : FormComboBoxDelegate.ComboBox
186
187 /**
188 * @brief The delegate component to use as entries in the combobox display mode.
189 */
190 property Component comboBoxDelegate: Delegates.RoundedItemDelegate {
191 implicitWidth: ListView.view ? ListView.view.width : Kirigami.Units.gridUnit * 16
192 text: controlRoot.textRole ? (Array.isArray(controlRoot.model) ? modelData[controlRoot.textRole] : model[controlRoot.textRole]) : modelData
193 highlighted: controlRoot.highlightedIndex === index
194 }
195
196 /**
197 * @brief The delegate component to use as entries for each value in the dialog and page display mode.
198 */
199 property Component dialogDelegate: Delegates.RoundedItemDelegate {
200 implicitWidth: ListView.view ? ListView.view.width : Kirigami.Units.gridUnit * 16
201 text: controlRoot.textRole ? (Array.isArray(controlRoot.model) ? modelData[controlRoot.textRole] : model[controlRoot.textRole]) : modelData
202 checked: controlRoot.currentIndex === index
203
204 Layout.topMargin: index == 0 ? Math.round(Kirigami.Units.smallSpacing / 2) : 0
205
206 onClicked: {
207 controlRoot.currentIndex = index;
208 controlRoot.activated(index);
209 controlRoot.closeDialog();
210 }
211 }
212
213 /**
214 * @brief Closes the dialog or layer.
215 *
216 * This function can be used when reimplementing the ::page or ::dialog.
217 */
218 function closeDialog() {
219 if (_selectionPageItem) {
220 _selectionPageItem.closeDialog();
221 _selectionPageItem = null;
222 }
223
224 if (dialog) {
225 dialog.close();
226 }
227 }
228
229 property var _selectionPageItem: null
230 property real __indicatorMargin: controlRoot.indicator && controlRoot.indicator.visible && controlRoot.indicator.width > 0 ? controlRoot.spacing + indicator.width + controlRoot.spacing : 0
231
232 leftPadding: horizontalPadding + (!controlRoot.mirrored ? 0 : __indicatorMargin)
233 rightPadding: horizontalPadding + (controlRoot.mirrored ? 0 : __indicatorMargin)
234
235
236 // use connections instead of onClicked on root, so that users can supply
237 // their own behaviour.
238 Connections {
239 target: controlRoot
240 function onClicked() {
241 if (controlRoot.displayMode === FormComboBoxDelegate.Dialog) {
242 controlRoot.dialog.open();
243 } else if (controlRoot.displayMode === FormComboBoxDelegate.Page) {
244 controlRoot._selectionPageItem = controlRoot.ApplicationWindow.window.pageStack.pushDialogLayer(page)
245 } else {
246 combobox.popup.open();
247 combobox.forceActiveFocus(Qt.PopupFocusReason);
248 }
249 }
250 }
251
252 /**
253 * @brief The dialog component used for the combobox.
254 *
255 * This property allows to override the internal dialog
256 * with a custom component.
257 */
258 property var dialog: Kirigami.Dialog {
259 id: dialog
260 showCloseButton: false
261 title: controlRoot.text
262 preferredWidth: Kirigami.Units.gridUnit * 16
263 parent: QQC2.Overlay.overlay
264
265 ColumnLayout {
266 spacing: 0
267
268 Repeater {
269 model: controlRoot.model
270 delegate: controlRoot.dialogDelegate
271 }
272
273 QQC2.TextField {
274 visible: controlRoot.editable
275 onTextChanged: controlRoot.editText = text;
276 Layout.fillWidth: true
277 }
278 }
279 }
280
281 /**
282 * @brief The page component used for the combobox, if applicable.
283 *
284 * This property allows to override the internal
285 * Kirigami.ScrollablePage with a custom component.
286 */
287 property Component page: Kirigami.ScrollablePage {
288 title: controlRoot.text
289
290 ListView {
291 spacing: 0
292 model: controlRoot.model
293 delegate: controlRoot.dialogDelegate
294
295 footer: QQC2.TextField {
296 visible: controlRoot.editable
297 onTextChanged: controlRoot.editText = text;
298 Layout.fillWidth: true
299 }
300 }
301 }
302
303 function indexOfValue(value) {
304 return combobox.indexOfValue(value);
305 }
306
307 focusPolicy: Qt.StrongFocus
308 Accessible.description: description
309 Accessible.onPressAction: controlRoot.clicked()
310
311 contentItem: ColumnLayout {
312 spacing: Kirigami.Units.smallSpacing
313
314 RowLayout {
315 Layout.fillWidth: true
316 spacing: Kirigami.Units.smallSpacing
317
318 QQC2.Label {
319 Layout.fillWidth: true
320 text: controlRoot.text
321 elide: Text.ElideRight
322 color: controlRoot.enabled ? Kirigami.Theme.textColor : Kirigami.Theme.disabledTextColor
323 wrapMode: Text.Wrap
324 maximumLineCount: 2
325 Accessible.ignored: true
326 }
327
328 QQC2.Label {
329 Layout.alignment: Qt.AlignRight
330 Layout.rightMargin: Kirigami.Units.smallSpacing
331 color: Kirigami.Theme.disabledTextColor
332 text: controlRoot.displayText
333 visible: controlRoot.displayMode === FormComboBoxDelegate.Dialog || controlRoot.displayMode === FormComboBoxDelegate.Page
334 }
335
336 FormArrow {
337 Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
338 direction: Qt.DownArrow
339 visible: controlRoot.displayMode === FormComboBoxDelegate.Dialog || controlRoot.displayMode === FormComboBoxDelegate.Page
340 }
341 }
342
343 QQC2.ComboBox {
344 id: combobox
345 focusPolicy: Qt.NoFocus // provided by parent
346 model: controlRoot.model
347 visible: controlRoot.displayMode == FormComboBoxDelegate.ComboBox
348 delegate: controlRoot.comboBoxDelegate
349 currentIndex: controlRoot.currentIndex
350 onActivated: index => controlRoot.activated(index)
351 onAccepted: controlRoot.accepted()
352 popup.contentItem.clip: true
353 Layout.fillWidth: true
354 }
355
356 QQC2.Label {
357 visible: controlRoot.description !== ""
358 Layout.fillWidth: true
359 text: controlRoot.description
360 color: Kirigami.Theme.disabledTextColor
361 wrapMode: Text.Wrap
362 Accessible.ignored: true
363 }
364 }
365}
366
An arrow UI component used in Form delegates.
Definition FormArrow.qml:22
A Form delegate that corresponds to a combobox.
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 Jul 26 2024 11:54:39 by doxygen 1.11.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.