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//! \nativetype 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
367bool QQuickTextFieldPrivate::setLastFocusChangeReason(Qt::FocusReason reason)
368{
369 Q_Q(QQuickTextField);
370 const auto focusReasonChanged = QQuickItemPrivate::setLastFocusChangeReason(reason);
371 if (focusReasonChanged)
372 emit q->focusReasonChanged();
373
374 return focusReasonChanged;
375}
376
377QQuickTextField::QQuickTextField(QQuickItem *parent)
378 : QQuickTextInput(*(new QQuickTextFieldPrivate), parent)
379{
380 Q_D(QQuickTextField);
381 d->pressHandler.control = this;
382 d->setImplicitResizeEnabled(false);
383 setAcceptedMouseButtons(Qt::AllButtons);
384 setActiveFocusOnTab(true);
385#if QT_CONFIG(cursor)
386 setCursor(Qt::IBeamCursor);
387#endif
388 QObjectPrivate::connect(sender: this, signal: &QQuickTextInput::readOnlyChanged, receiverPrivate: d, slot: &QQuickTextFieldPrivate::readOnlyChanged);
389 QObjectPrivate::connect(sender: this, signal: &QQuickTextInput::echoModeChanged, receiverPrivate: d, slot: &QQuickTextFieldPrivate::echoModeChanged);
390#if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
391 if (qEnvironmentVariable(varName: "QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR") == u"old"_s)
392 QQuickTextInput::setOldSelectionDefault();
393#endif
394}
395
396QQuickTextField::~QQuickTextField()
397{
398 Q_D(QQuickTextField);
399 QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
400}
401
402QFont QQuickTextField::font() const
403{
404 Q_D(const QQuickTextField);
405 QFont font = QQuickTextInput::font();
406 // The resolve mask should inherit from the requestedFont
407 font.setResolveMask(d->extra.value().requestedFont.resolveMask());
408 return font;
409}
410
411void QQuickTextField::setFont(const QFont &font)
412{
413 Q_D(QQuickTextField);
414 if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font)
415 return;
416
417 d->extra.value().requestedFont = font;
418 d->resolveFont();
419}
420
421/*!
422 \qmlproperty Item QtQuick.Controls::TextField::background
423
424 This property holds the background item.
425
426 \input qquickcontrol-background.qdocinc notes
427
428 \sa {Customizing TextField}
429*/
430QQuickItem *QQuickTextField::background() const
431{
432 QQuickTextFieldPrivate *d = const_cast<QQuickTextFieldPrivate *>(d_func());
433 if (!d->background)
434 d->executeBackground();
435 return d->background;
436}
437
438void QQuickTextField::setBackground(QQuickItem *background)
439{
440 Q_D(QQuickTextField);
441 if (d->background == background)
442 return;
443
444 QQuickControlPrivate::warnIfCustomizationNotSupported(control: this, item: background, QStringLiteral("background"));
445
446 if (!d->background.isExecuting())
447 d->cancelBackground();
448
449 const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth();
450 const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight();
451
452 if (d->extra.isAllocated()) {
453 d->extra.value().hasBackgroundWidth = false;
454 d->extra.value().hasBackgroundHeight = false;
455 }
456
457 QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
458 QQuickControlPrivate::hideOldItem(item: d->background);
459 d->background = background;
460
461 if (background) {
462 background->setParentItem(this);
463 if (qFuzzyIsNull(d: background->z()))
464 background->setZ(-1);
465 QQuickItemPrivate *p = QQuickItemPrivate::get(item: background);
466 if (p->widthValid() || p->heightValid()) {
467 d->extra.value().hasBackgroundWidth = p->widthValid();
468 d->extra.value().hasBackgroundHeight = p->heightValid();
469 }
470 if (isComponentComplete())
471 d->resizeBackground();
472 QQuickControlPrivate::addImplicitSizeListener(item: background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry);
473 }
474
475 if (!qFuzzyCompare(p1: oldImplicitBackgroundWidth, p2: implicitBackgroundWidth()))
476 emit implicitBackgroundWidthChanged();
477 if (!qFuzzyCompare(p1: oldImplicitBackgroundHeight, p2: implicitBackgroundHeight()))
478 emit implicitBackgroundHeightChanged();
479 if (!d->background.isExecuting())
480 emit backgroundChanged();
481}
482
483/*!
484 \qmlproperty string QtQuick.Controls::TextField::placeholderText
485
486 This property holds the hint that is displayed in the TextField before the user
487 enters text.
488*/
489QString QQuickTextField::placeholderText() const
490{
491 Q_D(const QQuickTextField);
492 return d->placeholder;
493}
494
495void QQuickTextField::setPlaceholderText(const QString &text)
496{
497 Q_D(QQuickTextField);
498 if (d->placeholder == text)
499 return;
500
501 d->placeholder = text;
502#if QT_CONFIG(accessibility)
503 if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: this))
504 accessibleAttached->setDescription(text);
505#endif
506 emit placeholderTextChanged();
507}
508
509/*!
510 \qmlproperty color QtQuick.Controls::TextField::placeholderTextColor
511 \since QtQuick.Controls 2.5 (Qt 5.12)
512
513 This property holds the color of placeholderText.
514
515 \sa placeholderText
516*/
517QColor QQuickTextField::placeholderTextColor() const
518{
519 Q_D(const QQuickTextField);
520 return d->placeholderColor;
521}
522
523void QQuickTextField::setPlaceholderTextColor(const QColor &color)
524{
525 Q_D(QQuickTextField);
526 if (d->placeholderColor == color)
527 return;
528
529 d->placeholderColor = color;
530 emit placeholderTextColorChanged();
531}
532
533/*!
534 \qmlproperty enumeration QtQuick.Controls::TextField::focusReason
535
536 This property holds the reason of the last focus change.
537
538 \note This property does not indicate whether the item has \l {Item::activeFocus}
539 {active focus}, but the reason why the item either gained or lost focus.
540
541 \value Qt.MouseFocusReason A mouse action occurred.
542 \value Qt.TabFocusReason The Tab key was pressed.
543 \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab.
544 \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive.
545 \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus.
546 \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut
547 \value Qt.MenuBarFocusReason The menu bar took focus.
548 \value Qt.OtherFocusReason Another reason, usually application-specific.
549
550 \note Prefer \l {QtQuick.Controls::Control::focusReason} to this property.
551*/
552Qt::FocusReason QQuickTextField::focusReason() const
553{
554 Q_D(const QQuickTextField);
555 return d->lastFocusChangeReason();
556}
557
558void QQuickTextField::setFocusReason(Qt::FocusReason reason)
559{
560 Q_D(QQuickTextField);
561 d->setLastFocusChangeReason(reason);
562}
563
564/*!
565 \since QtQuick.Controls 2.1 (Qt 5.8)
566 \qmlproperty bool QtQuick.Controls::TextField::hovered
567 \readonly
568
569 This property holds whether the text field is hovered.
570
571 \sa hoverEnabled
572*/
573bool QQuickTextField::isHovered() const
574{
575#if QT_CONFIG(quicktemplates2_hover)
576 Q_D(const QQuickTextField);
577 return d->hovered;
578#else
579 return false;
580#endif
581}
582
583void QQuickTextField::setHovered(bool hovered)
584{
585#if QT_CONFIG(quicktemplates2_hover)
586 Q_D(QQuickTextField);
587 if (hovered == d->hovered)
588 return;
589
590 d->hovered = hovered;
591 emit hoveredChanged();
592#else
593 Q_UNUSED(hovered);
594#endif
595}
596
597/*!
598 \since QtQuick.Controls 2.1 (Qt 5.8)
599 \qmlproperty bool QtQuick.Controls::TextField::hoverEnabled
600
601 This property determines whether the text field accepts hover events. The default value is \c false.
602
603 \sa hovered
604*/
605bool QQuickTextField::isHoverEnabled() const
606{
607#if QT_CONFIG(quicktemplates2_hover)
608 Q_D(const QQuickTextField);
609 return d->hoverEnabled;
610#else
611 return false;
612#endif
613}
614
615void QQuickTextField::setHoverEnabled(bool enabled)
616{
617#if QT_CONFIG(quicktemplates2_hover)
618 Q_D(QQuickTextField);
619 if (d->explicitHoverEnabled && enabled == d->hoverEnabled)
620 return;
621
622 d->updateHoverEnabled(enabled, xplicit: true); // explicit=true
623#else
624 Q_UNUSED(enabled);
625#endif
626}
627
628void QQuickTextField::resetHoverEnabled()
629{
630#if QT_CONFIG(quicktemplates2_hover)
631 Q_D(QQuickTextField);
632 if (!d->explicitHoverEnabled)
633 return;
634
635 d->explicitHoverEnabled = false;
636 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
637#endif
638}
639
640void QQuickTextField::classBegin()
641{
642 Q_D(QQuickTextField);
643 QQuickTextInput::classBegin();
644 d->resolveFont();
645}
646
647/*!
648 \since QtQuick.Controls 2.5 (Qt 5.12)
649 \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundWidth
650 \readonly
651
652 This property holds the implicit background width.
653
654 The value is equal to \c {background ? background.implicitWidth : 0}.
655
656 \sa implicitBackgroundHeight
657*/
658qreal QQuickTextField::implicitBackgroundWidth() const
659{
660 Q_D(const QQuickTextField);
661 if (!d->background)
662 return 0;
663 return d->background->implicitWidth();
664}
665
666/*!
667 \since QtQuick.Controls 2.5 (Qt 5.12)
668 \qmlproperty real QtQuick.Controls::TextField::implicitBackgroundHeight
669 \readonly
670
671 This property holds the implicit background height.
672
673 The value is equal to \c {background ? background.implicitHeight : 0}.
674
675 \sa implicitBackgroundWidth
676*/
677qreal QQuickTextField::implicitBackgroundHeight() const
678{
679 Q_D(const QQuickTextField);
680 if (!d->background)
681 return 0;
682 return d->background->implicitHeight();
683}
684
685/*!
686 \since QtQuick.Controls 2.5 (Qt 5.12)
687 \qmlproperty real QtQuick.Controls::TextField::topInset
688
689 This property holds the top inset for the background.
690
691 \sa {Control Layout}, bottomInset
692*/
693qreal QQuickTextField::topInset() const
694{
695 Q_D(const QQuickTextField);
696 return d->getTopInset();
697}
698
699void QQuickTextField::setTopInset(qreal inset)
700{
701 Q_D(QQuickTextField);
702 d->setTopInset(value: inset);
703}
704
705void QQuickTextField::resetTopInset()
706{
707 Q_D(QQuickTextField);
708 d->setTopInset(value: 0, reset: true);
709}
710
711/*!
712 \since QtQuick.Controls 2.5 (Qt 5.12)
713 \qmlproperty real QtQuick.Controls::TextField::leftInset
714
715 This property holds the left inset for the background.
716
717 \sa {Control Layout}, rightInset
718*/
719qreal QQuickTextField::leftInset() const
720{
721 Q_D(const QQuickTextField);
722 return d->getLeftInset();
723}
724
725void QQuickTextField::setLeftInset(qreal inset)
726{
727 Q_D(QQuickTextField);
728 d->setLeftInset(value: inset);
729}
730
731void QQuickTextField::resetLeftInset()
732{
733 Q_D(QQuickTextField);
734 d->setLeftInset(value: 0, reset: true);
735}
736
737/*!
738 \since QtQuick.Controls 2.5 (Qt 5.12)
739 \qmlproperty real QtQuick.Controls::TextField::rightInset
740
741 This property holds the right inset for the background.
742
743 \sa {Control Layout}, leftInset
744*/
745qreal QQuickTextField::rightInset() const
746{
747 Q_D(const QQuickTextField);
748 return d->getRightInset();
749}
750
751void QQuickTextField::setRightInset(qreal inset)
752{
753 Q_D(QQuickTextField);
754 d->setRightInset(value: inset);
755}
756
757void QQuickTextField::resetRightInset()
758{
759 Q_D(QQuickTextField);
760 d->setRightInset(value: 0, reset: true);
761}
762
763/*!
764 \since QtQuick.Controls 2.5 (Qt 5.12)
765 \qmlproperty real QtQuick.Controls::TextField::bottomInset
766
767 This property holds the bottom inset for the background.
768
769 \sa {Control Layout}, topInset
770*/
771qreal QQuickTextField::bottomInset() const
772{
773 Q_D(const QQuickTextField);
774 return d->getBottomInset();
775}
776
777void QQuickTextField::setBottomInset(qreal inset)
778{
779 Q_D(QQuickTextField);
780 d->setBottomInset(value: inset);
781}
782
783void QQuickTextField::resetBottomInset()
784{
785 Q_D(QQuickTextField);
786 d->setBottomInset(value: 0, reset: true);
787}
788
789void QQuickTextField::componentComplete()
790{
791 Q_D(QQuickTextField);
792 d->executeBackground(complete: true);
793 QQuickTextInput::componentComplete();
794 d->resizeBackground();
795#if QT_CONFIG(quicktemplates2_hover)
796 if (!d->explicitHoverEnabled)
797 setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(item: d->parentItem));
798#endif
799#if QT_CONFIG(accessibility)
800 if (QAccessible::isActive())
801 d->accessibilityActiveChanged(active: true);
802#endif
803}
804
805void QQuickTextField::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
806{
807 Q_D(QQuickTextField);
808 QQuickTextInput::itemChange(change, value);
809 switch (change) {
810 case ItemEnabledHasChanged:
811 break;
812 case ItemSceneChange:
813 case ItemParentHasChanged:
814 if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) {
815 d->resolveFont();
816#if QT_CONFIG(quicktemplates2_hover)
817 if (!d->explicitHoverEnabled)
818 d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false
819#endif
820 }
821 break;
822 default:
823 break;
824 }
825}
826
827void QQuickTextField::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry)
828{
829 Q_D(QQuickTextField);
830 QQuickTextInput::geometryChange(newGeometry, oldGeometry);
831 d->resizeBackground();
832}
833
834void QQuickTextField::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset)
835{
836 Q_D(QQuickTextField);
837 Q_UNUSED(newInset);
838 Q_UNUSED(oldInset);
839 d->resizeBackground();
840}
841QSGNode *QQuickTextField::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
842{
843 QQuickDefaultClipNode *clipNode = static_cast<QQuickDefaultClipNode *>(oldNode);
844 if (!clipNode)
845 clipNode = new QQuickDefaultClipNode(QRectF());
846
847 clipNode->setRect(clipRect().adjusted(xp1: leftPadding(), yp1: topPadding(), xp2: -rightPadding(), yp2: -bottomPadding()));
848 clipNode->update();
849
850 QSGNode *textNode = QQuickTextInput::updatePaintNode(oldNode: clipNode->firstChild(), data);
851 if (!textNode->parent())
852 clipNode->appendChildNode(node: textNode);
853
854 return clipNode;
855}
856
857void QQuickTextField::focusInEvent(QFocusEvent *event)
858{
859 QQuickTextInput::focusInEvent(event);
860}
861
862void QQuickTextField::focusOutEvent(QFocusEvent *event)
863{
864 QQuickTextInput::focusOutEvent(event);
865}
866
867#if QT_CONFIG(quicktemplates2_hover)
868void QQuickTextField::hoverEnterEvent(QHoverEvent *event)
869{
870 Q_D(QQuickTextField);
871 QQuickTextInput::hoverEnterEvent(event);
872 setHovered(d->hoverEnabled);
873 event->ignore();
874}
875
876void QQuickTextField::hoverLeaveEvent(QHoverEvent *event)
877{
878 QQuickTextInput::hoverLeaveEvent(event);
879 setHovered(false);
880 event->ignore();
881}
882#endif
883
884void QQuickTextField::mousePressEvent(QMouseEvent *event)
885{
886 Q_D(QQuickTextField);
887 d->pressHandler.mousePressEvent(event);
888 if (d->pressHandler.isActive()) {
889 if (d->pressHandler.delayedMousePressEvent) {
890 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
891 d->pressHandler.clearDelayedMouseEvent();
892 }
893 if (event->buttons() != Qt::RightButton)
894 QQuickTextInput::mousePressEvent(event);
895 }
896}
897
898void QQuickTextField::mouseMoveEvent(QMouseEvent *event)
899{
900 Q_D(QQuickTextField);
901 d->pressHandler.mouseMoveEvent(event);
902 if (d->pressHandler.isActive()) {
903 if (d->pressHandler.delayedMousePressEvent) {
904 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
905 d->pressHandler.clearDelayedMouseEvent();
906 }
907 const bool isMouse = QQuickDeliveryAgentPrivate::isEventFromMouseOrTouchpad(ev: event)
908 #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0)
909 || d->selectByTouchDrag
910 #endif
911 ;
912 if (event->buttons() != Qt::RightButton && isMouse)
913 QQuickTextInput::mouseMoveEvent(event);
914 }
915}
916
917void QQuickTextField::mouseReleaseEvent(QMouseEvent *event)
918{
919 Q_D(QQuickTextField);
920 d->pressHandler.mouseReleaseEvent(event);
921 if (d->pressHandler.isActive()) {
922 if (d->pressHandler.delayedMousePressEvent) {
923 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
924 d->pressHandler.clearDelayedMouseEvent();
925 }
926 if (event->buttons() != Qt::RightButton)
927 QQuickTextInput::mouseReleaseEvent(event);
928 }
929}
930
931void QQuickTextField::mouseDoubleClickEvent(QMouseEvent *event)
932{
933 Q_D(QQuickTextField);
934 if (d->pressHandler.delayedMousePressEvent) {
935 QQuickTextInput::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get());
936 d->pressHandler.clearDelayedMouseEvent();
937 }
938 if (event->buttons() != Qt::RightButton)
939 QQuickTextInput::mouseDoubleClickEvent(event);
940}
941
942void QQuickTextField::timerEvent(QTimerEvent *event)
943{
944 Q_D(QQuickTextField);
945 if (event->timerId() == d->pressHandler.timer.timerId())
946 d->pressHandler.timerEvent(event);
947 else
948 QQuickTextInput::timerEvent(event);
949}
950
951QT_END_NAMESPACE
952
953#include "moc_qquicktextfield_p.cpp"
954

Provided by KDAB

Privacy Policy
Learn to use CMake with our Intro Training
Find out more

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