Skip to content

Commit

Permalink
Fix vertical offset of TextInput.positionToRectangle.
Browse files Browse the repository at this point in the history
Offset the y value of the rectangle by the vertical scroll and line
offset.

Task-number: QTBUG-23934
Change-Id: I43815b480f43a089a9a03b0aec32dfc0598b6154
Reviewed-by: Martin Jones <martin.jones@nokia.com>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Feb 6, 2012
1 parent 5260a56 commit 4cd28a7
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 4 deletions.
8 changes: 5 additions & 3 deletions src/quick/items/qquicktextinput.cpp
Expand Up @@ -1299,11 +1299,13 @@ void QQuickTextInput::createCursor()
QRectF QQuickTextInput::positionToRectangle(int pos) const
{
Q_D(const QQuickTextInput);
if (pos > d->m_cursor)
if (d->m_echoMode == NoEcho)
pos = 0;
else if (pos > d->m_cursor)
pos += d->preeditAreaText().length();
QTextLine l = d->m_textLayout.lineAt(0);
QTextLine l = d->m_textLayout.lineForTextPosition(pos);
return l.isValid()
? QRectF(l.cursorToX(pos) - d->hscroll, 0.0, d->m_cursorWidth, l.height())
? QRectF(l.cursorToX(pos) - d->hscroll, l.y() - d->vscroll, d->m_cursorWidth, l.height())
: QRectF();
}

Expand Down
54 changes: 53 additions & 1 deletion tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
Expand Up @@ -1411,17 +1411,25 @@ void tst_qquicktextinput::verticalAlignment()

QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignTop);
QVERIFY(textInputPrivate->boundingRect.bottom() - textInputPrivate->vscroll < canvas.height() / 2);
QVERIFY(textInput->cursorRectangle().bottom() < canvas.height() / 2);
QVERIFY(textInput->positionToRectangle(0).bottom() < canvas.height() / 2);

// bottom aligned
textInput->setVAlign(QQuickTextInput::AlignBottom);
QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignBottom);
QVERIFY(textInputPrivate->boundingRect.top() - textInputPrivate->vscroll > canvas.height() / 2);
QVERIFY(textInput->cursorRectangle().top() > canvas.height() / 2);
QVERIFY(textInput->positionToRectangle(0).top() > canvas.height() / 2);

// explicitly center aligned
textInput->setVAlign(QQuickTextInput::AlignVCenter);
QCOMPARE(textInput->vAlign(), QQuickTextInput::AlignVCenter);
QVERIFY(textInputPrivate->boundingRect.top() - textInputPrivate->vscroll < canvas.height() / 2);
QVERIFY(textInputPrivate->boundingRect.bottom() - textInputPrivate->vscroll > canvas.height() / 2);
QVERIFY(textInput->cursorRectangle().top() < canvas.height() / 2);
QVERIFY(textInput->cursorRectangle().bottom() > canvas.height() / 2);
QVERIFY(textInput->positionToRectangle(0).top() < canvas.height() / 2);
QVERIFY(textInput->positionToRectangle(0).bottom() > canvas.height() / 2);
}

void tst_qquicktextinput::boundingRect()
Expand Down Expand Up @@ -2374,6 +2382,9 @@ void tst_qquicktextinput::cursorVisible()
QCOMPARE(spy.count(), 7);
}

static QRect round(const QRectF &r) {
return QRect(qRound(r.left()), qRound(r.top()), qCeil(r.width()), qCeil(r.height())); }

void tst_qquicktextinput::cursorRectangle()
{

Expand Down Expand Up @@ -2413,6 +2424,7 @@ void tst_qquicktextinput::cursorRectangle()
QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing)));
QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading)));
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

// Check the cursor rectangle remains within the input bounding rect when auto scrolling.
Expand All @@ -2423,6 +2435,7 @@ void tst_qquicktextinput::cursorRectangle()
input.setCursorPosition(i);
QCOMPARE(r, input.cursorRectangle());
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

for (int i = text.length() - 2; i >= 0; --i) {
Expand All @@ -2431,10 +2444,40 @@ void tst_qquicktextinput::cursorRectangle()
QCOMPARE(r.top(), 0);
QVERIFY(r.right() >= 0);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

// Check vertical scrolling with word wrap.
// Check position with word wrap.
input.setWrapMode(QQuickTextInput::WordWrap);
input.setAutoScroll(false);
for (int i = 0; i <= 5; ++i) {
input.setCursorPosition(i);
r = input.cursorRectangle();

QVERIFY(r.left() < qCeil(line.cursorToX(i, QTextLine::Trailing)));
QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading)));
QCOMPARE(r.top(), 0);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

input.setCursorPosition(6);
r = input.cursorRectangle();
QCOMPARE(r.left(), 0);
QVERIFY(r.top() > line.height() - error);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(6)), r);

for (int i = 7; i < text.length(); ++i) {
input.setCursorPosition(i);
r = input.cursorRectangle();
QVERIFY(r.top() > line.height() - error);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

// Check vertical scrolling with word wrap.
input.setAutoScroll(true);
for (int i = 0; i <= 5; ++i) {
input.setCursorPosition(i);
r = input.cursorRectangle();
Expand All @@ -2443,29 +2486,38 @@ void tst_qquicktextinput::cursorRectangle()
QVERIFY(r.right() >= qFloor(line.cursorToX(i , QTextLine::Leading)));
QCOMPARE(r.top(), 0);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(round(input.positionToRectangle(i))), r);
}

input.setCursorPosition(6);
r = input.cursorRectangle();
QCOMPARE(r.left(), 0);
QVERIFY(r.bottom() >= input.height() - error);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(6)), r);

for (int i = 7; i < text.length(); ++i) {
input.setCursorPosition(i);
r = input.cursorRectangle();
QVERIFY(r.bottom() >= input.height() - error);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

for (int i = text.length() - 2; i >= 6; --i) {
input.setCursorPosition(i);
r = input.cursorRectangle();
QVERIFY(r.bottom() >= input.height() - error);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

for (int i = 5; i >= 0; --i) {
input.setCursorPosition(i);
r = input.cursorRectangle();
QCOMPARE(r.top(), 0);
QCOMPARE(input.inputMethodQuery(Qt::ImCursorRectangle).toRect(), r);
QCOMPARE(round(input.positionToRectangle(i)), r);
}

input.setText("Hi!");
Expand Down

0 comments on commit 4cd28a7

Please sign in to comment.