MauiKit Controls

TextFieldPopup.qml
1/*
2 * Copyright 2023 Camilo Higuita <milo.h@aol.com>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
13 *
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 */
19
20import QtQuick
21import QtQuick.Controls
22import QtQuick.Layouts
23import QtQuick.Effects
24import QtQuick.Window
25
26import org.mauikit.controls as Maui
27
28/**
29 * @inherit QtQuick.Controls.AbstractButton
30 * @brief A TextField control with an attached popup surface.
31 *
32 * @image html Misc/textfieldpopup.gif
33 *
34 * This control groups a text field box and a popup page together - the popup surface can be used to display any data content that might be related to the text field input.
35 *
36 * The text field control is handled by a QQC2 TextField control, which is exposed as `textField`, and the popup surface is hanlded by a QQC2 Popup control, also exposed as an alias `popup`. With those alias you can fine tune the properties of said controls.
37 * @see textField
38 * @see popup
39 *
40 * @code
41 * Maui.Page
42 * {
43 * anchors.fill: parent
44 *
45 * Maui.Controls.showCSD: true
46 * Maui.Theme.colorSet: Maui.Theme.Window
47 *
48 * footBar.middleContent: Maui.TextFieldPopup
49 * {
50 * position: ToolBar.Footer
51 *
52 * Layout.fillWidth: true
53 * Layout.maximumWidth: 500
54 * Layout.alignment: Qt.AlignHCenter
55 *
56 * placeholderText: "Search for Something."
57 *
58 * Maui.Holder
59 * {
60 * anchors.fill: parent
61 *
62 * visible: true
63 * title: "Something Here"
64 * body: "List whatever in here."
65 * emoji: "edit-find"
66 * }
67 * }
68 * }
69 * @endcode
70 * <a href="https://invent.kde.org/maui/mauikit/-/blob/qt6-2/examples/TextFieldPopup.qml">You can find a more complete example at this link.</a>
71 */
72AbstractButton
73{
74 id: control
75
76 Maui.Theme.colorSet: Maui.Theme.Button
77 Maui.Theme.inherit: false
78
79 property int minimumWidth: 400
80 property int minimumHeight: 500
81
82 implicitWidth: 200
83 implicitHeight: _layout.implicitHeight + topPadding + bottomPadding
84
85 hoverEnabled: true
86
87 /**
88 * @brief The children elements are placed inside the popup surface. The elements have to be positioned manually.
89 * The popup surface is open once the text field bar is focused.
90 * @property list<QtObject> TextFieldPopup::content
91 */
92 default property alias content: _page.content
93
94 /**
95 * @brief An alias to the QQC2 control handling the popup surface.
96 * Exposed to access its properties. See Qt documentation on the Popup control.
97 * @property Popup TextFieldPopup::popup
98 */
99 readonly property alias popup: _popup
100
101 /**
102 * @brief An alias to the TextField control handling the text field box.
103 * Exposed to access its properties. See Qt documentation on the TextField control.
104 * @property TextField TextFieldPopup::popup
105 */
106 readonly property alias textField : _textField
107
108 /**
109 * @brief Whether the popup surface is currently visible
110 * @property bool TextFieldPopup::popupVisible
111 */
112 readonly property alias popupVisible: _popup.visible
113
114 /**
115 * @brief The Popup close policy.
116 * by default this is set to ` Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent`
117 * @property enum TextFieldPopup::closePolicy
118 */
119 property alias closePolicy: _popup.closePolicy
120
121 /**
122 * @brief The position of the control. This will make the popup go in either of the picked position: top or bottom.
123 * By default this is set to `ToolBar.Header`
124 * Possible values are:
125 * - ToolBar.Header
126 * - ToolBar.Footer
127 */
128 property int position: ToolBar.Header
129
130 /**
131 * @brief The text to be used as the placeholder in the text field box.
132 * @property string TextFieldPopup::placeholderText
133 */
134 property alias placeholderText: _textField.placeholderText
135
136 /**
137 * @brief The input method hints for the text field.
138 * refer to the Qt TextField documentation for further information.
139 * @property enum TextFieldPopup::inputMethodHints
140 */
141 property alias inputMethodHints: _textField.inputMethodHints
142
143 /**
144 * @brief Whether the text field box gets focused on pressed.
145 * By default this is set to `true`
146 * @property bool TextFieldPopup::activeFocusOnPress
147 */
148 property alias activeFocusOnPress: _textField.activeFocusOnPress
149
150 /**
151 * @brief The wrap mode for the text in the text field box.
152 * By default this is set to `Text.NoWrap`.
153 * @property enum TextFieldPopup::wrapMode
154 */
155 property alias wrapMode :_textField.wrapMode
157 /**
158 * @brief The color fo the text in the text field.
159 * @property color TextFieldPopup::color
160 */
161 property alias color: _textField.color
162
163 /**
164 * @brief The vertical alignment of the text in the text field box.
165 * By default his is set to `Qt.AlignVCenter`
166 * @property enum TextFieldPopup::verticalAlignment
167 */
168 property alias verticalAlignment: _textField.verticalAlignment
169
170 onClicked:
171 {
172 _popup.open()
173 }
175 text: _textField.text
176 icon.name: "edit-find"
177
178 Keys.onEscapePressed: control.close()
179
180 /**
181 * @brief Emitted when the text entered has been accepted, either by pressing Enter, or manually accepted.
182 */
183 signal accepted()
184
185 /**
186 * @brief Emitted when the text in the text field box has been cleared using the clear button or clear action.
187 */
188 signal cleared()
189
190 /**
191 * @brief Emitted when the popup surface has been activated and is visible.
192 */
193 signal opened()
194
195 /**
196 * @brief Emitted when the popup surfaced has been dismissed.
197 */
198 signal closed()
199
200 /**
201 * @brief Forces to open the popup surface.
202 */
203 function open()
204 {
205 _popup.open()
206 }
207
208 /**
209 * @brief Forces to close the popup surface.
210 */
211 function close()
212 {
213 _popup.close()
214 }
215
216 /**
217 * @brief Forces to clear the text in the text field box.
218 */
219 function clear()
220 {
221 _textField.clear()
222 }
223
224 padding: Maui.Style.defaultPadding
225 spacing: Maui.Style.space.small
226
227 contentItem: Item
228 {
229 RowLayout
230 {
231 id: _layout
232 anchors.fill: parent
233 spacing: control.spacing
234
235 Maui.Icon
236 {
237 visible: source ? true : false
238 source: control.icon.name
239 implicitHeight: visible ? 16 : 0
240 implicitWidth: height
241 color: control.color
242 }
243
244 Item
245 {
246 Layout.fillWidth: true
247 visible: !placeholder.visible
248 }
249
250 Label
251 {
252 id: placeholder
253 Layout.fillWidth: true
254 text: control.text.length > 0 ? control.text : control.placeholderText
255 font: control.font
256 color: control.color
257 verticalAlignment: control.verticalAlignment
258 elide: Text.ElideRight
259 wrapMode: Text.NoWrap
260
261 opacity: control.text.length > 0 ? 1 : 0.5
262
263 Behavior on opacity
264 {
265 NumberAnimation
266 {
267 duration: Maui.Style.units.longDuration
268 easing.type: Easing.InOutQuad
269 }
270 }
271 }
272 }
273
274 Loader
275 {
276 asynchronous: true
277 anchors.fill: parent
278 sourceComponent: DropArea
279 {
280 onDropped: (drop) =>
281 {
282 if (drop.hasText)
283 {
284 control.text += drop.text
285
286 }else if(drop.hasUrls)
287 {
288 control.text = drop.urls
289 }
290 }
291 }
292 }
293 }
294
295 data: Maui.Popup
296 {
297 id: _popup
298
299 parent: control
300
301 closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
302 modal: false
303
304 y: control.position === ToolBar.Header ? 0 : (0 - (height) + control.height)
305 x: width === control.width ? 0 : 0 - ((width - control.width)/2)
306
307 width: Math.min(Math.max(control.minimumWidth, parent.width), control.Window.window.width - Maui.Style.defaultPadding*2)
308 height: Math.min(control.Window.window.height- Maui.Style.defaultPadding*2, control.minimumHeight)
309
310 anchors.centerIn: undefined
311
312 margins: 0
313 padding: 0
314
315 onClosed:
316 {
317 // _textField.clear()
318 control.closed()
319 }
320
321 onOpened:
322 {
323 _textField.forceActiveFocus()
324 _textField.selectAll()
325 control.opened()
326 }
327
328 Maui.Page
329 {
330 id:_page
331 anchors.fill: parent
332 altHeader: control.position === ToolBar.Footer
333
334 headBar.visible: false
335 headerColumn: Maui.TextField
336 {
337 implicitHeight: control.height
338 width: parent.width
339
340 id: _textField
341 text: control.text
342
343 icon.source: control.icon.name
344
345 onTextChanged: control.text = text
346 onAccepted:
347 {
348 control.text = text
349 control.accepted()
350 }
351
352 onCleared:
353 {
354 control.cleared()
355 }
356
357 Keys.enabled: true
358 Keys.forwardTo: control
359 Keys.onEscapePressed: control.close()
360
361 background: Rectangle
362 {
363 color: Maui.Theme.backgroundColor
364
365
366 Maui.Separator
367 {
368 id: _border
369 anchors.left: parent.left
370 anchors.right: parent.right
371 weight: Maui.Separator.Weight.Light
372 opacity: 0.4
373
374 Behavior on color
375 {
376 Maui.ColorTransition{}
377 }
378 }
379
380 states: [ State
381 {
382 when: control.position === ToolBar.Header
383
384 AnchorChanges
385 {
386 target: _border
387 anchors.top: undefined
388 anchors.bottom: parent.bottom
389 }
390 },
391
392 State
393 {
394 when: control.position === ToolBar.Footer
395
396 AnchorChanges
397 {
398 target: _border
399 anchors.top: parent.top
400 anchors.bottom: undefined
401 }
402 }
403 ]
404 }
405 }
406 }
407
408 background: Rectangle
409 {
410 color: Maui.Theme.backgroundColor
411
412 radius: Maui.Style.radiusV
413 layer.enabled: GraphicsInfo.api !== GraphicsInfo.Software
414 layer.effect: MultiEffect
415 {
416 autoPaddingEnabled: true
417 shadowEnabled: true
418 shadowColor: "#80000000"
419 }
420
421 Behavior on color
422 {
423 Maui.ColorTransition{}
424 }
425 }
426 }
427
428 background: Rectangle
429 {
430 color: control.enabled ? (control.hovered ? Maui.Theme.hoverColor : Maui.Theme.backgroundColor) : "transparent"
431
432 radius: Maui.Style.radiusV
433
434 Behavior on color
435 {
436 Maui.ColorTransition{}
437 }
438 }
439
440 /**
441 * @brief Force the focus to go on the text field box and open up the popup surface.
442 */
443 function forceActiveFocus()
444 {
445 control.open()
446 }
447}
Popup A global sidebar for the application window that can be collapsed.
Definition Popup.qml:33
The MauiKit Style preferences singleton object.
Definition style.h:86
void opened()
Emitted when the popup surface has been activated and is visible.
void accepted()
Emitted when the text entered has been accepted, either by pressing Enter, or manually accepted.
void cleared()
Emitted when the text in the text field box has been cleared using the clear button or clear action.
void open()
Forces to open the popup surface.
void closed()
Emitted when the popup surfaced has been dismissed.
An alternative to QQC2 ToolBar, with a custom horizontal layout - divided into three main sections - ...
Definition ToolBar.qml:115
KIOWIDGETS_EXPORT DropJob * drop(const QDropEvent *dropEvent, const QUrl &destUrl, DropJobFlags dropjobFlags, JobFlags flags=DefaultFlags)
QWidget * window(QObject *job)
KGuiItem clear()
This file is part of the KDE documentation.
Documentation copyright © 1996-2025 The KDE developers.
Generated on Fri May 2 2025 11:57:11 by doxygen 1.13.2 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.