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 "qquicktextarea_p.h" |
5 | #include "qquicktextarea_p_p.h" |
6 | #include "qquickcontrol_p.h" |
7 | #include "qquickcontrol_p_p.h" |
8 | #include "qquickscrollview_p.h" |
9 | #include "qquickdeferredexecute_p_p.h" |
10 | |
11 | #include <QtQml/qqmlinfo.h> |
12 | #include <QtQuick/private/qquickitem_p.h> |
13 | #include <QtQuick/private/qquickclipnode_p.h> |
14 | #include <QtQuick/private/qquickflickable_p.h> |
15 | |
16 | #if QT_CONFIG(accessibility) |
17 | #include <QtQuick/private/qquickaccessibleattached_p.h> |
18 | #endif |
19 | |
20 | QT_BEGIN_NAMESPACE |
21 | |
22 | using namespace Qt::StringLiterals; |
23 | |
24 | /*! |
25 | \qmltype TextArea |
26 | \inherits TextEdit |
27 | //! \nativetype QQuickTextArea |
28 | \inqmlmodule QtQuick.Controls |
29 | \since 5.7 |
30 | \ingroup qtquickcontrols-input |
31 | \brief Multi-line text input area. |
32 | |
33 | TextArea is a multi-line text editor. TextArea extends TextEdit with |
34 | a \l {placeholderText}{placeholder text} functionality, and adds decoration. |
35 | |
36 | \image qtquickcontrols-textarea.png |
37 | |
38 | \code |
39 | TextArea { |
40 | placeholderText: qsTr("Enter description") |
41 | } |
42 | \endcode |
43 | |
44 | TextArea is not scrollable by itself. Especially on screen-size constrained |
45 | platforms, it is often preferable to make entire application pages scrollable. |
46 | On such a scrollable page, a non-scrollable TextArea might behave better than |
47 | nested scrollable controls. Notice, however, that in such a scenario, the background |
48 | decoration of the TextArea scrolls together with the rest of the scrollable |
49 | content. |
50 | |
51 | \section2 Scrollable TextArea |
52 | |
53 | If you want to make a TextArea scrollable, for example, when it covers |
54 | an entire application page, it can be placed inside a \l ScrollView. |
55 | |
56 | \image qtquickcontrols-textarea-scrollable.png |
57 | |
58 | \snippet qtquickcontrols-textarea-scrollable.qml 1 |
59 | |
60 | A TextArea that is placed inside a \l ScrollView does the following: |
61 | |
62 | \list |
63 | \li Sets the content size automatically |
64 | \li Ensures that the background decoration stays in place |
65 | \li Clips the content |
66 | \endlist |
67 | |
68 | \section2 Tab Focus |
69 | |
70 | By default, pressing the tab key while TextArea has |
71 | \l {Item::activeFocus}{active focus} results in a tab character being input |
72 | into the control itself. To make tab pass active focus onto another item, |
73 | use the attached \l KeyNavigation properties: |
74 | |
75 | \code |
76 | TextField { |
77 | id: textField |
78 | } |
79 | |
80 | TextArea { |
81 | KeyNavigation.priority: KeyNavigation.BeforeItem |
82 | KeyNavigation.tab: textField |
83 | } |
84 | \endcode |
85 | |
86 | \sa TextField, {Customizing TextArea}, {Input Controls} |
87 | */ |
88 | |
89 | /*! |
90 | \qmlsignal QtQuick.Controls::TextArea::pressAndHold(MouseEvent event) |
91 | |
92 | This signal is emitted when there is a long press (the delay depends on the platform plugin). |
93 | The \a event parameter provides information about the press, including the x and y |
94 | coordinates of the press, and which button is pressed. |
95 | |
96 | \sa pressed, released |
97 | */ |
98 | |
99 | /*! |
100 | \qmlsignal QtQuick.Controls::TextArea::pressed(MouseEvent event) |
101 | \since QtQuick.Controls 2.1 (Qt 5.8) |
102 | |
103 | This signal is emitted when the text area is pressed by the user. |
104 | The \a event parameter provides information about the press, |
105 | including the x and y coordinates of the press, and which button is pressed. |
106 | |
107 | \sa released, pressAndHold |
108 | */ |
109 | |
110 | /*! |
111 | \qmlsignal QtQuick.Controls::TextArea::released(MouseEvent event) |
112 | \since QtQuick.Controls 2.1 (Qt 5.8) |
113 | |
114 | This signal is emitted when the text area is released by the user. |
115 | The \a event parameter provides information about the release, |
116 | including the x and y coordinates of the press, and which button |
117 | is pressed. |
118 | |
119 | \sa pressed, pressAndHold |
120 | */ |
121 | |
122 | QQuickTextAreaPrivate::QQuickTextAreaPrivate() |
123 | { |
124 | } |
125 | |
126 | QQuickTextAreaPrivate::~QQuickTextAreaPrivate() |
127 | { |
128 | } |
129 | |
130 | void QQuickTextAreaPrivate::setTopInset(qreal value, bool reset) |
131 | { |
132 | Q_Q(QQuickTextArea); |
133 | const QMarginsF oldInset = getInset(); |
134 | extra.value().topInset = value; |
135 | extra.value().hasTopInset = !reset; |
136 | if (!qFuzzyCompare(p1: oldInset.top(), p2: value)) { |
137 | emit q->topInsetChanged(); |
138 | q->insetChange(newInset: getInset(), oldInset); |
139 | } |
140 | } |
141 | |
142 | void QQuickTextAreaPrivate::setLeftInset(qreal value, bool reset) |
143 | { |
144 | Q_Q(QQuickTextArea); |
145 | const QMarginsF oldInset = getInset(); |
146 | extra.value().leftInset = value; |
147 | extra.value().hasLeftInset = !reset; |
148 | if (!qFuzzyCompare(p1: oldInset.left(), p2: value)) { |
149 | emit q->leftInsetChanged(); |
150 | q->insetChange(newInset: getInset(), oldInset); |
151 | } |
152 | } |
153 | |
154 | void QQuickTextAreaPrivate::setRightInset(qreal value, bool reset) |
155 | { |
156 | Q_Q(QQuickTextArea); |
157 | const QMarginsF oldInset = getInset(); |
158 | extra.value().rightInset = value; |
159 | extra.value().hasRightInset = !reset; |
160 | if (!qFuzzyCompare(p1: oldInset.right(), p2: value)) { |
161 | emit q->rightInsetChanged(); |
162 | q->insetChange(newInset: getInset(), oldInset); |
163 | } |
164 | } |
165 | |
166 | void QQuickTextAreaPrivate::setBottomInset(qreal value, bool reset) |
167 | { |
168 | Q_Q(QQuickTextArea); |
169 | const QMarginsF oldInset = getInset(); |
170 | extra.value().bottomInset = value; |
171 | extra.value().hasBottomInset = !reset; |
172 | if (!qFuzzyCompare(p1: oldInset.bottom(), p2: value)) { |
173 | emit q->bottomInsetChanged(); |
174 | q->insetChange(newInset: getInset(), oldInset); |
175 | } |
176 | } |
177 | |
178 | void QQuickTextAreaPrivate::resizeBackground() |
179 | { |
180 | if (!background) |
181 | return; |
182 | |
183 | resizingBackground = true; |
184 | |
185 | // When using the attached property TextArea.flickable, we reparent the background out |
186 | // of TextArea and into the Flickable since we don't want the background to move while |
187 | // flicking. This means that the size of the background should also follow the size of |
188 | // the Flickable rather than the size of the TextArea. |
189 | const auto flickable = qobject_cast<QQuickFlickable *>(object: background->parentItem()); |
190 | |
191 | QQuickItemPrivate *p = QQuickItemPrivate::get(item: background); |
192 | if (((!p->widthValid() || !extra.isAllocated() || !extra->hasBackgroundWidth) && qFuzzyIsNull(d: background->x())) |
193 | || (extra.isAllocated() && (extra->hasLeftInset || extra->hasRightInset))) { |
194 | const qreal bgWidth = flickable ? flickable->width() : width; |
195 | background->setX(getLeftInset()); |
196 | background->setWidth(bgWidth - getLeftInset() - getRightInset()); |
197 | } |
198 | |
199 | if (((!p->heightValid() || !extra.isAllocated() || !extra->hasBackgroundHeight) && qFuzzyIsNull(d: background->y())) |
200 | || (extra.isAllocated() && (extra->hasTopInset || extra->hasBottomInset))) { |
201 | const qreal bgHeight = flickable ? flickable->height() : height; |
202 | background->setY(getTopInset()); |
203 | background->setHeight(bgHeight - getTopInset() - getBottomInset()); |
204 | } |
205 | |
206 | resizingBackground = false; |
207 | } |
208 | |
209 | /*! |
210 | \internal |
211 | |
212 | Determine which font is implicitly imposed on this control by its ancestors |
213 | and QGuiApplication::font, resolve this against its own font (attributes from |
214 | the implicit font are copied over). Then propagate this font to this |
215 | control's children. |
216 | */ |
217 | void QQuickTextAreaPrivate::resolveFont() |
218 | { |
219 | Q_Q(QQuickTextArea); |
220 | inheritFont(font: QQuickControlPrivate::parentFont(item: q)); |
221 | } |
222 | |
223 | void QQuickTextAreaPrivate::inheritFont(const QFont &font) |
224 | { |
225 | QFont parentFont = extra.isAllocated() ? extra->requestedFont.resolve(font) : font; |
226 | parentFont.setResolveMask(extra.isAllocated() ? extra->requestedFont.resolveMask() | font.resolveMask() : font.resolveMask()); |
227 | |
228 | const QFont defaultFont = QQuickTheme::font(scope: QQuickTheme::TextArea); |
229 | QFont resolvedFont = parentFont.resolve(defaultFont); |
230 | |
231 | setFont_helper(resolvedFont); |
232 | } |
233 | |
234 | /*! |
235 | \internal |
236 | |
237 | Assign \a font to this control, and propagate it to all children. |
238 | */ |
239 | void QQuickTextAreaPrivate::updateFont(const QFont &font) |
240 | { |
241 | Q_Q(QQuickTextArea); |
242 | QFont oldFont = sourceFont; |
243 | q->QQuickTextEdit::setFont(font); |
244 | |
245 | QQuickControlPrivate::updateFontRecur(item: q, font); |
246 | |
247 | if (oldFont != font) |
248 | emit q->fontChanged(); |
249 | } |
250 | |
251 | #if QT_CONFIG(quicktemplates2_hover) |
252 | void QQuickTextAreaPrivate::updateHoverEnabled(bool enabled, bool xplicit) |
253 | { |
254 | Q_Q(QQuickTextArea); |
255 | if (!xplicit && explicitHoverEnabled) |
256 | return; |
257 | |
258 | bool wasEnabled = q->isHoverEnabled(); |
259 | explicitHoverEnabled = xplicit; |
260 | if (wasEnabled != enabled) { |
261 | q->setAcceptHoverEvents(enabled); |
262 | QQuickControlPrivate::updateHoverEnabledRecur(item: q, enabled); |
263 | emit q->hoverEnabledChanged(); |
264 | } |
265 | } |
266 | #endif |
267 | |
268 | void QQuickTextAreaPrivate::attachFlickable(QQuickFlickable *item) |
269 | { |
270 | Q_Q(QQuickTextArea); |
271 | flickable = item; |
272 | q->setParentItem(flickable->contentItem()); |
273 | |
274 | if (background) |
275 | background->setParentItem(flickable); |
276 | |
277 | QObjectPrivate::connect(sender: q, signal: &QQuickTextArea::contentSizeChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::resizeFlickableContent); |
278 | QObjectPrivate::connect(sender: q, signal: &QQuickTextEdit::cursorRectangleChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::ensureCursorVisible); |
279 | |
280 | QObject::connect(sender: flickable, signal: &QQuickFlickable::contentXChanged, context: q, slot: &QQuickItem::update); |
281 | QObject::connect(sender: flickable, signal: &QQuickFlickable::contentYChanged, context: q, slot: &QQuickItem::update); |
282 | |
283 | QQuickItemPrivate::get(item: flickable)->updateOrAddGeometryChangeListener(listener: this, types: QQuickGeometryChange::Size); |
284 | QQuickItemPrivate::get(item: flickable)->addItemChangeListener(listener: this, types: QQuickItemPrivate::Destroyed); |
285 | QObjectPrivate::connect(sender: flickable, signal: &QQuickFlickable::contentWidthChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::resizeFlickableControl); |
286 | QObjectPrivate::connect(sender: flickable, signal: &QQuickFlickable::contentHeightChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::resizeFlickableControl); |
287 | |
288 | resizeFlickableControl(); |
289 | } |
290 | |
291 | void QQuickTextAreaPrivate::detachFlickable() |
292 | { |
293 | Q_Q(QQuickTextArea); |
294 | q->setParentItem(nullptr); |
295 | if (background && background->parentItem() == flickable) |
296 | background->setParentItem(q); |
297 | |
298 | QObjectPrivate::disconnect(sender: q, signal: &QQuickTextArea::contentSizeChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::resizeFlickableContent); |
299 | QObjectPrivate::disconnect(sender: q, signal: &QQuickTextEdit::cursorRectangleChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::ensureCursorVisible); |
300 | |
301 | QObject::disconnect(sender: flickable, signal: &QQuickFlickable::contentXChanged, receiver: q, slot: &QQuickItem::update); |
302 | QObject::disconnect(sender: flickable, signal: &QQuickFlickable::contentYChanged, receiver: q, slot: &QQuickItem::update); |
303 | |
304 | QQuickItemPrivate::get(item: flickable)->updateOrRemoveGeometryChangeListener(listener: this, types: QQuickGeometryChange::Nothing); |
305 | QQuickItemPrivate::get(item: flickable)->removeItemChangeListener(this, types: QQuickItemPrivate::Destroyed); |
306 | QObjectPrivate::disconnect(sender: flickable, signal: &QQuickFlickable::contentWidthChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::resizeFlickableControl); |
307 | QObjectPrivate::disconnect(sender: flickable, signal: &QQuickFlickable::contentHeightChanged, receiverPrivate: this, slot: &QQuickTextAreaPrivate::resizeFlickableControl); |
308 | |
309 | flickable = nullptr; |
310 | |
311 | resizeBackground(); |
312 | } |
313 | |
314 | void QQuickTextAreaPrivate::ensureCursorVisible() |
315 | { |
316 | Q_Q(QQuickTextArea); |
317 | if (!flickable) |
318 | return; |
319 | |
320 | const qreal cx = flickable->contentX(); |
321 | const qreal cy = flickable->contentY(); |
322 | const qreal w = flickable->width(); |
323 | const qreal h = flickable->height(); |
324 | |
325 | const qreal tp = q->topPadding(); |
326 | const qreal lp = q->leftPadding(); |
327 | const QRectF cr = q->cursorRectangle(); |
328 | |
329 | if (cr.left() <= cx + lp) { |
330 | flickable->setContentX(cr.left() - lp); |
331 | } else { |
332 | // calculate the rectangle of the next character and ensure that |
333 | // it's visible if it's on the same line with the cursor |
334 | const qreal rp = q->rightPadding(); |
335 | const QRectF nr = q->cursorPosition() < q->length() ? q->positionToRectangle(q->cursorPosition() + 1) : QRectF(); |
336 | if (qFuzzyCompare(p1: nr.y(), p2: cr.y()) && nr.right() >= cx + lp + w - rp) |
337 | flickable->setContentX(nr.right() - w + rp); |
338 | else if (cr.right() >= cx + lp + w - rp) |
339 | flickable->setContentX(cr.right() - w + rp); |
340 | } |
341 | |
342 | if (cr.top() <= cy + tp) { |
343 | flickable->setContentY(cr.top() - tp); |
344 | } else { |
345 | const qreal bp = q->bottomPadding(); |
346 | if (cr.bottom() >= cy + tp + h - bp && cr.bottom() <= flickable->contentHeight()) |
347 | flickable->setContentY(cr.bottom() - h + bp); |
348 | } |
349 | } |
350 | |
351 | void QQuickTextAreaPrivate::resizeFlickableControl() |
352 | { |
353 | Q_Q(QQuickTextArea); |
354 | if (!flickable) |
355 | return; |
356 | |
357 | const qreal w = wrapMode == QQuickTextArea::NoWrap ? qMax(a: flickable->width(), b: flickable->contentWidth()) : flickable->width(); |
358 | const qreal h = qMax(a: flickable->height(), b: flickable->contentHeight()); |
359 | q->setSize(QSizeF(w, h)); |
360 | |
361 | resizeBackground(); |
362 | } |
363 | |
364 | void QQuickTextAreaPrivate::resizeFlickableContent() |
365 | { |
366 | Q_Q(QQuickTextArea); |
367 | if (!flickable) |
368 | return; |
369 | |
370 | flickable->setContentWidth(q->implicitWidth()); |
371 | flickable->setContentHeight(q->implicitHeight()); |
372 | } |
373 | |
374 | void QQuickTextAreaPrivate::itemGeometryChanged(QQuickItem *item, QQuickGeometryChange change, const QRectF &diff) |
375 | { |
376 | Q_UNUSED(diff); |
377 | if (!resizingBackground && item == background) { |
378 | QQuickItemPrivate *p = QQuickItemPrivate::get(item); |
379 | // Only set hasBackgroundWidth/Height if it was a width/height change, |
380 | // otherwise we're prevented from setting a width/height in the future. |
381 | if (change.widthChange()) |
382 | extra.value().hasBackgroundWidth = p->widthValid(); |
383 | if (change.heightChange()) |
384 | extra.value().hasBackgroundHeight = p->heightValid(); |
385 | } |
386 | |
387 | if (flickable) |
388 | resizeFlickableControl(); |
389 | else |
390 | resizeBackground(); |
391 | } |
392 | |
393 | qreal QQuickTextAreaPrivate::getImplicitWidth() const |
394 | { |
395 | return QQuickItemPrivate::getImplicitWidth(); |
396 | } |
397 | |
398 | qreal QQuickTextAreaPrivate::getImplicitHeight() const |
399 | { |
400 | return QQuickItemPrivate::getImplicitHeight(); |
401 | } |
402 | |
403 | void QQuickTextAreaPrivate::implicitWidthChanged() |
404 | { |
405 | Q_Q(QQuickTextArea); |
406 | QQuickItemPrivate::implicitWidthChanged(); |
407 | emit q->implicitWidthChanged3(); |
408 | } |
409 | |
410 | void QQuickTextAreaPrivate::implicitHeightChanged() |
411 | { |
412 | Q_Q(QQuickTextArea); |
413 | QQuickItemPrivate::implicitHeightChanged(); |
414 | emit q->implicitHeightChanged3(); |
415 | } |
416 | |
417 | #if QT_CONFIG(accessibility) |
418 | void QQuickTextAreaPrivate::accessibilityActiveChanged(bool active) |
419 | { |
420 | QQuickTextEditPrivate::accessibilityActiveChanged(active); |
421 | if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: q_func())) |
422 | accessibleAttached->setDescription(placeholder); |
423 | } |
424 | #endif |
425 | |
426 | void QQuickTextAreaPrivate::cancelBackground() |
427 | { |
428 | Q_Q(QQuickTextArea); |
429 | quickCancelDeferred(object: q, property: backgroundName()); |
430 | } |
431 | |
432 | void QQuickTextAreaPrivate::executeBackground(bool complete) |
433 | { |
434 | Q_Q(QQuickTextArea); |
435 | if (background.wasExecuted()) |
436 | return; |
437 | |
438 | if (!background || complete) |
439 | quickBeginDeferred(object: q, property: backgroundName(), delegate&: background); |
440 | if (complete) |
441 | quickCompleteDeferred(object: q, property: backgroundName(), delegate&: background); |
442 | } |
443 | |
444 | void QQuickTextAreaPrivate::itemImplicitWidthChanged(QQuickItem *item) |
445 | { |
446 | Q_Q(QQuickTextArea); |
447 | if (item == background) |
448 | emit q->implicitBackgroundWidthChanged(); |
449 | } |
450 | |
451 | void QQuickTextAreaPrivate::itemImplicitHeightChanged(QQuickItem *item) |
452 | { |
453 | Q_Q(QQuickTextArea); |
454 | if (item == background) |
455 | emit q->implicitBackgroundHeightChanged(); |
456 | } |
457 | |
458 | void QQuickTextAreaPrivate::itemDestroyed(QQuickItem *item) |
459 | { |
460 | Q_Q(QQuickTextArea); |
461 | if (item == background) { |
462 | background = nullptr; |
463 | emit q->implicitBackgroundWidthChanged(); |
464 | emit q->implicitBackgroundHeightChanged(); |
465 | } else if (item == flickable) { |
466 | detachFlickable(); |
467 | } |
468 | } |
469 | |
470 | QPalette QQuickTextAreaPrivate::defaultPalette() const |
471 | { |
472 | return QQuickTheme::palette(scope: QQuickTheme::TextArea); |
473 | } |
474 | |
475 | bool QQuickTextAreaPrivate::setLastFocusChangeReason(Qt::FocusReason reason) |
476 | { |
477 | Q_Q(QQuickTextArea); |
478 | const auto focusReasonChanged = QQuickItemPrivate::setLastFocusChangeReason(reason); |
479 | if (focusReasonChanged) |
480 | emit q->focusReasonChanged(); |
481 | |
482 | return focusReasonChanged; |
483 | } |
484 | |
485 | QQuickTextArea::QQuickTextArea(QQuickItem *parent) |
486 | : QQuickTextEdit(*(new QQuickTextAreaPrivate), parent) |
487 | { |
488 | Q_D(QQuickTextArea); |
489 | setActiveFocusOnTab(true); |
490 | setAcceptedMouseButtons(Qt::AllButtons); |
491 | d->setImplicitResizeEnabled(false); |
492 | d->pressHandler.control = this; |
493 | |
494 | #if QT_VERSION < QT_VERSION_CHECK(7, 0, 0) |
495 | if (qEnvironmentVariable(varName: "QT_QUICK_CONTROLS_TEXT_SELECTION_BEHAVIOR") == u "old"_s) |
496 | QQuickTextEdit::setOldSelectionDefault(); |
497 | #endif |
498 | } |
499 | |
500 | QQuickTextArea::~QQuickTextArea() |
501 | { |
502 | Q_D(QQuickTextArea); |
503 | if (d->flickable) |
504 | d->detachFlickable(); |
505 | QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); |
506 | } |
507 | |
508 | QQuickTextAreaAttached *QQuickTextArea::qmlAttachedProperties(QObject *object) |
509 | { |
510 | return new QQuickTextAreaAttached(object); |
511 | } |
512 | |
513 | QFont QQuickTextArea::font() const |
514 | { |
515 | Q_D(const QQuickTextArea); |
516 | QFont font = QQuickTextEdit::font(); |
517 | // The resolve mask should inherit from the requestedFont |
518 | font.setResolveMask(d->extra.value().requestedFont.resolveMask()); |
519 | return font; |
520 | } |
521 | |
522 | void QQuickTextArea::setFont(const QFont &font) |
523 | { |
524 | Q_D(QQuickTextArea); |
525 | if (d->extra.value().requestedFont.resolveMask() == font.resolveMask() && d->extra.value().requestedFont == font) |
526 | return; |
527 | |
528 | d->extra.value().requestedFont = font; |
529 | d->resolveFont(); |
530 | } |
531 | |
532 | /*! |
533 | \qmlproperty Item QtQuick.Controls::TextArea::background |
534 | |
535 | This property holds the background item. |
536 | |
537 | \input qquickcontrol-background.qdocinc notes |
538 | |
539 | \sa {Customizing TextArea} |
540 | */ |
541 | QQuickItem *QQuickTextArea::background() const |
542 | { |
543 | QQuickTextAreaPrivate *d = const_cast<QQuickTextAreaPrivate *>(d_func()); |
544 | if (!d->background) |
545 | d->executeBackground(); |
546 | return d->background; |
547 | } |
548 | |
549 | void QQuickTextArea::setBackground(QQuickItem *background) |
550 | { |
551 | Q_D(QQuickTextArea); |
552 | if (d->background == background) |
553 | return; |
554 | |
555 | QQuickControlPrivate::warnIfCustomizationNotSupported(control: this, item: background, QStringLiteral("background")); |
556 | |
557 | if (!d->background.isExecuting()) |
558 | d->cancelBackground(); |
559 | |
560 | const qreal oldImplicitBackgroundWidth = implicitBackgroundWidth(); |
561 | const qreal oldImplicitBackgroundHeight = implicitBackgroundHeight(); |
562 | |
563 | if (d->extra.isAllocated()) { |
564 | d->extra.value().hasBackgroundWidth = false; |
565 | d->extra.value().hasBackgroundHeight = false; |
566 | } |
567 | |
568 | QQuickControlPrivate::removeImplicitSizeListener(item: d->background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); |
569 | QQuickControlPrivate::hideOldItem(item: d->background); |
570 | d->background = background; |
571 | |
572 | if (background) { |
573 | QQuickItemPrivate *p = QQuickItemPrivate::get(item: background); |
574 | if (p->widthValid() || p->heightValid()) { |
575 | d->extra.value().hasBackgroundWidth = p->widthValid(); |
576 | d->extra.value().hasBackgroundHeight = p->heightValid(); |
577 | } |
578 | if (d->flickable) |
579 | background->setParentItem(d->flickable); |
580 | else |
581 | background->setParentItem(this); |
582 | if (qFuzzyIsNull(d: background->z())) |
583 | background->setZ(-1); |
584 | if (isComponentComplete()) |
585 | d->resizeBackground(); |
586 | QQuickControlPrivate::addImplicitSizeListener(item: background, listener: d, changes: QQuickControlPrivate::ImplicitSizeChanges | QQuickItemPrivate::Geometry); |
587 | } |
588 | |
589 | if (!qFuzzyCompare(p1: oldImplicitBackgroundWidth, p2: implicitBackgroundWidth())) |
590 | emit implicitBackgroundWidthChanged(); |
591 | if (!qFuzzyCompare(p1: oldImplicitBackgroundHeight, p2: implicitBackgroundHeight())) |
592 | emit implicitBackgroundHeightChanged(); |
593 | if (!d->background.isExecuting()) |
594 | emit backgroundChanged(); |
595 | } |
596 | |
597 | /*! |
598 | \qmlproperty string QtQuick.Controls::TextArea::placeholderText |
599 | |
600 | This property holds the short hint that is displayed in the text area before |
601 | the user enters a value. |
602 | */ |
603 | QString QQuickTextArea::placeholderText() const |
604 | { |
605 | Q_D(const QQuickTextArea); |
606 | return d->placeholder; |
607 | } |
608 | |
609 | void QQuickTextArea::setPlaceholderText(const QString &text) |
610 | { |
611 | Q_D(QQuickTextArea); |
612 | if (d->placeholder == text) |
613 | return; |
614 | |
615 | d->placeholder = text; |
616 | #if QT_CONFIG(accessibility) |
617 | if (QQuickAccessibleAttached *accessibleAttached = QQuickControlPrivate::accessibleAttached(object: this)) |
618 | accessibleAttached->setDescription(text); |
619 | #endif |
620 | emit placeholderTextChanged(); |
621 | } |
622 | |
623 | /*! |
624 | \qmlproperty color QtQuick.Controls::TextArea::placeholderTextColor |
625 | \since QtQuick.Controls 2.5 (Qt 5.12) |
626 | |
627 | This property holds the color of placeholderText. |
628 | |
629 | \sa placeholderText |
630 | */ |
631 | QColor QQuickTextArea::placeholderTextColor() const |
632 | { |
633 | Q_D(const QQuickTextArea); |
634 | return d->placeholderColor; |
635 | } |
636 | |
637 | void QQuickTextArea::setPlaceholderTextColor(const QColor &color) |
638 | { |
639 | Q_D(QQuickTextArea); |
640 | if (d->placeholderColor == color) |
641 | return; |
642 | |
643 | d->placeholderColor = color; |
644 | emit placeholderTextColorChanged(); |
645 | } |
646 | |
647 | /*! |
648 | \qmlproperty enumeration QtQuick.Controls::TextArea::focusReason |
649 | |
650 | This property holds the reason of the last focus change. |
651 | |
652 | \note This property does not indicate whether the item has \l {Item::activeFocus} |
653 | {active focus}, but the reason why the item either gained or lost focus. |
654 | |
655 | \value Qt.MouseFocusReason A mouse action occurred. |
656 | \value Qt.TabFocusReason The Tab key was pressed. |
657 | \value Qt.BacktabFocusReason A Backtab occurred. The input for this may include the Shift or Control keys; e.g. Shift+Tab. |
658 | \value Qt.ActiveWindowFocusReason The window system made this window either active or inactive. |
659 | \value Qt.PopupFocusReason The application opened/closed a pop-up that grabbed/released the keyboard focus. |
660 | \value Qt.ShortcutFocusReason The user typed a label's buddy shortcut |
661 | \value Qt.MenuBarFocusReason The menu bar took focus. |
662 | \value Qt.OtherFocusReason Another reason, usually application-specific. |
663 | |
664 | \note Prefer \l {QtQuick.Controls::Control::focusReason} to this property. |
665 | */ |
666 | Qt::FocusReason QQuickTextArea::focusReason() const |
667 | { |
668 | Q_D(const QQuickTextArea); |
669 | return d->lastFocusChangeReason(); |
670 | } |
671 | |
672 | void QQuickTextArea::setFocusReason(Qt::FocusReason reason) |
673 | { |
674 | Q_D(QQuickTextArea); |
675 | d->setLastFocusChangeReason(reason); |
676 | } |
677 | |
678 | |
679 | bool QQuickTextArea::contains(const QPointF &point) const |
680 | { |
681 | Q_D(const QQuickTextArea); |
682 | if (d->flickable && !d->flickable->contains(point: d->flickable->mapFromItem(item: this, point))) |
683 | return false; |
684 | return QQuickTextEdit::contains(point); |
685 | } |
686 | |
687 | /*! |
688 | \since QtQuick.Controls 2.1 (Qt 5.8) |
689 | \qmlproperty bool QtQuick.Controls::TextArea::hovered |
690 | \readonly |
691 | |
692 | This property holds whether the text area is hovered. |
693 | |
694 | \sa hoverEnabled |
695 | */ |
696 | bool QQuickTextArea::isHovered() const |
697 | { |
698 | #if QT_CONFIG(quicktemplates2_hover) |
699 | Q_D(const QQuickTextArea); |
700 | return d->hovered; |
701 | #else |
702 | return false; |
703 | #endif |
704 | } |
705 | |
706 | void QQuickTextArea::setHovered(bool hovered) |
707 | { |
708 | #if QT_CONFIG(quicktemplates2_hover) |
709 | Q_D(QQuickTextArea); |
710 | if (hovered == d->hovered) |
711 | return; |
712 | |
713 | d->hovered = hovered; |
714 | emit hoveredChanged(); |
715 | #else |
716 | Q_UNUSED(hovered); |
717 | #endif |
718 | } |
719 | |
720 | /*! |
721 | \since QtQuick.Controls 2.1 (Qt 5.8) |
722 | \qmlproperty bool QtQuick.Controls::TextArea::hoverEnabled |
723 | |
724 | This property determines whether the text area accepts hover events. The default value is \c true. |
725 | |
726 | \sa hovered |
727 | */ |
728 | bool QQuickTextArea::isHoverEnabled() const |
729 | { |
730 | #if QT_CONFIG(quicktemplates2_hover) |
731 | Q_D(const QQuickTextArea); |
732 | return d->hoverEnabled; |
733 | #else |
734 | return false; |
735 | #endif |
736 | } |
737 | |
738 | void QQuickTextArea::setHoverEnabled(bool enabled) |
739 | { |
740 | #if QT_CONFIG(quicktemplates2_hover) |
741 | Q_D(QQuickTextArea); |
742 | if (d->explicitHoverEnabled && enabled == d->hoverEnabled) |
743 | return; |
744 | |
745 | d->updateHoverEnabled(enabled, xplicit: true); // explicit=true |
746 | #else |
747 | Q_UNUSED(enabled); |
748 | #endif |
749 | } |
750 | |
751 | void QQuickTextArea::resetHoverEnabled() |
752 | { |
753 | #if QT_CONFIG(quicktemplates2_hover) |
754 | Q_D(QQuickTextArea); |
755 | if (!d->explicitHoverEnabled) |
756 | return; |
757 | |
758 | d->explicitHoverEnabled = false; |
759 | d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false |
760 | #endif |
761 | } |
762 | |
763 | /*! |
764 | \since QtQuick.Controls 2.5 (Qt 5.12) |
765 | \qmlproperty real QtQuick.Controls::TextArea::implicitBackgroundWidth |
766 | \readonly |
767 | |
768 | This property holds the implicit background width. |
769 | |
770 | The value is equal to \c {background ? background.implicitWidth : 0}. |
771 | |
772 | \sa implicitBackgroundHeight |
773 | */ |
774 | qreal QQuickTextArea::implicitBackgroundWidth() const |
775 | { |
776 | Q_D(const QQuickTextArea); |
777 | if (!d->background) |
778 | return 0; |
779 | return d->background->implicitWidth(); |
780 | } |
781 | |
782 | /*! |
783 | \since QtQuick.Controls 2.5 (Qt 5.12) |
784 | \qmlproperty real QtQuick.Controls::TextArea::implicitBackgroundHeight |
785 | \readonly |
786 | |
787 | This property holds the implicit background height. |
788 | |
789 | The value is equal to \c {background ? background.implicitHeight : 0}. |
790 | |
791 | \sa implicitBackgroundWidth |
792 | */ |
793 | qreal QQuickTextArea::implicitBackgroundHeight() const |
794 | { |
795 | Q_D(const QQuickTextArea); |
796 | if (!d->background) |
797 | return 0; |
798 | return d->background->implicitHeight(); |
799 | } |
800 | |
801 | /*! |
802 | \since QtQuick.Controls 2.5 (Qt 5.12) |
803 | \qmlproperty real QtQuick.Controls::TextArea::topInset |
804 | |
805 | This property holds the top inset for the background. |
806 | |
807 | \sa {Control Layout}, bottomInset |
808 | */ |
809 | qreal QQuickTextArea::topInset() const |
810 | { |
811 | Q_D(const QQuickTextArea); |
812 | return d->getTopInset(); |
813 | } |
814 | |
815 | void QQuickTextArea::setTopInset(qreal inset) |
816 | { |
817 | Q_D(QQuickTextArea); |
818 | d->setTopInset(value: inset); |
819 | } |
820 | |
821 | void QQuickTextArea::resetTopInset() |
822 | { |
823 | Q_D(QQuickTextArea); |
824 | d->setTopInset(value: 0, reset: true); |
825 | } |
826 | |
827 | /*! |
828 | \since QtQuick.Controls 2.5 (Qt 5.12) |
829 | \qmlproperty real QtQuick.Controls::TextArea::leftInset |
830 | |
831 | This property holds the left inset for the background. |
832 | |
833 | \sa {Control Layout}, rightInset |
834 | */ |
835 | qreal QQuickTextArea::leftInset() const |
836 | { |
837 | Q_D(const QQuickTextArea); |
838 | return d->getLeftInset(); |
839 | } |
840 | |
841 | void QQuickTextArea::setLeftInset(qreal inset) |
842 | { |
843 | Q_D(QQuickTextArea); |
844 | d->setLeftInset(value: inset); |
845 | } |
846 | |
847 | void QQuickTextArea::resetLeftInset() |
848 | { |
849 | Q_D(QQuickTextArea); |
850 | d->setLeftInset(value: 0, reset: true); |
851 | } |
852 | |
853 | /*! |
854 | \since QtQuick.Controls 2.5 (Qt 5.12) |
855 | \qmlproperty real QtQuick.Controls::TextArea::rightInset |
856 | |
857 | This property holds the right inset for the background. |
858 | |
859 | \sa {Control Layout}, leftInset |
860 | */ |
861 | qreal QQuickTextArea::rightInset() const |
862 | { |
863 | Q_D(const QQuickTextArea); |
864 | return d->getRightInset(); |
865 | } |
866 | |
867 | void QQuickTextArea::setRightInset(qreal inset) |
868 | { |
869 | Q_D(QQuickTextArea); |
870 | d->setRightInset(value: inset); |
871 | } |
872 | |
873 | void QQuickTextArea::resetRightInset() |
874 | { |
875 | Q_D(QQuickTextArea); |
876 | d->setRightInset(value: 0, reset: true); |
877 | } |
878 | |
879 | /*! |
880 | \since QtQuick.Controls 2.5 (Qt 5.12) |
881 | \qmlproperty real QtQuick.Controls::TextArea::bottomInset |
882 | |
883 | This property holds the bottom inset for the background. |
884 | |
885 | \sa {Control Layout}, topInset |
886 | */ |
887 | qreal QQuickTextArea::bottomInset() const |
888 | { |
889 | Q_D(const QQuickTextArea); |
890 | return d->getBottomInset(); |
891 | } |
892 | |
893 | void QQuickTextArea::setBottomInset(qreal inset) |
894 | { |
895 | Q_D(QQuickTextArea); |
896 | d->setBottomInset(value: inset); |
897 | } |
898 | |
899 | void QQuickTextArea::resetBottomInset() |
900 | { |
901 | Q_D(QQuickTextArea); |
902 | d->setBottomInset(value: 0, reset: true); |
903 | } |
904 | |
905 | void QQuickTextArea::classBegin() |
906 | { |
907 | Q_D(QQuickTextArea); |
908 | QQuickTextEdit::classBegin(); |
909 | d->resolveFont(); |
910 | } |
911 | |
912 | void QQuickTextArea::componentComplete() |
913 | { |
914 | Q_D(QQuickTextArea); |
915 | d->executeBackground(complete: true); |
916 | QQuickTextEdit::componentComplete(); |
917 | d->resizeBackground(); |
918 | #if QT_CONFIG(quicktemplates2_hover) |
919 | if (!d->explicitHoverEnabled) |
920 | setAcceptHoverEvents(QQuickControlPrivate::calcHoverEnabled(item: d->parentItem)); |
921 | #endif |
922 | } |
923 | |
924 | void QQuickTextArea::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value) |
925 | { |
926 | Q_D(QQuickTextArea); |
927 | QQuickTextEdit::itemChange(change, value); |
928 | switch (change) { |
929 | case ItemEnabledHasChanged: |
930 | break; |
931 | case ItemSceneChange: |
932 | case ItemParentHasChanged: |
933 | if ((change == ItemParentHasChanged && value.item) || (change == ItemSceneChange && value.window)) { |
934 | d->resolveFont(); |
935 | #if QT_CONFIG(quicktemplates2_hover) |
936 | if (!d->explicitHoverEnabled) |
937 | d->updateHoverEnabled(enabled: QQuickControlPrivate::calcHoverEnabled(item: d->parentItem), xplicit: false); // explicit=false |
938 | #endif |
939 | if (change == ItemParentHasChanged) { |
940 | QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(object: value.item->parentItem()); |
941 | if (flickable) { |
942 | QQuickScrollView *scrollView = qobject_cast<QQuickScrollView *>(object: flickable->parentItem()); |
943 | if (scrollView) |
944 | d->attachFlickable(item: flickable); |
945 | } |
946 | } |
947 | } |
948 | break; |
949 | default: |
950 | break; |
951 | } |
952 | } |
953 | |
954 | void QQuickTextArea::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) |
955 | { |
956 | Q_D(QQuickTextArea); |
957 | QQuickTextEdit::geometryChange(newGeometry, oldGeometry); |
958 | d->resizeBackground(); |
959 | } |
960 | |
961 | void QQuickTextArea::insetChange(const QMarginsF &newInset, const QMarginsF &oldInset) |
962 | { |
963 | Q_D(QQuickTextArea); |
964 | Q_UNUSED(newInset); |
965 | Q_UNUSED(oldInset); |
966 | d->resizeBackground(); |
967 | } |
968 | |
969 | QSGNode *QQuickTextArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) |
970 | { |
971 | Q_D(QQuickTextArea); |
972 | QQuickDefaultClipNode *clipNode = static_cast<QQuickDefaultClipNode *>(oldNode); |
973 | if (!clipNode) |
974 | clipNode = new QQuickDefaultClipNode(QRectF()); |
975 | |
976 | QQuickItem *clipper = this; |
977 | if (d->flickable) |
978 | clipper = d->flickable; |
979 | |
980 | const QRectF cr = clipper->clipRect().adjusted( |
981 | xp1: leftPadding(), yp1: topPadding(), |
982 | xp2: (!d->cursorItem && effectiveHAlign() == HAlignment::AlignRight ? 1 : 0) - rightPadding(), |
983 | yp2: -bottomPadding()); |
984 | |
985 | clipNode->setRect(!d->flickable ? cr : cr.translated(dx: d->flickable->contentX(), dy: d->flickable->contentY())); |
986 | clipNode->update(); |
987 | |
988 | QSGNode *textNode = QQuickTextEdit::updatePaintNode(oldNode: clipNode->firstChild(), updatePaintNodeData: data); |
989 | if (!textNode->parent()) |
990 | clipNode->appendChildNode(node: textNode); |
991 | |
992 | if (d->cursorItem) { |
993 | QQuickDefaultClipNode *cursorNode = QQuickItemPrivate::get(item: d->cursorItem)->clipNode(); |
994 | if (cursorNode) |
995 | cursorNode->setClipRect(d->cursorItem->mapRectFromItem(item: clipper, rect: cr)); |
996 | } |
997 | |
998 | return clipNode; |
999 | } |
1000 | |
1001 | void QQuickTextArea::focusInEvent(QFocusEvent *event) |
1002 | { |
1003 | QQuickTextEdit::focusInEvent(event); |
1004 | } |
1005 | |
1006 | void QQuickTextArea::focusOutEvent(QFocusEvent *event) |
1007 | { |
1008 | QQuickTextEdit::focusOutEvent(event); |
1009 | } |
1010 | |
1011 | #if QT_CONFIG(quicktemplates2_hover) |
1012 | void QQuickTextArea::hoverEnterEvent(QHoverEvent *event) |
1013 | { |
1014 | Q_D(QQuickTextArea); |
1015 | QQuickTextEdit::hoverEnterEvent(event); |
1016 | setHovered(d->hoverEnabled); |
1017 | event->ignore(); |
1018 | } |
1019 | |
1020 | void QQuickTextArea::hoverLeaveEvent(QHoverEvent *event) |
1021 | { |
1022 | QQuickTextEdit::hoverLeaveEvent(event); |
1023 | setHovered(false); |
1024 | event->ignore(); |
1025 | } |
1026 | #endif |
1027 | |
1028 | void QQuickTextArea::mousePressEvent(QMouseEvent *event) |
1029 | { |
1030 | Q_D(QQuickTextArea); |
1031 | d->pressHandler.mousePressEvent(event); |
1032 | if (d->pressHandler.isActive()) { |
1033 | if (d->pressHandler.delayedMousePressEvent) { |
1034 | QQuickTextEdit::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get()); |
1035 | d->pressHandler.clearDelayedMouseEvent(); |
1036 | } |
1037 | // Calling the base class implementation will result in QQuickTextControl's |
1038 | // press handler being called, which ignores events that aren't Qt::LeftButton. |
1039 | const bool wasAccepted = event->isAccepted(); |
1040 | QQuickTextEdit::mousePressEvent(event); |
1041 | if (wasAccepted) |
1042 | event->accept(); |
1043 | } |
1044 | } |
1045 | |
1046 | void QQuickTextArea::mouseMoveEvent(QMouseEvent *event) |
1047 | { |
1048 | Q_D(QQuickTextArea); |
1049 | d->pressHandler.mouseMoveEvent(event); |
1050 | if (d->pressHandler.isActive()) { |
1051 | if (d->pressHandler.delayedMousePressEvent) { |
1052 | QQuickTextEdit::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get()); |
1053 | d->pressHandler.clearDelayedMouseEvent(); |
1054 | } |
1055 | QQuickTextEdit::mouseMoveEvent(event); |
1056 | } |
1057 | } |
1058 | |
1059 | void QQuickTextArea::mouseReleaseEvent(QMouseEvent *event) |
1060 | { |
1061 | Q_D(QQuickTextArea); |
1062 | d->pressHandler.mouseReleaseEvent(event); |
1063 | if (d->pressHandler.isActive()) { |
1064 | if (d->pressHandler.delayedMousePressEvent) { |
1065 | QQuickTextEdit::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get()); |
1066 | d->pressHandler.clearDelayedMouseEvent(); |
1067 | } |
1068 | QQuickTextEdit::mouseReleaseEvent(event); |
1069 | } |
1070 | } |
1071 | |
1072 | void QQuickTextArea::mouseDoubleClickEvent(QMouseEvent *event) |
1073 | { |
1074 | Q_D(QQuickTextArea); |
1075 | if (d->pressHandler.delayedMousePressEvent) { |
1076 | QQuickTextEdit::mousePressEvent(event: d->pressHandler.delayedMousePressEvent.get()); |
1077 | d->pressHandler.clearDelayedMouseEvent(); |
1078 | } |
1079 | QQuickTextEdit::mouseDoubleClickEvent(event); |
1080 | } |
1081 | |
1082 | void QQuickTextArea::timerEvent(QTimerEvent *event) |
1083 | { |
1084 | Q_D(QQuickTextArea); |
1085 | if (event->timerId() == d->pressHandler.timer.timerId()) |
1086 | d->pressHandler.timerEvent(event); |
1087 | else |
1088 | QQuickTextEdit::timerEvent(event); |
1089 | } |
1090 | |
1091 | class QQuickTextAreaAttachedPrivate : public QObjectPrivate |
1092 | { |
1093 | public: |
1094 | QQuickTextArea *control = nullptr; |
1095 | }; |
1096 | |
1097 | QQuickTextAreaAttached::QQuickTextAreaAttached(QObject *parent) |
1098 | : QObject(*(new QQuickTextAreaAttachedPrivate), parent) |
1099 | { |
1100 | } |
1101 | |
1102 | /*! |
1103 | \qmlattachedproperty TextArea QtQuick.Controls::TextArea::flickable |
1104 | |
1105 | This property attaches a text area to a \l Flickable. |
1106 | |
1107 | \sa ScrollBar, ScrollIndicator, {Scrollable TextArea} |
1108 | */ |
1109 | QQuickTextArea *QQuickTextAreaAttached::flickable() const |
1110 | { |
1111 | Q_D(const QQuickTextAreaAttached); |
1112 | return d->control; |
1113 | } |
1114 | |
1115 | void QQuickTextAreaAttached::setFlickable(QQuickTextArea *control) |
1116 | { |
1117 | Q_D(QQuickTextAreaAttached); |
1118 | QQuickFlickable *flickable = qobject_cast<QQuickFlickable *>(object: parent()); |
1119 | if (!flickable) { |
1120 | qmlWarning(me: parent()) << "TextArea must be attached to a Flickable"; |
1121 | return; |
1122 | } |
1123 | |
1124 | if (d->control == control) |
1125 | return; |
1126 | |
1127 | if (d->control) |
1128 | QQuickTextAreaPrivate::get(item: d->control)->detachFlickable(); |
1129 | |
1130 | d->control = control; |
1131 | |
1132 | if (control) |
1133 | QQuickTextAreaPrivate::get(item: control)->attachFlickable(item: flickable); |
1134 | |
1135 | emit flickableChanged(); |
1136 | } |
1137 | |
1138 | QT_END_NAMESPACE |
1139 | |
1140 | #include "moc_qquicktextarea_p.cpp" |
1141 |
Definitions
- QQuickTextAreaPrivate
- ~QQuickTextAreaPrivate
- setTopInset
- setLeftInset
- setRightInset
- setBottomInset
- resizeBackground
- resolveFont
- inheritFont
- updateFont
- updateHoverEnabled
- attachFlickable
- detachFlickable
- ensureCursorVisible
- resizeFlickableControl
- resizeFlickableContent
- itemGeometryChanged
- getImplicitWidth
- getImplicitHeight
- implicitWidthChanged
- implicitHeightChanged
- accessibilityActiveChanged
- cancelBackground
- executeBackground
- itemImplicitWidthChanged
- itemImplicitHeightChanged
- itemDestroyed
- defaultPalette
- setLastFocusChangeReason
- QQuickTextArea
- ~QQuickTextArea
- qmlAttachedProperties
- font
- setFont
- background
- setBackground
- placeholderText
- setPlaceholderText
- placeholderTextColor
- setPlaceholderTextColor
- focusReason
- setFocusReason
- contains
- isHovered
- setHovered
- isHoverEnabled
- setHoverEnabled
- resetHoverEnabled
- implicitBackgroundWidth
- implicitBackgroundHeight
- topInset
- setTopInset
- resetTopInset
- leftInset
- setLeftInset
- resetLeftInset
- rightInset
- setRightInset
- resetRightInset
- bottomInset
- setBottomInset
- resetBottomInset
- classBegin
- componentComplete
- itemChange
- geometryChange
- insetChange
- updatePaintNode
- focusInEvent
- focusOutEvent
- hoverEnterEvent
- hoverLeaveEvent
- mousePressEvent
- mouseMoveEvent
- mouseReleaseEvent
- mouseDoubleClickEvent
- timerEvent
- QQuickTextAreaAttachedPrivate
- QQuickTextAreaAttached
- flickable
Start learning QML with our Intro Training
Find out more