aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorAndrew den Exter <andrew.den-exter@nokia.com>2012-06-19 11:30:59 +1000
committerQt by Nokia <qt-info@nokia.com>2012-06-25 08:57:36 +0200
commit3ae9c8c36097abffd73e29cea1b897ca7d704916 (patch)
tree0657805f357206636bd37b9b95e6d4557ce6473c /src
parent31ba131f9b166ef857f8559a23429d99609e6669 (diff)
Fix clicking on links in aligned or elided Text.
Adjust the mouse position to compensate for any alignment offsets and test the elided text layout for anchors if none is found in the normal layout. Change-Id: Idfda3f7e372d0f2d6c1b7bb5f22d7015d52e8239 Reviewed-by: Yann Bodson <yann.bodson@nokia.com>
Diffstat (limited to 'src')
-rw-r--r--src/quick/items/qquicktext.cpp108
-rw-r--r--src/quick/items/qquicktext_p_p.h3
-rw-r--r--src/quick/items/qquicktextutil.cpp33
-rw-r--r--src/quick/items/qquicktextutil_p.h4
4 files changed, 84 insertions, 64 deletions
diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp
index f03afd657a..b19b13fec2 100644
--- a/src/quick/items/qquicktext.cpp
+++ b/src/quick/items/qquicktext.cpp
@@ -47,6 +47,8 @@
#include <private/qsgadaptationlayer_p.h>
#include "qquicktextnode_p.h"
#include "qquickimage_p_p.h"
+#include "qquicktextutil_p.h"
+
#include <QtQuick/private/qsgtexture_p.h>
#include <QtQml/qqmlinfo.h>
@@ -2011,36 +2013,13 @@ QRectF QQuickText::boundingRect() const
Q_D(const QQuickText);
QRectF rect = d->layedOutTextRect;
+ rect.moveLeft(QQuickTextUtil::alignedX(rect, width(), d->hAlign));
+ rect.moveTop(QQuickTextUtil::alignedY(rect, height(), d->vAlign));
+
if (d->style != Normal)
rect.adjust(-1, 0, 1, 2);
-
// Could include font max left/right bearings to either side of rectangle.
- qreal w = width();
- switch (d->hAlign) {
- case AlignLeft:
- case AlignJustify:
- break;
- case AlignRight:
- rect.moveLeft(w - rect.width());
- break;
- case AlignHCenter:
- rect.moveLeft((w - rect.width()) / 2);
- break;
- }
-
- qreal h = height();
- switch (d->vAlign) {
- case AlignTop:
- break;
- case AlignBottom:
- rect.moveTop(h - rect.height());
- break;
- case AlignVCenter:
- rect.moveTop((h - rect.height()) / 2);
- break;
- }
-
return rect;
}
@@ -2131,7 +2110,7 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
d->updateType = QQuickTextPrivate::UpdateNone;
- QRectF bounds = boundingRect();
+ const qreal dy = QQuickTextUtil::alignedY(d->layedOutTextRect, height(), d->vAlign);
// We need to make sure the layout is done in the current thread
#if defined(Q_OS_MAC)
@@ -2156,27 +2135,28 @@ QSGNode *QQuickText::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data
if (d->richText) {
d->ensureDoc();
- node->addTextDocument(bounds.topLeft(), d->extra->doc, color, d->style, styleColor, linkColor);
- } else if (d->elideMode == QQuickText::ElideNone || bounds.width() > 0.) {
+ const qreal dx = QQuickTextUtil::alignedX(d->layedOutTextRect, width(), d->hAlign);
+ node->addTextDocument(QPointF(dx, dy), d->extra->doc, color, d->style, styleColor, linkColor);
+ } else if (d->elideMode == QQuickText::ElideNone || d->layedOutTextRect.width() > 0.) {
int unelidedLineCount = d->lineCount;
if (d->elideLayout)
unelidedLineCount -= 1;
if (unelidedLineCount > 0) {
node->addTextLayout(
- QPoint(0, bounds.y()),
+ QPoint(0, dy),
&d->layout,
color, d->style, styleColor, linkColor,
QColor(), QColor(), -1, -1,
0, unelidedLineCount);
}
if (d->elideLayout)
- node->addTextLayout(QPoint(0, bounds.y()), d->elideLayout, color, d->style, styleColor, linkColor);
+ node->addTextLayout(QPoint(0, dy), d->elideLayout, color, d->style, styleColor, linkColor);
}
foreach (QQuickStyledTextImgTag *img, d->visibleImgTags) {
QQuickPixmap *pix = img->pix;
if (pix && pix->isReady())
- node->addImage(QRectF(img->pos.x(), img->pos.y() + bounds.y(), pix->width(), pix->height()), pix->image());
+ node->addImage(QRectF(img->pos.x(), img->pos.y() + dy, pix->width(), pix->height()), pix->image());
}
return node;
}
@@ -2397,28 +2377,42 @@ void QQuickText::componentComplete()
d->updateLayout();
}
-
-QString QQuickTextPrivate::anchorAt(const QPointF &mousePos)
+QString QQuickTextPrivate::anchorAt(const QTextLayout *layout, const QPointF &mousePos)
{
- if (styledText) {
- for (int i = 0; i < layout.lineCount(); ++i) {
- QTextLine line = layout.lineAt(i);
- if (line.naturalTextRect().contains(mousePos)) {
- int charPos = line.xToCursor(mousePos.x());
- foreach (const QTextLayout::FormatRange &formatRange, layout.additionalFormats()) {
- if (formatRange.format.isAnchor()
- && charPos >= formatRange.start
- && charPos <= formatRange.start + formatRange.length) {
- return formatRange.format.anchorHref();
- }
+ for (int i = 0; i < layout->lineCount(); ++i) {
+ QTextLine line = layout->lineAt(i);
+ if (line.naturalTextRect().contains(mousePos)) {
+ int charPos = line.xToCursor(mousePos.x(), QTextLine::CursorOnCharacter);
+ foreach (const QTextLayout::FormatRange &formatRange, layout->additionalFormats()) {
+ if (formatRange.format.isAnchor()
+ && charPos >= formatRange.start
+ && charPos < formatRange.start + formatRange.length) {
+ return formatRange.format.anchorHref();
}
- break;
}
+ break;
}
}
return QString();
}
+QString QQuickTextPrivate::anchorAt(const QPointF &mousePos) const
+{
+ Q_Q(const QQuickText);
+ QPointF translatedMousePos = mousePos;
+ translatedMousePos.ry() -= QQuickTextUtil::alignedY(layedOutTextRect, q->height(), vAlign);
+ if (styledText) {
+ QString link = anchorAt(&layout, translatedMousePos);
+ if (link.isEmpty() && elideLayout)
+ link = anchorAt(elideLayout, translatedMousePos);
+ return link;
+ } else if (richText && extra.isAllocated() && extra->doc) {
+ translatedMousePos.rx() -= QQuickTextUtil::alignedX(layedOutTextRect, q->width(), hAlign);
+ return extra->doc->documentLayout()->anchorAt(translatedMousePos);
+ }
+ return QString();
+}
+
bool QQuickTextPrivate::isLinkActivatedConnected()
{
Q_Q(QQuickText);
@@ -2431,14 +2425,8 @@ void QQuickText::mousePressEvent(QMouseEvent *event)
Q_D(QQuickText);
QString link;
- if (d->isLinkActivatedConnected()) {
- if (d->styledText)
- link = d->anchorAt(event->localPos());
- else if (d->richText) {
- d->ensureDoc();
- link = d->extra->doc->documentLayout()->anchorAt(event->localPos());
- }
- }
+ if (d->isLinkActivatedConnected())
+ link = d->anchorAt(event->localPos());
if (link.isEmpty()) {
event->setAccepted(false);
@@ -2450,9 +2438,9 @@ void QQuickText::mousePressEvent(QMouseEvent *event)
if (!event->isAccepted())
QQuickItem::mousePressEvent(event);
-
}
+
/*! \internal */
void QQuickText::mouseReleaseEvent(QMouseEvent *event)
{
@@ -2461,14 +2449,8 @@ void QQuickText::mouseReleaseEvent(QMouseEvent *event)
// ### confirm the link, and send a signal out
QString link;
- if (d->isLinkActivatedConnected()) {
- if (d->styledText)
- link = d->anchorAt(event->localPos());
- else if (d->richText) {
- d->ensureDoc();
- link = d->extra->doc->documentLayout()->anchorAt(event->localPos());
- }
- }
+ if (d->isLinkActivatedConnected())
+ link = d->anchorAt(event->localPos());
if (!link.isEmpty() && d->extra.isAllocated() && d->extra->activeLink == link)
emit linkActivated(d->extra->activeLink);
diff --git a/src/quick/items/qquicktext_p_p.h b/src/quick/items/qquicktext_p_p.h
index 2afcd8f369..985b1e1c80 100644
--- a/src/quick/items/qquicktext_p_p.h
+++ b/src/quick/items/qquicktext_p_p.h
@@ -166,7 +166,8 @@ public:
QRectF setupTextLayout(qreal *const naturalWidth, qreal * const baseline);
void setupCustomLineGeometry(QTextLine &line, qreal &height, int lineOffset = 0);
bool isLinkActivatedConnected();
- QString anchorAt(const QPointF &pos);
+ static QString anchorAt(const QTextLayout *layout, const QPointF &mousePos);
+ QString anchorAt(const QPointF &pos) const;
inline qreal lineHeight() const { return extra.isAllocated() ? extra->lineHeight : 1.0; }
inline int maximumLineCount() const { return extra.isAllocated() ? extra->maximumLineCount : INT_MAX; }
diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp
index c2c11b3daa..176301d450 100644
--- a/src/quick/items/qquicktextutil.cpp
+++ b/src/quick/items/qquicktextutil.cpp
@@ -78,4 +78,37 @@ QQuickItem *QQuickTextUtil::createCursor(
return item;
}
+qreal QQuickTextUtil::alignedX(const QRectF &rect, qreal width, int alignment)
+{
+ qreal x = 0;
+ switch (alignment) {
+ case Qt::AlignLeft:
+ case Qt::AlignJustify:
+ break;
+ case Qt::AlignRight:
+ x = width - rect.width();
+ break;
+ case Qt::AlignHCenter:
+ x = (width - rect.width()) / 2;
+ break;
+ }
+ return x;
+}
+
+qreal QQuickTextUtil::alignedY(const QRectF &rect, const qreal height, int alignment)
+{
+ qreal y = 0;
+ switch (alignment) {
+ case Qt::AlignTop:
+ break;
+ case Qt::AlignBottom:
+ y = height - rect.height();
+ break;
+ case Qt::AlignVCenter:
+ y = (height - rect.height()) / 2;
+ break;
+ }
+ return y;
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquicktextutil_p.h b/src/quick/items/qquicktextutil_p.h
index 91ef40b221..d6c05aac3b 100644
--- a/src/quick/items/qquicktextutil_p.h
+++ b/src/quick/items/qquicktextutil_p.h
@@ -66,12 +66,16 @@ public:
template <typename Private> static void setCursorDelegate(Private *d, QQmlComponent *delegate);
template <typename Private> static void createCursor(Private *d);
+ static qreal alignedX(const QRectF &rect, qreal width, int alignment);
+ static qreal alignedY(const QRectF &rect, qreal height, int alignment);
+
private:
static QQuickItem *createCursor(
QQmlComponent *component,
QQuickItem *parent,
const QRectF &cursorRectangle,
const char *className);
+
};
template <typename Private>