1// Copyright (C) 2017 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qquicktextfield_p.h"
5#include "qquicktextfield_p_p.h"
6#include "qquickcontrol_p.h"
7#include "qquickcontrol_p_p.h"
8#include "qquickdeferredexecute_p_p.h"
9
10#include <QtQuick/private/qquickitem_p.h>
11#include <QtQuick/private/qquicktextinput_p.h>
12#include <QtQuick/private/qquickclipnode_p.h>
13
14#if QT_CONFIG(accessibility)
15#include <QtQuick/private/qquickaccessibleattached_p.h>
16#endif
17
18QT_BEGIN_NAMESPACE
19
20using namespace Qt::StringLiterals;
21
22/*!
23 \qmltype TextField
24 \inherits TextInput
25//! \instantiates QQuickTextField
26 \inqmlmodule QtQuick.Controls
27 \since 5.7
28 \ingroup qtquickcontrols-input
29 \brief Single-line text input field.
30
31 TextField is a single line text editor. TextField extends TextInput with
32 a \l {placeholderText}{placeholder text} functionality, and adds decoration.
33
34 \table
35 \row \li \image qtquickcontrols-textfield-normal.png
36 \li A text field in its normal state.
37 \row \li \image qtquickcontrols-textfield-focused.png
38 \li A text field that has active focus.
39 \row \li \image qtquickcontrols-textfield-disabled.png
40 \li A text field that is disabled.
41 \endtable
42
43 \code
44 TextField {
45 placeholderText: qsTr("Enter name")
46 }
47 \endcode
48
49 \sa TextArea, {Customizing TextField}, {Input Controls}
50*/
51
52/*!
53 \qmlsignal QtQuick.Controls::TextField::pressAndHold(MouseEvent event)
54
55 This signal is emitted when there is a long press (the delay depends on the platform plugin).
56 The \a event parameter provides information about the press, including the x and y
57 coordinates of the press, and which button is pressed.
58
59 \sa pressed, released
60*/
61
62/*!
63 \qmlsignal QtQuick.Controls::TextField::pressed(MouseEvent event)
64 \since QtQuick.Controls 2.1 (Qt 5.8)
65
66 This signal is emitted when the text field is pressed by the user.
67 The \a event parameter provides information about the press,
68 including the x and y coordinates of the press, and which button
69 is pressed.
70
71 \sa released, pressAndHold
72*/
73
74/*!
75 \qmlsignal QtQuick.Controls::TextField::released(MouseEvent event)
76 \since QtQuick.Controls 2.1 (Qt 5.8)
77
78 This signal is emitted when the text field is released by the user.
79 The \a event parameter provides information about the release,
80 including the x and y coordinates of the press, and which button
81 is pressed.
82
83 \sa pressed, pressAndHold
84*/
85
86QQuickTextFieldPrivate::QQuickTextFieldPrivate()
87{
88#if QT_CONFIG(accessibility)
89 QAccessible::installActivationObserver(this);
90#endif
91}
92
93QQuickTextFieldPrivate::~QQuickTextFieldPrivate()
94{
95#if QT_CONFIG(accessibility)
96 QAccessible::removeActivationObserver(this);
97#endif
98}
99
100void QQuickTextFieldPrivate::setTopInset(qreal value, bool reset)
101{
102 Q_Q(QQuickTextField);
103 const QMarginsF oldInset = getInset();
104 extra.value().topInset = value;
105 extra.value().hasTopInset = !reset;
106 if (!qFuzzyCompare(p1: oldInset.top(), p2: value)) {
107 emit q->topInsetChanged();
108 q->insetChange(newInset: getInset(), oldInset);
109 }
110}
111
112void QQuickTextFieldPrivate::setLeftInset(qreal value, bool reset)
113{
114 Q_Q(QQuickTextField);
115 const QMarginsF oldInset = getInset();
116 extra.value().leftInset = value;
117 extra.value().hasLeftInset = !reset;
118 if (!qFuzzyCompare(p1: oldInset.left(), p2: value)) {
119 emit q->leftInsetChanged();
120 q->insetChange(newInset: getInset(), oldInset);
121 }
122}
123
124void QQuickTextFieldPrivate::setRightInset(qreal value, bool reset)
125{
126 Q_Q(QQuickTextField);
127 const QMarginsF oldInset = getInset();
128 extra.value().rightInset = value;
129 extra.value().hasRightInset = !reset;
130 if (!qFuzzyCompare(p1: oldInset.right(), p2: value)) {
131 emit q->rightInsetChanged();
132 q->insetChange(newInset: getInset(), oldInset);
133 }
134}
135
136void QQuickTextFieldPrivate::setBottomInset(qreal value, bool reset)
137{
138 Q_Q(QQuickTextField);
139 const QMarginsF oldInset = getInset();
140 extra.value().bottomInset = value;
141 extra.value().hasBottomInset = !reset;
142 if (!qFuzzyCompare(p1: oldInset.bottom(), p2: value)) {
143 emit q->bottomInsetChanged();
144 q->insetChange(newInset: getInset(), oldInset);
145 }
146}
147
148void QQuickTextFieldPrivate::resizeBackground()
149{
150 if (!background)
151 return;
152
153 resizingBackground = true;
154
155 QQuickItemPrivate *p = QQuickItemPrivate::get(item: background);
156 if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(d: background->x()))
157 || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) {
158 const bool wasWidthValid = p->widthValid();
159 background->setX(getLeftInset());
160 background->setWidth(width - getLeftInset() - getRightInset());
161 // If the user hadn't previously set the width, that shouldn't change when we set it for them.
162 if (!wasWidthValid)
163 p->widthValidFlag = false;
164 }
165 if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(d: background->y()))
166 || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) {
167 const bool wasHeightValid = p->heightValid();
168 background->setY(getTopInset());
169 background->setHeight(height - getTopInset() - getBottomInset());
170 if (!wasHeightValid)
171 p->heightValidFlag = false;
172 }
173
174 resizingBackground = false;
175}
176
177/*!
178 \internal
179
180 Determine which font is implicitly imposed on this control by its ancestors
181 and QGuiApplication::font, resolve this against its own font (attributes from
182 the implicit font are copied over). Then propagate this font to this
183 control's children.
184*/
185void QQuickTextFieldPrivate::resolveFont()
186{
187 Q_Q(QQuickTextField);
188 inheritFont(font: QQuickControlPrivate::parentFont(item: q));
189}
190
191void QQuickTextFieldPrivate::inheritFont(const QFont &font)
192{
193 QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font;
194 parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask());
195
196 const QFont defaultFont = QQuickTheme::font(scope: QQuickTheme::TextField);
197 QFont resolvedFont = parentFont.resolve(defaultFont);
198
199 setFont_helper(resolvedFont);
200}
201
202/*!
203 \internal
204
205 Assign \a font to this control, and propagate it to all children.
206*/
207void QQuickTextFieldPrivate::updateFont(const QFont &font)
208{
209 Q_Q(QQuickTextField);
210 QFont oldFont = sourceFont;
211 q->QQuickTextInput::setFont(font);
212
213 QQuickControlPrivate::updateFontRecur(item: q, font);
214
215 if (oldFont != font)
216 emit q->fontChanged();
217}
218
219#if QT_CONFIG(quicktemplates2_hover)
220void QQuickTextFieldPrivate::updateHoverEnabled(bool enabled, bool xplicit)
221{
222 Q_Q(QQuickTextField);
223 if (!xplicit && explicitHoverEnabled)
224 return;
225
226 bool wasEnabled = q->isHoverEnabled();
227 explicitHoverEnabled = xplicit;
228 if (wasEnabled != enabled) {
229 q->setAcceptHoverEvents(enabled);
230 QQuickControlPrivate::updateHoverEnabledRecur(item: q, enabled);
231 emit q->hoverEnabledChanged();
232 }
233}
234#endif
235
236qreal QQuickTextFieldPrivate::getImplicitWidth() const
237{
238 return QQuickItemPrivate::getImplicitWidth();
239}
240
241qreal QQuickTextFieldPrivate::getImplicitHeight() const
242{
243 return QQuickItemPrivate::getImplicitHeight();
244}
245
246void QQuickTextFieldPrivate::implicitWidthChanged()
247{
248 Q_Q(QQuickTextField);
249 QQuickItemPrivate::implicitWidthChanged();
250 emit q->implicitWidthChanged3();
251}
252
253void QQuickTextFieldPrivate::implicitHeightChanged()
254{
255 Q_Q(QQuickTextField);
256 QQuickItemPrivate::implicitHeightChanged();
257 emit q->implicitHeightChanged3();
258}
259
260void QQuickTextFieldPrivate::readOnlyChanged(bool isReadOnly)
261{
262 Q_UNUSED(isReadOnly);
263#if QT_CONFIG(accessibility)
264 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: q_func()))
265 accessibleAttached->set_readOnly(isReadOnly);
266#endif
267#if QT_CONFIG(cursor)
268 q_func()->setCursor(isReadOnly && !selectByMouse ? Qt::ArrowCursor : Qt::IBeamCursor);
269#endif
270}
271
272void QQuickTextFieldPrivate::echoModeChanged(QQuickTextField::EchoMode echoMode)
273{
274#if QT_CONFIG(accessibility)
275 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: q_func()))
276 accessibleAttached->set_passwordEdit((echoMode == QQuickTextField::Password || echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false);
277#else
278 Q_UNUSED(echoMode);
279#endif
280}
281
282#if QT_CONFIG(accessibility)
283void QQuickTextFieldPrivate::accessibilityActiveChanged(bool active)
284{
285 if (!active)
286 return;
287
288 Q_Q(QQuickTextField);
289 QQuickAccessibleAttached *accessibleAttached = qobject_cast<QQuickAccessibleAttached *>(object: qmlAttachedPropertiesObject<QQuickAccessibleAttached>(obj: q, create: true));
290 Q_ASSERT(accessibleAttached);
291 accessibleAttached->setRole(effectiveAccessibleRole());
292 accessibleAttached->set_readOnly(m_readOnly);
293 accessibleAttached->set_passwordEdit((m_echoMode == QQuickTextField::Password || m_echoMode == QQuickTextField::PasswordEchoOnEdit) ? true : false);
294 accessibleAttached->setDescription(placeholder);
295}
296
297QAccessible::Role QQuickTextFieldPrivate::accessibleRole() const
298{
299 return QAccessible::EditableText;
300}
301#endif
302
303void QQuickTextFieldPrivate::cancelBackground()
304{
305 Q_Q(QQuickTextField);
306 quickCancelDeferred(object: q, property: backgroundName());
307}
308
309void QQuickTextFieldPrivate::executeBackground(bool complete)
310{
311 Q_Q(QQuickTextField);
312 if (background.wasExecuted())
313 return;
314
315 if (!background || complete)
316 quickBeginDeferred(object: q, property: backgroundName(), delegate&: background);
317 if (complete)
318 quickCompleteDeferred(object: q, property: backgroundName(), delegate&: background);
319}
320
321void QQuickTextFieldPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff)
322{
323 Q_UNUSED(diff);
324 if (resizingBackground || item != background || !change.sizeChange())
325 return;
326
327 QQuickItemPrivate *p = QQuickItemPrivate::get(item);
328 // QTBUG-71875: only allocate the extra data if we have to.
329 // resizeBackground() relies on the value of extra.isAllocated()
330 // as part of its checks to see whether it should resize the background or not.
331 if (p->widthValid() || extra.isAllocated())
332 extra.value().hasBackgroundWidth = p->widthValid();
333 if (p->heightValid() || extra.isAllocated())
334 extra.value().hasBackgroundHeight = p->heightValid();
335 resizeBackground();
336}
337
338void QQuickTextFieldPrivate::itemImplicitWidthChanged(QQuickItem *item)
339{
340 Q_Q(QQuickTextField);
341 if (item == background)
342 emit q->implicitBackgroundWidthChanged();
343}
344
345void QQuickTextFieldPrivate::itemImplicitHeightChanged(QQuickItem *item)
346{
347 Q_Q(QQuickTextField);
348 if (item == background)
349 emit q->implicitBackgroundHeightChanged();
350}
351
352void QQuickTextFieldPrivate::itemDestroyed(QQuickItem *item)
353{
354 Q_Q(QQuickTextField);
355 if (item == background) {
356 background = nullptr;
357 emit q->implicitBackgroundWidthChanged();
358 emit q->implicitBackgroundHeightChanged();
359 }
360}
361
362QPalette QQuickTextFieldPrivate::defaultPalette() const
363{
364 return QQuickTheme::palette(scope: QQuickTheme::TextField);
365}
366
367QQuickTextField::QQuickTextField(QQuickItem *parent)
368 : QQuickTextInput(*(new QQuickTextFieldPrivate), parent)
369{
370 Q_D(QQuickTextField);
371 d->pressHandler.control = this;
372 d->setImplicitResizeEnabled(false);
373 setAcceptedMouseButtons(Qt::AllButtons);
374 setActiveFocusOnTab(true);
375#if QT_CONFIG(cursor)
376 setCursor(Qt::IBeamCursor);
377#endif
378 QObjectPrivate::connect(sender: this, signal: &QQuickTextInput::readOnlyChanged, receiverPrivate: d, slot: &QQuickTextFieldPrivate::readOnlyChanged);
379 QObjectPrivate::connect(sender: this, signal: &QQuickTextInput::echoModeChanged, receiverPrivate: d, slot: &QQuickTextFieldPrivate::echoModeChanged);
380#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
381 if (qEnvironmentVariable(varName: "QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR") == u"old"_s)
382 QQuickTextInput::setOldSelectionDefault();
383#endif
384}
385
386QQuickTextField::~QQuickTextField()
387{
388 Q_D(QQuickTextField);
389 QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
390}
391
392QFont QQuickTextField::font() const
393{
394 Q_D(const QQuickTextField);
395 QFont font = QQuickTextInput::font();
396 // The resolve mask should inherit from the requestedFont
397 font.setResolveMask(d->extra.value().requestedFont.resolveMask());
398 return font;
399}
400
401void QQuickTextField::setFont(const QFont &font)
402{
403 Q_D(QQuickTextField);
404 if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font)
405 return;
406
407 d->extra.value().requestedFont = font;
408 d->resolveFont();
409}
410
411/*!
412 \qmlproperty Item QtQuick.Controls::TextField::background
413
414 This property holds the background item.
415
416 \input qquickcontrol-background.qdocinc notes
417
418 \sa {Customizing TextField}
419*/
420QQuickItem *QQuickTextField::background() const
421{
422 QQuickTextFieldPrivate *d = const_cast<QQuickTextFieldPrivate *>(d_func());
423 if (!d->background)
424 d->executeBackground();
425 return d->background;
426}
427
428void QQuickTextField::setBackground(QQuickItem *background)
429{
430 Q_D(QQuickTextField);
431 if (d->background == background)
432 return;
433
434 QQuickControlPrivate::warnIfCustomizationNotSupported(control: this, item: background, QStringLiteral("background"));
435
436 if (!d->background.isExecuting())
437 d->cancelBackground();
438
439 const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
440 const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();
441
442 if (d->extra.isAllocated()) {
443 d->extra.value().hasBackgroundWidth = false;
444 d->extra.value().hasBackgroundHeight = false;
445 }
446
447 QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
448 QQuickControlPrivate::hideOldItem(item: d->background);
449 d->background = background;
450
451 if (background) {
452 background->setParentItem(this);
453 if (qFuzzyIsNull(d: background->z()))
454 background->setZ(-1);
455 QQuickItemPrivate *p = QQuickItemPrivate::get(item: background);
456 if (p->widthValid() || p->heightValid()) {
457 d->extra.value().hasBackgroundWidth = p->widthValid();
458 d->extra.value().hasBackgroundHeight = p->heightValid();
459 }
460 if (isComponentComplete())
461 d->resizeBackground();
462 QQuickControlPrivate::addImplicitSizeListener(item: background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
463 }
464
465 if (!qFuzzyCompare(p1: oldImplicitBackgroundWidth, p2: implicitBackgroundWidth()))
466 emit implicitBackgroundWidthChanged();
467 if (!qFuzzyCompare(p1: oldImplicitBackgroundHeight, p2: implicitBackgroundHeight()))
468 emit implicitBackgroundHeightChanged();
469 if (!d->background.isExecuting())
470 emit backgroundChanged();
471}
472
473/*!
474 \qmlproperty string QtQuick.Controls::TextField::placeholderText
475
476 This property holds the hint that is displayed in the TextField before the user
477 enters text.
478*/
479QString QQuickTextField::placeholderText() const
480{
481 Q_D(const QQuickTextField);
482 return d->placeholder;
483}
484
485void QQuickTextField::setPlaceholderText(const QString &text)
486{
487 Q_D(QQuickTextField);
488 if (d->placeholder == text)
489 return;
490
491 d->placeholder = text;
492#if QT_CONFIG(accessibility)
493 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: this))
494 accessibleAttached->setDescription(text);
495#endif
496 emit placeholderTextChanged();
497}
498
499/*!
500 \qmlproperty color QtQuick.Controls::TextField::placeholderTextColor
501 \since QtQuick.Controls 2.5 (Qt 5.12)
502
503 This property holds the color of placeholderText.
504
505 \sa placeholderText
506*/
507QColor QQuickTextField::placeholderTextColor() const
508{
509 Q_D(const QQuickTextField);
510 return d->placeholderColor;
511}
512
513void QQuickTextField::setPlaceholderTextColor(const QColor &color)
514{
515 Q_D(QQuickTextField);
516 if (d->placeholderColor == color)
517 return;
518
519 d->placeholderColor = color;
520 emit placeholderTextColorChanged();
521}
522
523/*!
524 \qmlproperty enumeration QtQuick.Controls::TextField::focusReason
525
526 \include qquickcontrol-focusreason.qdocinc
527*/
528Qt::FocusReason QQuickTextField::focusReason() const
529{
530 Q_D(const QQuickTextField);
531 return d->focusReason;
532}
533
534void QQuickTextField::setFocusReason(Qt::FocusReason reason)
535{
536 Q_D(QQuickTextField);
537 if (d->focusReason == reason)
538 return;
539
540 d->focusReason = reason;
541 emit focusReasonChanged();
542}
543
544/*!
545 \since QtQuick.Controls 2.1 (Qt 5.8)
546 \qmlproperty bool QtQuick.Controls::TextField::hovered
547 \readonly
548
549 This property holds whether the text field is hovered.
550
551 \sa hoverEnabled
552*/
553bool QQuickTextField::isHovered() const
554{
555#if QT_CONFIG(quicktemplates2_hover)
556 Q_D(const QQuickTextField);
557 return d->hovered;
558#else
559 return false;
560#endif
561}
562
563void QQuickTextField::setHovered(bool hovered)
564{
565#if QT_CONFIG(quicktemplates2_hover)
566 Q_D(QQuickTextField);
567 if (hovered == d->hovered)
568 return;
569
570 d->hovered = hovered;
571 emit hoveredChanged();
572#else
573 Q_UNUSED(hovered);
574#endif
575}
576
577/*!
578 \since QtQuick.Controls 2.1 (Qt 5.8)
579 \qmlproperty bool QtQuick.Controls::TextField::hoverEnabled
580
581 This property determines whether the text field accepts hover events. The default value is \c false.
582
583 \sa hovered
584*/
585bool QQuickTextField::isHoverEnabled() const
586{
587#if QT_CONFIG(quicktemplates2_hover)
588 Q_D(const QQuickTextField);
589 return d->hoverEnabled;
590#else
591 return false;
592#endif
593}
594
595void QQuickTextField::setHoverEnabled(bool enabled)
596{
597#if QT_CONFIG(quicktemplates2_hover)
598 Q_D(QQuickTextField);
599 if (d->explicitHoverEnabled && enabled == d->hoverEnabled)
600 return;
601
602 d->updateHoverEnabled(enabled, xplicit: true); // explicit=true
603#else
604 Q_UNUSED(enabled);
605#endif
606}
607
608void QQuickTextField::resetHoverEnabled()
609{
610#if QT_CONFIG(quicktemplates2_hover)
611 Q_D(QQuickTextField);
612 if (!d->explicitHoverEnabled)
613 return;
614
615 d->explicitHoverEnabled = false;
616 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
617#endif
618}
619
620void QQuickTextField::classBegin()
621{
622 Q_D(QQuickTextField);
623 QQuickTextInput::classBegin();
624 d->resolveFont();
625}
626
627/*!
628 \since QtQuick.Controls 2.5 (Qt 5.12)
629 \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundWidth
630 \readonly
631
632 This property holds the implicit background width.
633
634 The value is equal to \c {background ? background.implicitWidth : 0}.
635
636 \sa implicitBackgroundHeight
637*/
638qreal QQuickTextField::implicitBackgroundWidth() const
639{
640 Q_D(const QQuickTextField);
641 if (!d->background)
642 return 0;
643 return d->background->implicitWidth();
644}
645
646/*!
647 \since QtQuick.Controls 2.5 (Qt 5.12)
648 \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundHeight
649 \readonly
650
651 This property holds the implicit background height.
652
653 The value is equal to \c {background ? background.implicitHeight : 0}.
654
655 \sa implicitBackgroundWidth
656*/
657qreal QQuickTextField::implicitBackgroundHeight() const
658{
659 Q_D(const QQuickTextField);
660 if (!d->background)
661 return 0;
662 return d->background->implicitHeight();
663}
664
665/*!
666 \since QtQuick.Controls 2.5 (Qt 5.12)
667 \qmlproperty real QtQuick.Controls::TextField::topInset
668
669 This property holds the top inset for the background.
670
671 \sa {Control Layout}, bottomInset
672*/
673qreal QQuickTextField::topInset() const
674{
675 Q_D(const QQuickTextField);
676 return d->getTopInset();
677}
678
679void QQuickTextField::setTopInset(qreal inset)
680{
681 Q_D(QQuickTextField);
682 d->setTopInset(value: inset);
683}
684
685void QQuickTextField::resetTopInset()
686{
687 Q_D(QQuickTextField);
688 d->setTopInset(value: 0, reset: true);
689}
690
691/*!
692 \since QtQuick.Controls 2.5 (Qt 5.12)
693 \qmlproperty real QtQuick.Controls::TextField::leftInset
694
695 This property holds the left inset for the background.
696
697 \sa {Control Layout}, rightInset
698*/
699qreal QQuickTextField::leftInset() const
700{
701 Q_D(const QQuickTextField);
702 return d->getLeftInset();
703}
704
705void QQuickTextField::setLeftInset(qreal inset)
706{
707 Q_D(QQuickTextField);
708 d->setLeftInset(value: inset);
709}
710
711void QQuickTextField::resetLeftInset()
712{
713 Q_D(QQuickTextField);
714 d->setLeftInset(value: 0, reset: true);
715}
716
717/*!
718 \since QtQuick.Controls 2.5 (Qt 5.12)
719 \qmlproperty real QtQuick.Controls::TextField::rightInset
720
721 This property holds the right inset for the background.
722
723 \sa {Control Layout}, leftInset
724*/
725qreal QQuickTextField::rightInset() const
726{
727 Q_D(const QQuickTextField);
728 return d->getRightInset();
729}
730
731void QQuickTextField::setRightInset(qreal inset)
732{
733 Q_D(QQuickTextField);
734 d->setRightInset(value: inset);
735}
736
737void QQuickTextField::resetRightInset()
738{
739 Q_D(QQuickTextField);
740 d->setRightInset(value: 0, reset: true);
741}
742
743/*!
744 \since QtQuick.Controls 2.5 (Qt 5.12)
745 \qmlproperty real QtQuick.Controls::TextField::bottomInset
746
747 This property holds the bottom inset for the background.
748
749 \sa {Control Layout}, topInset
750*/
751qreal QQuickTextField::bottomInset() const
752{
753 Q_D(const QQuickTextField);
754 return d->getBottomInset();
755}
756
757void QQuickTextField::setBottomInset(qreal inset)
758{
759 Q_D(QQuickTextField);
760 d->setBottomInset(value: inset);
761}
762
763void QQuickTextField::resetBottomInset()
764{
765 Q_D(QQuickTextField);
766 d->setBottomInset(value: 0, reset: true);
767}
768
769void QQuickTextField::componentComplete()
770{
771 Q_D(QQuickTextField);
772 d->executeBackground(complete: true);
773 QQuickTextInput::componentComplete();
774 d->resizeBackground();
775#if QT_CONFIG(quicktemplates2_hover)
776 if (!d->explicitHoverEnabled)
777 setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(item: d->parentItem));
778#endif
779#if QT_CONFIG(accessibility)
780 if (QAccessible::isActive())
781 d->accessibilityActiveChanged(active: true);
782#endif
783}
784
785void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
786{
787 Q_D(QQuickTextField);
788 QQuickTextInput::itemChange(change, value);
789 switch (change) {
790 case ItemEnabledHasChanged:
791 break;
792 case ItemSceneChange:
793 case ItemParentHasChanged:
794 if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
795 d->resolveFont();
796#if QT_CONFIG(quicktemplates2_hover)
797 if (!d->explicitHoverEnabled)
798 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
799#endif
800 }
801 break;
802 default:
803 break;
804 }
805}
806
807void QQuickTextField::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
808{
809 Q_D(QQuickTextField);
810 QQuickTextInput::geometryChange(newGeometry, oldGeometry);
811 d->resizeBackground();
812}
813
814void QQuickTextField::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
815{
816 Q_D(QQuickTextField);
817 Q_UNUSED(newInset);
818 Q_UNUSED(oldInset);
819 d->resizeBackground();
820}
821QSGNode *QQuickTextField::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
822{
823 QQuickDefaultClipNode *clipNode = static_cast<QQuickDefaultClipNode *>(oldNode);
824 if (!clipNode)
825 clipNode = new QQuickDefaultClipNode(QRectF());
826
827 clipNode->setRect(clipRect().adjusted(xp1: leftPadding(), yp1: topPadding(), xp2: -rightPadding(), yp2: -bottomPadding()));
828 clipNode->update();
829
830 QSGNode *textNode = QQuickTextInput::updatePaintNode(oldNode: clipNode->firstChild(), data);
831 if (!textNode->parent())
832 clipNode->appendChildNode(node: textNode);
833
834 return clipNode;
835}
836
837void QQuickTextField::focusInEvent(QFocusEvent *event)
838{
839 QQuickTextInput::focusInEvent(event);
840 setFocusReason(event->reason());
841}
842
843void QQuickTextField::focusOutEvent(QFocusEvent *event)
844{
845 QQuickTextInput::focusOutEvent(event);
846 setFocusReason(event->reason());
847}
848
849#if QT_CONFIG(quicktemplates2_hover)
850void QQuickTextField::hoverEnterEvent(QHoverEvent *event)
851{
852 Q_D(QQuickTextField);
853 QQuickTextInput::hoverEnterEvent(event);
854 setHovered(d->hoverEnabled);
855 event->ignore();
856}
857
858void QQuickTextField::hoverLeaveEvent(QHoverEvent *event)
859{
860 QQuickTextInput::hoverLeaveEvent(event);
861 setHovered(false);
862 event->ignore();
863}
864#endif
865
866void QQuickTextField::mousePressEvent(QMouseEvent *event)
867{
868 Q_D(QQuickTextField);
869 d->pressHandler.mousePressEvent(event);
870 if (d->pressHandler.isActive()) {
871 if (d->pressHandler.delayedMousePressEvent) {
872 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
873 d->pressHandler.clearDelayedMouseEvent();
874 }
875 if (event->buttons() != Qt::RightButton)
876 QQuickTextInput::mousePressEvent(event);
877 }
878}
879
880void QQuickTextField::mouseMoveEvent(QMouseEvent *event)
881{
882 Q_D(QQuickTextField);
883 d->pressHandler.mouseMoveEvent(event);
884 if (d->pressHandler.isActive()) {
885 if (d->pressHandler.delayedMousePressEvent) {
886 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
887 d->pressHandler.clearDelayedMouseEvent();
888 }
889 const bool isMouse = QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(ev: event)
890 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
891 || d->selectByTouchDrag
892 #endif
893 ;
894 if (event->buttons() != Qt::RightButton && isMouse)
895 QQuickTextInput::mouseMoveEvent(event);
896 }
897}
898
899void QQuickTextField::mouseReleaseEvent(QMouseEvent *event)
900{
901 Q_D(QQuickTextField);
902 d->pressHandler.mouseReleaseEvent(event);
903 if (d->pressHandler.isActive()) {
904 if (d->pressHandler.delayedMousePressEvent) {
905 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
906 d->pressHandler.clearDelayedMouseEvent();
907 }
908 if (event->buttons() != Qt::RightButton)
909 QQuickTextInput::mouseReleaseEvent(event);
910 }
911}
912
913void QQuickTextField::mouseDoubleClickEvent(QMouseEvent *event)
914{
915 Q_D(QQuickTextField);
916 if (d->pressHandler.delayedMousePressEvent) {
917 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
918 d->pressHandler.clearDelayedMouseEvent();
919 }
920 if (event->buttons() != Qt::RightButton)
921 QQuickTextInput::mouseDoubleClickEvent(event);
922}
923
924void QQuickTextField::timerEvent(QTimerEvent *event)
925{
926 Q_D(QQuickTextField);
927 if (event->timerId() == d->pressHandler.timer.timerId())
928 d->pressHandler.timerEvent(event);
929 else
930 QQuickTextInput::timerEvent(event);
931}
932
933QT_END_NAMESPACE
934
935#include "moc_qquicktextfield_p.cpp"
936

source code of qtdeclarative/src/quicktemplates/qquicktextfield.cpp