#include "qquicktextinput_p.h"
#include "qquicktextinput_p_p.h"
-#include "qquickcanvas.h"
+#include "qquickwindow.h"
#include "qquicktextutil_p.h"
#include <private/qqmlglobal_p.h>
/*!
\qmlclass TextInput QQuickTextInput
\inqmlmodule QtQuick 2
- \ingroup qml-basic-visual-elements
+ \ingroup qtquick-visual
+ \ingroup qtquick-input
\inherits Item
\brief Displays an editable line of text
- The TextInput element displays a single line of editable plain text.
+ The TextInput type displays a single line of editable plain text.
TextInput is used to accept a line of text input. Input constraints
can be placed on a TextInput item (for example, through a \l validator or \l inputMask),
d->internalSetText(s, -1, false);
}
+
+/*!
+ \qmlproperty enumeration QtQuick2::TextInput::renderType
+
+ Override the default rendering type for this component.
+
+ Supported render types are:
+ \list
+ \li Text.QtRendering - the default
+ \li Text.NativeRendering
+ \endlist
+
+ Select Text.NativeRendering if you prefer text to look native on the target platform and do
+ not require advanced features such as transformation of the text. Using such features in
+ combination with the NativeRendering render type will lend poor and sometimes pixelated
+ results.
+*/
+QQuickTextInput::RenderType QQuickTextInput::renderType() const
+{
+ Q_D(const QQuickTextInput);
+ return d->renderType;
+}
+
+void QQuickTextInput::setRenderType(QQuickTextInput::RenderType renderType)
+{
+ Q_D(QQuickTextInput);
+ if (d->renderType == renderType)
+ return;
+
+ d->renderType = renderType;
+ emit renderTypeChanged();
+
+ if (isComponentComplete())
+ d->updateLayout();
+}
+
/*!
\qmlproperty int QtQuick2::TextInput::length
forward keys to it and you desire it to look active when this happens
(but without actually giving it active focus).
- It should not be set directly on the element, like in the below QML,
+ It should not be set directly on the item, like in the below QML,
as the specified value will be overridden an lost on focus changes.
\code
/*!
\qmlclass IntValidator QIntValidator
\inqmlmodule QtQuick 2
- \ingroup qml-basic-visual-elements
+ \ingroup qtquick-text-utility
\brief Defines a validator for integer values
- This element provides a validator for integer values.
+ The IntValidator type provides a validator for integer values.
If no \l locale is set IntValidator uses the \l {QLocale::setDefault()}{default locale} to
interpret the number and will accept locale specific digits, group separators, and positive
/*!
\qmlclass DoubleValidator QDoubleValidator
\inqmlmodule QtQuick 2
- \ingroup qml-basic-visual-elements
+ \ingroup qtquick-text-utility
\brief Defines a validator for non-integer numbers
- This element provides a validator for non-integer numbers.
+ The DoubleValidator type provides a validator for non-integer numbers.
Input is accepted if it contains a double that is within the valid range
and is in the correct format.
/*!
\qmlclass RegExpValidator QRegExpValidator
\inqmlmodule QtQuick 2
- \ingroup qml-basic-visual-elements
+ \ingroup qtquick-text-utility
\brief Provides a string validator
- This element provides a validator, which counts as valid any string which
+ The RegExpValidator type provides a validator, which counts as valid any string which
matches a specified regular expression.
*/
/*!
if (d->m_validator == v)
return;
+ if (d->m_validator) {
+ qmlobject_disconnect(
+ d->m_validator, QValidator, SIGNAL(changed()),
+ this, QQuickTextInput, SLOT(q_validatorChanged()));
+ }
+
d->m_validator = v;
+ if (d->m_validator) {
+ qmlobject_connect(
+ d->m_validator, QValidator, SIGNAL(changed()),
+ this, QQuickTextInput, SLOT(q_validatorChanged()));
+ }
+
if (isComponentComplete())
d->checkIsValid();
emit validatorChanged();
}
+void QQuickTextInput::q_validatorChanged()
+{
+ Q_D(QQuickTextInput);
+ d->checkIsValid();
+}
+
#endif // QT_NO_VALIDATOR
void QQuickTextInputPrivate::checkIsValid()
forceActiveFocus();
// re-open input panel on press if already focused
if (hasActiveFocus() && hadActiveFocus && !d->m_readOnly)
- openSoftwareInputPanel();
+ qGuiApp->inputMethod()->show();
}
event->setAccepted(true);
{
Q_D(QQuickTextInput);
if (!d->inLayout) {
- if (newGeometry.width() != oldGeometry.width() && d->wrapMode != NoWrap)
+ if (newGeometry.width() != oldGeometry.width())
d->updateLayout();
updateCursorRectangle();
}
if (!autoScroll || heightUsed <= height) {
// text fits in br; use vscroll for alignment
- switch (vAlign & ~(Qt::AlignAbsolute|Qt::AlignHorizontal_Mask)) {
- case Qt::AlignBottom:
- vscroll = heightUsed - height;
- break;
- case Qt::AlignVCenter:
- vscroll = (heightUsed - height) / 2;
- break;
- default:
- // Top
- vscroll = 0;
- break;
- }
+ vscroll = -QQuickTextUtil::alignedY(
+ heightUsed, height, vAlign & ~(Qt::AlignAbsolute|Qt::AlignHorizontal_Mask));
} else {
QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + preeditLength);
QRectF r = currentLine.isValid() ? currentLine.rect() : QRectF();
if (cursorNode != 0 && !isReadOnly()) {
cursorNode->setRect(cursorRectangle());
- if (!d->cursorVisible || (!d->m_blinkStatus && d->m_blinkPeriod > 0)) {
+ if (!d->cursorVisible || d->cursorItem || (!d->m_blinkStatus && d->m_blinkPeriod > 0)) {
d->hideCursor();
} else {
d->showCursor();
}
}
} else {
+ node->setUseNativeRenderer(d->renderType == QQuickTextInput::NativeRendering);
node->deleteContent();
node->setMatrix(QMatrix4x4());
}
/*!
- \qmlproperty enum QtQuick2::TextInput::mouseSelectionMode
+ \qmlproperty enumeration QtQuick2::TextInput::mouseSelectionMode
Specifies how text should be selected using a mouse.
}
}
-/*!
- \qmlmethod void QtQuick2::TextInput::openSoftwareInputPanel()
-
- Opens software input panels like virtual keyboards for typing, useful for
- customizing when you want the input keyboard to be shown and hidden in
- your application.
-
- By default the opening of input panels follows the platform style. Input panels are
- always closed if no editor has active focus.
-
- You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
- and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
- the behavior you want.
-
- Only relevant on platforms, which provide virtual keyboards.
-
- \qml
- import QtQuick 2.0
- TextInput {
- id: textInput
- text: "Hello world!"
- activeFocusOnPress: false
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (!textInput.activeFocus) {
- textInput.forceActiveFocus()
- textInput.openSoftwareInputPanel();
- } else {
- textInput.focus = false;
- }
- }
- onPressAndHold: textInput.closeSoftwareInputPanel();
- }
- }
- \endqml
-*/
-void QQuickTextInput::openSoftwareInputPanel()
-{
- if (qGuiApp)
- qGuiApp->inputMethod()->show();
-}
-
-/*!
- \qmlmethod void QtQuick2::TextInput::closeSoftwareInputPanel()
-
- Closes a software input panel like a virtual keyboard shown on the screen, useful
- for customizing when you want the input keyboard to be shown and hidden in
- your application.
-
- By default the opening of input panels follows the platform style. Input panels are
- always closed if no editor has active focus.
-
- You can disable the automatic behavior by setting the property \c activeFocusOnPress to false
- and use functions openSoftwareInputPanel() and closeSoftwareInputPanel() to implement
- the behavior you want.
-
- Only relevant on platforms, which provide virtual keyboards.
-
- \qml
- import QtQuick 2.0
- TextInput {
- id: textInput
- text: "Hello world!"
- activeFocusOnPress: false
- MouseArea {
- anchors.fill: parent
- onClicked: {
- if (!textInput.activeFocus) {
- textInput.forceActiveFocus();
- textInput.openSoftwareInputPanel();
- } else {
- textInput.focus = false;
- }
- }
- onPressAndHold: textInput.closeSoftwareInputPanel();
- }
- }
- \endqml
-*/
-void QQuickTextInput::closeSoftwareInputPanel()
-{
- if (qGuiApp)
- qGuiApp->inputMethod()->hide();
-}
-
void QQuickTextInput::focusInEvent(QFocusEvent *event)
{
Q_D(const QQuickTextInput);
if (d->focusOnPress && !d->m_readOnly)
- openSoftwareInputPanel();
+ qGuiApp->inputMethod()->show();
QQuickImplicitSizeItem::focusInEvent(event);
}
Q_D(QQuickTextInput);
if (change == ItemActiveFocusHasChanged) {
bool hasFocus = value.boolValue;
- setCursorVisible(hasFocus); // ### refactor: && d->canvas && d->canvas->hasFocus()
+ setCursorVisible(hasFocus);
if (!hasFocus && (d->m_passwordEchoEditing || d->m_passwordEchoTimer.isActive())) {
d->updatePasswordEchoEditing(false);//QQuickTextInputPrivate sets it on key events, but doesn't deal with focus events
}
if (!qmlDisableDistanceField()) {
QTextOption option = m_textLayout.textOption();
- option.setUseDesignMetrics(true);
+ option.setUseDesignMetrics(renderType != QQuickTextInput::NativeRendering);
m_textLayout.setTextOption(option);
}
}
int cursorWidth = d->cursorItem ? 0 : 1;
qreal hscroll = d->hscroll;
- if (!d->autoScroll || d->contentSize.width() < width()) {
- switch (effectiveHAlign()) {
- case AlignLeft:
- break;
- case AlignRight:
- hscroll += d->contentSize.width() - width();
- break;
- case AlignHCenter:
- hscroll += (d->contentSize.width() - width()) / 2;
- break;
- }
- }
+ if (!d->autoScroll || d->contentSize.width() < width())
+ hscroll -= QQuickTextUtil::alignedX(d->contentSize.width(), width(), effectiveHAlign());
// Could include font max left/right bearings to either side of rectangle.
QRectF r(-hscroll, -d->vscroll, d->contentSize.width(), d->contentSize.height());
m_textLayout.setAdditionalFormats(formats);
updateDisplayText(/*force*/ true);
- if (cursorPositionChanged) {
- emitCursorPositionChanged();
- } else if (m_preeditCursor != oldPreeditCursor || isGettingInput) {
+ if ((cursorPositionChanged && !emitCursorPositionChanged())
+ || m_preeditCursor != oldPreeditCursor
+ || isGettingInput) {
q->updateCursorRectangle();
}