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 Qt5Compat.GraphicalEffects
24import QtQuick.Window
25
26import org.mauikit.controls 1.3 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
296 data: Popup
297 {
298 id: _popup
299
300 parent: control
301
302 closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutsideParent
303 modal: false
304
305 y: control.position === ToolBar.Header ? 0 : (0 - (height) + control.height)
306 x: width === control.width ? 0 : 0 - ((width - control.width)/2)
307
308 width: Math.min(Math.max(control.minimumWidth, parent.width), control.Window.window.width - Maui.Style.defaultPadding*2)
309 height: Math.min(control.Window.window.height- Maui.Style.defaultPadding*2, control.minimumHeight)
310
311 anchors.centerIn: undefined
312
313 margins: 0
314 padding: 0
315
316 onClosed:
317 {
318 // _textField.clear()
319 control.closed()
320 }
321
322 onOpened:
323 {
324 _textField.forceActiveFocus()
325 _textField.selectAll()
326 control.opened()
327 }
328
329 Maui.Page
330 {
331 id:_page
332 anchors.fill: parent
333 altHeader: control.position === ToolBar.Footer
334
335 headBar.visible: false
336 headerColumn: TextField
337 {
338 implicitHeight: control.height
339 width: parent.width
340
341 id: _textField
342 text: control.text
343
344 icon.source: control.icon.name
345
346 onTextChanged: control.text = text
347 onAccepted:
348 {
349 control.text = text
350 control.accepted()
351 }
352
353 onCleared:
354 {
355 control.cleared()
356 }
357
358 Keys.enabled: true
359 Keys.forwardTo: control
360 Keys.onEscapePressed: control.close()
361
362 background: Rectangle
363 {
364 color: Maui.Theme.backgroundColor
365
366
367 Maui.Separator
368 {
369 id: _border
370 anchors.left: parent.left
371 anchors.right: parent.right
372 weight: Maui.Separator.Weight.Light
373 opacity: 0.4
374
375 Behavior on color
376 {
377 Maui.ColorTransition{}
378 }
379 }
380
381 states: [ State
382 {
383 when: control.position === ToolBar.Header
384
385 AnchorChanges
386 {
387 target: _border
388 anchors.top: undefined
389 anchors.bottom: parent.bottom
390 }
391 },
392
393 State
394 {
395 when: control.position === ToolBar.Footer
396
397 AnchorChanges
398 {
399 target: _border
400 anchors.top: parent.top
401 anchors.bottom: undefined
402 }
403 }
404 ]
405 }
406 }
407 }
408
409 background: Rectangle
410 {
411 color: Maui.Theme.backgroundColor
412
413 radius: Maui.Style.radiusV
414 layer.enabled: true
415 layer.effect: DropShadow
416 {
417 horizontalOffset: 0
418 verticalOffset: 0
419 radius: 8
420 samples: 16
421 color: "#80000000"
422 transparentBorder: true
423 }
424
425 Behavior on color
426 {
427 Maui.ColorTransition{}
428 }
429 }
430 }
431
432 background: Rectangle
433 {
434 color: control.enabled ? (control.hovered ? Maui.Theme.hoverColor : Maui.Theme.backgroundColor) : "transparent"
435
436 radius: Maui.Style.radiusV
437
438 Behavior on color
439 {
440 Maui.ColorTransition{}
441 }
442 }
443
444 /**
445 * @brief Force the focus to go on the text field box and open up the popup surface.
446 */
447 function forceActiveFocus()
448 {
449 control.open()
450 }
451}
The MauiKit Style preferences singleton object.
Definition style.h:85
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)
KGUIADDONS_EXPORT QWindow * window(QObject *job)
QAction * clear(const QObject *recvr, const char *slot, QObject *parent)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Fri May 17 2024 11:56:16 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.