Skip to content

Commit

Permalink
Fix clipping of TextInput contents.
Browse files Browse the repository at this point in the history
The boundingRect represents the clip rectangle of an item rather than
the size and position of its unclipped content.  This would prevent any
content from being clipped except the boundingRect is only re-evaluated
when the size of the item changes so the content is instead clipped to
the size of the original content.

Task-number: QTBUG-23422
Change-Id: I96f830f833129b3230f65452db67b00028c40d6a
Reviewed-by: Martin Jones <martin.jones@nokia.com>
  • Loading branch information
Andrew den Exter authored and Qt by Nokia committed Jan 4, 2012
1 parent f9c10b5 commit 8280351
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
4 changes: 1 addition & 3 deletions src/quick/items/qquicktextinput.cpp
Expand Up @@ -2307,13 +2307,11 @@ QRectF QQuickTextInput::boundingRect() const
{
Q_D(const QQuickTextInput);

QRectF r = d->boundingRect;
int cursorWidth = d->cursorItem ? d->cursorItem->width() : d->m_cursorWidth;

// Could include font max left/right bearings to either side of rectangle.

QRectF r = QQuickImplicitSizeItem::boundingRect();
r.setRight(r.right() + cursorWidth);
r.translate(-d->hscroll, -d->vscroll);
return r;
}

Expand Down
68 changes: 52 additions & 16 deletions tests/auto/qtquick2/qquicktextinput/tst_qquicktextinput.cpp
Expand Up @@ -125,6 +125,8 @@ private slots:
void horizontalAlignment_RightToLeft();
void verticalAlignment();

void boundingRect();

void positionAt();

void maxLength();
Expand Down Expand Up @@ -1225,57 +1227,57 @@ void tst_qquicktextinput::horizontalAlignment_RightToLeft()

QQuickTextInputPrivate *textInputPrivate = QQuickTextInputPrivate::get(textInput);
QVERIFY(textInputPrivate != 0);
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() > canvas.width()/2);

// implicit alignment should follow the reading direction of RTL text
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll > canvas.width()/2);

// explicitly left aligned
textInput->setHAlign(QQuickTextInput::AlignLeft);
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
QVERIFY(textInput->boundingRect().left() < canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll < canvas.width()/2);

// explicitly right aligned
textInput->setHAlign(QQuickTextInput::AlignRight);
QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll > canvas.width()/2);

// explicitly center aligned
textInput->setHAlign(QQuickTextInput::AlignHCenter);
QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignHCenter);
QVERIFY(textInput->boundingRect().left() < canvas.width()/2);
QVERIFY(textInput->boundingRect().right() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll < canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.right() - textInputPrivate->hscroll > canvas.width()/2);

// reseted alignment should go back to following the text reading direction
textInput->resetHAlign();
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll > canvas.width()/2);

// mirror the text item
QQuickItemPrivate::get(textInput)->setLayoutMirror(true);

// mirrored implicit alignment should continue to follow the reading direction of the text
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
QCOMPARE(textInput->effectiveHAlign(), textInput->hAlign());
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll > canvas.width()/2);

// explicitly right aligned behaves as left aligned
textInput->setHAlign(QQuickTextInput::AlignRight);
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignLeft);
QVERIFY(textInput->boundingRect().left() < canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll < canvas.width()/2);

// mirrored explicitly left aligned behaves as right aligned
textInput->setHAlign(QQuickTextInput::AlignLeft);
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
QCOMPARE(textInput->effectiveHAlign(), QQuickTextInput::AlignRight);
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll > canvas.width()/2);

// disable mirroring
QQuickItemPrivate::get(textInput)->setLayoutMirror(false);
Expand All @@ -1285,7 +1287,7 @@ void tst_qquicktextinput::horizontalAlignment_RightToLeft()
// English text should be implicitly left aligned
textInput->setText("Hello world!");
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignLeft);
QVERIFY(textInput->boundingRect().left() < canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll < canvas.width()/2);

canvas.requestActivateWindow();
QTest::qWaitForWindowShown(&canvas);
Expand Down Expand Up @@ -1313,7 +1315,7 @@ void tst_qquicktextinput::horizontalAlignment_RightToLeft()
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
textInput->setHAlign(QQuickTextInput::AlignRight);
QCOMPARE(textInput->hAlign(), QQuickTextInput::AlignRight);
QVERIFY(textInput->boundingRect().left() > canvas.width()/2);
QVERIFY(textInputPrivate->boundingRect.left() - textInputPrivate->hscroll > canvas.width()/2);

QString componentStr = "import QtQuick 2.0\nTextInput {}";
QDeclarativeComponent textComponent(&engine);
Expand All @@ -1335,18 +1337,52 @@ void tst_qquicktextinput::verticalAlignment()
QVERIFY(textInputPrivate != 0);

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

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

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

void tst_qquicktextinput::boundingRect()
{
QDeclarativeComponent 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);

QCOMPARE(input->width() + input->cursorRectangle().width(), input->boundingRect().width());
QCOMPARE(input->height(), input->boundingRect().height());

input->setText("Hello World");
QCOMPARE(input->width() + input->cursorRectangle().width(), input->boundingRect().width());
QCOMPARE(input->height(), input->boundingRect().height());

// bounding rect shouldn't exceed the size of the item, expect for the cursor width;
input->setWidth(input->width() / 2);
QCOMPARE(input->width() + input->cursorRectangle().width(), input->boundingRect().width());
QCOMPARE(input->height(), input->boundingRect().height());

input->setHeight(input->height() * 2);
QCOMPARE(input->width() + input->cursorRectangle().width(), input->boundingRect().width());
QCOMPARE(input->height(), input->boundingRect().height());

QDeclarativeComponent cursorComponent(&engine);
cursorComponent.setData("import QtQuick 2.0\nRectangle { height: 20; width: 8 }", QUrl());

input->setCursorDelegate(&cursorComponent);

// If a cursor delegate is used it's size should determine the excess width.
QCOMPARE(input->width() + 8, input->boundingRect().width());
QCOMPARE(input->height(), input->boundingRect().height());
}

void tst_qquicktextinput::positionAt()
Expand Down

0 comments on commit 8280351

Please sign in to comment.