Whether the TextInput should scroll when the text is longer than the width. By default this is
set to true.
+
+ \sa ensureVisible()
*/
bool QQuickTextInput::autoScroll() const
{
QQuickImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
}
-void QQuickTextInputPrivate::updateHorizontalScroll()
+void QQuickTextInputPrivate::ensureVisible(int position, int preeditCursor, int preeditLength)
{
Q_Q(QQuickTextInput);
-#ifndef QT_NO_IM
- QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor + m_preeditCursor);
- const int preeditLength = m_textLayout.preeditAreaText().length();
-#else
- QTextLine currentLine = m_textLayout.lineForTextPosition(m_cursor);
-#endif
+ QTextLine textLine = m_textLayout.lineForTextPosition(position + preeditCursor);
const qreal width = qMax<qreal>(0, q->width());
qreal cix = 0;
qreal widthUsed = 0;
- if (currentLine.isValid()) {
-#ifndef QT_NO_IM
- cix = currentLine.cursorToX(m_cursor + preeditLength);
-#else
- cix = currentLine.cursorToX(m_cursor);
-#endif
+ if (textLine.isValid()) {
+ cix = textLine.cursorToX(position + preeditLength);
const qreal cursorWidth = cix >= 0 ? cix : width - cix;
- widthUsed = qMax(currentLine.naturalTextWidth(), cursorWidth);
+ widthUsed = qMax(textLine.naturalTextWidth(), cursorWidth);
}
int previousScroll = hscroll;
- if (!autoScroll || widthUsed <= width || m_echoMode == QQuickTextInput::NoEcho) {
+ if (widthUsed <= width) {
hscroll = 0;
} else {
- Q_ASSERT(currentLine.isValid());
+ Q_ASSERT(textLine.isValid());
if (cix - hscroll >= width) {
// text doesn't fit, cursor is to the right of br (scroll right)
hscroll = cix - width;
if (preeditLength > 0) {
// check to ensure long pre-edit text doesn't push the cursor
// off to the left
- cix = currentLine.cursorToX(m_cursor + qMax(0, m_preeditCursor - 1));
+ cix = textLine.cursorToX(position + qMax(0, preeditCursor - 1));
if (cix < hscroll)
hscroll = cix;
}
textLayoutDirty = true;
}
+void QQuickTextInputPrivate::updateHorizontalScroll()
+{
+ if (autoScroll && m_echoMode != QQuickTextInput::NoEcho) {
+#ifndef QT_NO_IM
+ const int preeditLength = m_textLayout.preeditAreaText().length();
+ ensureVisible(m_cursor, m_preeditCursor, preeditLength);
+#else
+ ensureVisible(m_cursor);
+#endif
+ } else {
+ hscroll = 0;
+ }
+}
+
void QQuickTextInputPrivate::updateVerticalScroll()
{
Q_Q(QQuickTextInput);
}
}
-void QQuickTextInput::updateCursorRectangle()
+void QQuickTextInput::updateCursorRectangle(bool scroll)
{
Q_D(QQuickTextInput);
if (!isComponentComplete())
return;
- d->updateHorizontalScroll();
- d->updateVerticalScroll();
+ if (scroll) {
+ d->updateHorizontalScroll();
+ d->updateVerticalScroll();
+ }
d->updateType = QQuickTextInputPrivate::UpdatePaintNode;
update();
emit cursorRectangleChanged();
finishChange(priorState);
}
+/*!
+ \qmlmethod QtQuick::TextInput::ensureVisible(int position)
+ \since 5.4
+
+ Scrolls the contents of the text input so that the specified character
+ \a position is visible inside the boundaries of the text input.
+
+ \sa autoScroll
+*/
+void QQuickTextInput::ensureVisible(int position)
+{
+ Q_D(QQuickTextInput);
+ d->ensureVisible(position);
+ updateCursorRectangle(false);
+}
+
QT_END_NAMESPACE
void baselineOffset_data();
void baselineOffset();
+ void ensureVisible();
+
private:
void simulateKey(QWindow *, int key);
}
}
+void tst_qquicktextinput::ensureVisible()
+{
+ QQmlComponent component(&engine);
+ component.setData("import QtQuick 2.0\n TextInput {}", QUrl());
+ QScopedPointer<QObject> object(component.create());
+ QQuickTextInput *input = qobject_cast<QQuickTextInput *>(object.data());
+ QVERIFY(input);
+
+ input->setWidth(QFontMetrics(input->font()).averageCharWidth() * 3);
+ input->setText("Hello World");
+
+ QTextLayout layout;
+ layout.setText(input->text());
+ layout.setFont(input->font());
+
+ if (!qmlDisableDistanceField()) {
+ QTextOption option;
+ option.setUseDesignMetrics(true);
+ layout.setTextOption(option);
+ }
+ layout.beginLayout();
+ QTextLine line = layout.createLine();
+ layout.endLayout();
+
+ input->ensureVisible(0);
+
+ QCOMPARE(input->boundingRect().x(), qreal(0));
+ QCOMPARE(input->boundingRect().y(), qreal(0));
+ QCOMPARE(input->boundingRect().width(), line.naturalTextWidth() + input->cursorRectangle().width());
+ QCOMPARE(input->boundingRect().height(), line.height());
+
+ QSignalSpy cursorSpy(input, SIGNAL(cursorRectangleChanged()));
+ QVERIFY(cursorSpy.isValid());
+
+ input->ensureVisible(input->length());
+
+ QCOMPARE(cursorSpy.count(), 1);
+
+ QCOMPARE(input->boundingRect().x(), input->width() - line.naturalTextWidth());
+ QCOMPARE(input->boundingRect().y(), qreal(0));
+ QCOMPARE(input->boundingRect().width(), line.naturalTextWidth() + input->cursorRectangle().width());
+ QCOMPARE(input->boundingRect().height(), line.height());
+}
+
QTEST_MAIN(tst_qquicktextinput)
#include "tst_qquicktextinput.moc"