aboutsummaryrefslogtreecommitdiffstats
path: root/src/quick/items
diff options
context:
space:
mode:
authorLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-05-07 13:22:07 +0200
committerLaszlo Agocs <laszlo.agocs@theqtcompany.com>2016-05-07 13:26:27 +0200
commite3716cdf88a09109e368adc4f73fc52ff6325f83 (patch)
treeaae8225ed640befa4a3729e3e11d1e0dd2aaa607 /src/quick/items
parent6b8a0c932eb60a7839f9d8ae7112c79166e1f49b (diff)
parent69b7ba225007d68e113ee425ad58ce7e186a92c2 (diff)
Merge remote-tracking branch 'origin/dev' into wip/scenegraphng
Diffstat (limited to 'src/quick/items')
-rw-r--r--src/quick/items/qquickborderimage.cpp88
-rw-r--r--src/quick/items/qquickborderimage_p_p.h11
-rw-r--r--src/quick/items/qquickitem.cpp1
-rw-r--r--src/quick/items/qquickitemsmodule.cpp1
-rw-r--r--src/quick/items/qquickshadereffectmesh.cpp197
-rw-r--r--src/quick/items/qquickshadereffectmesh_p.h42
-rw-r--r--src/quick/items/qquickspriteengine.cpp2
-rw-r--r--src/quick/items/qquicktextcontrol.cpp19
-rw-r--r--src/quick/items/qquicktextcontrol_p.h1
-rw-r--r--src/quick/items/qquicktextedit.cpp7
-rw-r--r--src/quick/items/qquicktextinput.cpp50
-rw-r--r--src/quick/items/qquicktextinput_p_p.h2
-rw-r--r--src/quick/items/qquickview.cpp3
-rw-r--r--src/quick/items/qquickwindow.cpp4
-rw-r--r--src/quick/items/qquickwindowmodule.cpp10
15 files changed, 386 insertions, 52 deletions
diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp
index 5f8dd7b989..b3a35e6219 100644
--- a/src/quick/items/qquickborderimage.cpp
+++ b/src/quick/items/qquickborderimage.cpp
@@ -574,6 +574,52 @@ void QQuickBorderImage::doUpdate()
update();
}
+void QQuickBorderImagePrivate::calculateRects(const QQuickScaleGrid *border,
+ const QSize &sourceSize,
+ const QSizeF &targetSize,
+ int horizontalTileMode,
+ int verticalTileMode,
+ qreal devicePixelRatio,
+ QRectF *targetRect,
+ QRectF *innerTargetRect,
+ QRectF *innerSourceRect,
+ QRectF *subSourceRect)
+{
+ *innerSourceRect = QRectF(0, 0, 1, 1);
+ *targetRect = QRectF(0, 0, targetSize.width(), targetSize.height());
+ *innerTargetRect = *targetRect;
+
+ if (border) {
+ *innerSourceRect = QRectF(border->left() * devicePixelRatio / qreal(sourceSize.width()),
+ border->top() * devicePixelRatio / qreal(sourceSize.height()),
+ qMax<qreal>(0, sourceSize.width() - (border->right() + border->left()) * devicePixelRatio) / sourceSize.width(),
+ qMax<qreal>(0, sourceSize.height() - (border->bottom() + border->top()) * devicePixelRatio) / sourceSize.height());
+ *innerTargetRect = QRectF(border->left(),
+ border->top(),
+ qMax<qreal>(0, targetSize.width() - (border->right() + border->left())),
+ qMax<qreal>(0, targetSize.height() - (border->bottom() + border->top())));
+ }
+
+ qreal hTiles = 1;
+ qreal vTiles = 1;
+ const QSizeF innerTargetSize = innerTargetRect->size() * devicePixelRatio;
+ if (innerSourceRect->width() != 0
+ && horizontalTileMode != QQuickBorderImage::Stretch) {
+ hTiles = innerTargetSize.width() / qreal(innerSourceRect->width() * sourceSize.width());
+ if (horizontalTileMode == QQuickBorderImage::Round)
+ hTiles = qCeil(hTiles);
+ }
+ if (innerSourceRect->height() != 0
+ && verticalTileMode != QQuickBorderImage::Stretch) {
+ vTiles = innerTargetSize.height() / qreal(innerSourceRect->height() * sourceSize.height());
+ if (verticalTileMode == QQuickBorderImage::Round)
+ vTiles = qCeil(vTiles);
+ }
+
+ *subSourceRect = QRectF(0, 0, hTiles, vTiles);
+}
+
+
QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *)
{
Q_D(QQuickBorderImage);
@@ -598,45 +644,25 @@ QSGNode *QQuickBorderImage::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeDat
node->setTexture(texture);
// Don't implicitly create the scalegrid in the rendering thread...
- QRectF innerSourceRect(0, 0, 1, 1);
- QRectF targetRect(0, 0, width(), height());
- QRectF innerTargetRect = targetRect;
- if (d->border) {
- const QQuickScaleGrid *border = d->getScaleGrid();
- innerSourceRect = QRectF(border->left() * d->devicePixelRatio / qreal(d->pix.width()),
- border->top() * d->devicePixelRatio / qreal(d->pix.height()),
- qMax<qreal>(0, d->pix.width() - (border->right() + border->left()) * d->devicePixelRatio) / d->pix.width(),
- qMax<qreal>(0, d->pix.height() - (border->bottom() + border->top()) * d->devicePixelRatio) / d->pix.height());
- innerTargetRect = QRectF(border->left(),
- border->top(),
- qMax<qreal>(0, width() - (border->right() + border->left())),
- qMax<qreal>(0, height() - (border->bottom() + border->top())));
- }
- qreal hTiles = 1;
- qreal vTiles = 1;
- const QSizeF innerTargetSize = innerTargetRect.size() * d->devicePixelRatio;
- if (innerSourceRect.width() != 0
- && d->horizontalTileMode != QQuickBorderImage::Stretch) {
- hTiles = innerTargetSize.width() / qreal(innerSourceRect.width() * d->pix.width());
- if (d->horizontalTileMode == QQuickBorderImage::Round)
- hTiles = qCeil(hTiles);
- }
- if (innerSourceRect.height() != 0
- && d->verticalTileMode != QQuickBorderImage::Stretch) {
- vTiles = innerTargetSize.height() / qreal(innerSourceRect.height() * d->pix.height());
- if (d->verticalTileMode == QQuickBorderImage::Round)
- vTiles = qCeil(vTiles);
- }
+ QRectF targetRect;
+ QRectF innerTargetRect;
+ QRectF innerSourceRect;
+ QRectF subSourceRect;
+ d->calculateRects(d->border,
+ QSize(d->pix.width(), d->pix.height()), QSizeF(width(), height()),
+ d->horizontalTileMode, d->verticalTileMode, d->devicePixelRatio,
+ &targetRect, &innerTargetRect,
+ &innerSourceRect, &subSourceRect);
node->setTargetRect(targetRect);
node->setInnerSourceRect(innerSourceRect);
node->setInnerTargetRect(innerTargetRect);
- node->setSubSourceRect(QRectF(0, 0, hTiles, vTiles));
+ node->setSubSourceRect(subSourceRect);
node->setMirror(d->mirror);
node->setMipmapFiltering(QSGTexture::None);
node->setFiltering(d->smooth ? QSGTexture::Linear : QSGTexture::Nearest);
- if (innerSourceRect == QRectF(0, 0, 1, 1) && (vTiles > 1 || hTiles > 1)) {
+ if (innerSourceRect == QRectF(0, 0, 1, 1) && (subSourceRect.width() > 1 || subSourceRect.height() > 1)) {
node->setHorizontalWrapMode(QSGTexture::Repeat);
node->setVerticalWrapMode(QSGTexture::Repeat);
} else {
diff --git a/src/quick/items/qquickborderimage_p_p.h b/src/quick/items/qquickborderimage_p_p.h
index 1dc530e34e..56fbbab049 100644
--- a/src/quick/items/qquickborderimage_p_p.h
+++ b/src/quick/items/qquickborderimage_p_p.h
@@ -91,6 +91,17 @@ public:
return border;
}
+ static void calculateRects(const QQuickScaleGrid *border,
+ const QSize &sourceSize,
+ const QSizeF &targetSize,
+ int horizontalTileMode,
+ int verticalTileMode,
+ qreal devicePixelRatio,
+ QRectF *targetRect,
+ QRectF *innerTargetRect,
+ QRectF *innerSourceRect,
+ QRectF *subSourceRect);
+
QQuickScaleGrid *border;
QUrl sciurl;
QQuickBorderImage::TileMode horizontalTileMode;
diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp
index ea2cb5aa5f..1100b12cbc 100644
--- a/src/quick/items/qquickitem.cpp
+++ b/src/quick/items/qquickitem.cpp
@@ -4152,6 +4152,7 @@ QVariant QQuickItem::inputMethodQuery(Qt::InputMethodQuery query) const
v = (bool)(flags() & ItemAcceptsInputMethod);
break;
case Qt::ImHints:
+ case Qt::ImAnchorRectangle:
case Qt::ImCursorRectangle:
case Qt::ImFont:
case Qt::ImCursorPosition:
diff --git a/src/quick/items/qquickitemsmodule.cpp b/src/quick/items/qquickitemsmodule.cpp
index 5f5809b6f2..fb5bc3683f 100644
--- a/src/quick/items/qquickitemsmodule.cpp
+++ b/src/quick/items/qquickitemsmodule.cpp
@@ -297,6 +297,7 @@ static void qt_quickitems_defineModule(const char *uri, int major, int minor)
qmlRegisterType<QQuickShaderEffect, 2>(uri, 2, 8, "ShaderEffect");
qmlRegisterUncreatableType<QQuickRendererInfo>(uri, 2, 8,"RendererInfo", QQuickRendererInfo::tr("RendererInfo is only available via attached properties"));
+ qmlRegisterType<QQuickBorderImageMesh>("QtQuick", 2, 8, "BorderImageMesh");
}
static void initResources()
diff --git a/src/quick/items/qquickshadereffectmesh.cpp b/src/quick/items/qquickshadereffectmesh.cpp
index d7765cdc69..f5cc19c877 100644
--- a/src/quick/items/qquickshadereffectmesh.cpp
+++ b/src/quick/items/qquickshadereffectmesh.cpp
@@ -39,6 +39,10 @@
#include "qquickshadereffectmesh_p.h"
#include <QtQuick/qsggeometry.h>
+#include "qquickshadereffect_p.h"
+#include "qquickscalegrid_p_p.h"
+#include "qquickborderimage_p_p.h"
+#include <QtQuick/private/qsgbasicimagenode_p.h>
QT_BEGIN_NAMESPACE
@@ -239,4 +243,197 @@ QSize QQuickGridMesh::resolution() const
return m_resolution;
}
+/*!
+ \qmltype BorderImageMesh
+ \instantiates QQuickBorderImageMesh
+ \inqmlmodule QtQuick
+ \since 5.8
+ \ingroup qtquick-effects
+ \brief Defines a mesh with vertices arranged like those of a BorderImage.
+
+ BorderImageMesh provides BorderImage-like capabilities to a ShaderEffect
+ without the need for a potentially costly ShaderEffectSource.
+
+ The following are functionally equivalent:
+ \qml
+ BorderImage {
+ id: borderImage
+ border {
+ left: 10
+ right: 10
+ top: 10
+ bottom: 10
+ }
+ source: "myImage.png"
+ visible: false
+ }
+ ShaderEffectSource {
+ id: effectSource
+ sourceItem: borderImage
+ visible: false
+ }
+ ShaderEffect {
+ property var source: effectSource
+ ...
+ }
+ \endqml
+
+ \qml
+ Image {
+ id: image
+ source: "myImage.png"
+ visible: false
+ }
+ ShaderEffect {
+ property var source: image
+ mesh: BorderImageMesh {
+ border {
+ left: 10
+ right: 10
+ top: 10
+ bottom: 10
+ }
+ size: image.sourceSize
+ }
+ ...
+ }
+ \endqml
+
+ But the BorderImageMesh version can typically be better optimized.
+*/
+QQuickBorderImageMesh::QQuickBorderImageMesh(QObject *parent)
+ : QQuickShaderEffectMesh(parent), m_border(new QQuickScaleGrid(this)),
+ m_horizontalTileMode(QQuickBorderImageMesh::Stretch),
+ m_verticalTileMode(QQuickBorderImageMesh::Stretch)
+{
+}
+
+bool QQuickBorderImageMesh::validateAttributes(const QVector<QByteArray> &attributes, int *posIndex)
+{
+ Q_UNUSED(attributes);
+ Q_UNUSED(posIndex);
+ return true;
+}
+
+QSGGeometry *QQuickBorderImageMesh::updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex,
+ const QRectF &srcRect, const QRectF &rect)
+{
+ Q_UNUSED(attrCount);
+ Q_UNUSED(posIndex);
+
+ QRectF innerSourceRect;
+ QRectF targetRect;
+ QRectF innerTargetRect;
+ QRectF subSourceRect;
+
+ QQuickBorderImagePrivate::calculateRects(m_border, m_size, rect.size(), m_horizontalTileMode, m_verticalTileMode,
+ 1, &targetRect, &innerTargetRect, &innerSourceRect, &subSourceRect);
+
+ QRectF sourceRect = srcRect;
+ QRectF modifiedInnerSourceRect(sourceRect.x() + innerSourceRect.x() * sourceRect.width(),
+ sourceRect.y() + innerSourceRect.y() * sourceRect.height(),
+ innerSourceRect.width() * sourceRect.width(),
+ innerSourceRect.height() * sourceRect.height());
+
+ geometry = QSGBasicImageNode::updateGeometry(targetRect, innerTargetRect, sourceRect,
+ modifiedInnerSourceRect, subSourceRect, geometry);
+
+ return geometry;
+}
+
+/*!
+ \qmlpropertygroup QtQuick::BorderImageMesh::border
+ \qmlproperty int QtQuick::BorderImageMesh::border.left
+ \qmlproperty int QtQuick::BorderImageMesh::border.right
+ \qmlproperty int QtQuick::BorderImageMesh::border.top
+ \qmlproperty int QtQuick::BorderImageMesh::border.bottom
+
+ The 4 border lines (2 horizontal and 2 vertical) break the image into 9 sections,
+ as shown below:
+
+ \image declarative-scalegrid.png
+
+ Each border line (left, right, top, and bottom) specifies an offset in pixels
+ from the respective edge of the mesh. By default, each border line has
+ a value of 0.
+
+ For example, the following definition sets the bottom line 10 pixels up from
+ the bottom of the mesh:
+
+ \qml
+ BorderImageMesh {
+ border.bottom: 10
+ // ...
+ }
+ \endqml
+*/
+QQuickScaleGrid *QQuickBorderImageMesh::border()
+{
+ return m_border;
+}
+
+/*!
+ \qmlproperty size QtQuick::BorderImageMesh::size
+
+ The base size of the mesh. This generally corresponds to the \l {Image::}{sourceSize}
+ of the image being used by the ShaderEffect.
+*/
+QSize QQuickBorderImageMesh::size() const
+{
+ return m_size;
+}
+
+void QQuickBorderImageMesh::setSize(const QSize &size)
+{
+ if (size == m_size)
+ return;
+ m_size = size;
+ Q_EMIT sizeChanged();
+ Q_EMIT geometryChanged();
+}
+
+/*!
+ \qmlproperty enumeration QtQuick::BorderImageMesh::horizontalTileMode
+ \qmlproperty enumeration QtQuick::BorderImageMesh::verticalTileMode
+
+ This property describes how to repeat or stretch the middle parts of an image.
+
+ \list
+ \li BorderImage.Stretch - Scales the image to fit to the available area.
+ \li BorderImage.Repeat - Tile the image until there is no more space. May crop the last image.
+ \li BorderImage.Round - Like Repeat, but scales the images down to ensure that the last image is not cropped.
+ \endlist
+
+ The default tile mode for each property is BorderImage.Stretch.
+*/
+
+QQuickBorderImageMesh::TileMode QQuickBorderImageMesh::horizontalTileMode() const
+{
+ return m_horizontalTileMode;
+}
+
+void QQuickBorderImageMesh::setHorizontalTileMode(TileMode t)
+{
+ if (t == m_horizontalTileMode)
+ return;
+ m_horizontalTileMode = t;
+ Q_EMIT horizontalTileModeChanged();
+ Q_EMIT geometryChanged();
+}
+
+QQuickBorderImageMesh::TileMode QQuickBorderImageMesh::verticalTileMode() const
+{
+ return m_verticalTileMode;
+}
+
+void QQuickBorderImageMesh::setVerticalTileMode(TileMode t)
+{
+ if (t == m_verticalTileMode)
+ return;
+
+ m_verticalTileMode = t;
+ Q_EMIT verticalTileModeChanged();
+ Q_EMIT geometryChanged();
+}
+
QT_END_NAMESPACE
diff --git a/src/quick/items/qquickshadereffectmesh_p.h b/src/quick/items/qquickshadereffectmesh_p.h
index b6894dc2ec..c5f1d19866 100644
--- a/src/quick/items/qquickshadereffectmesh_p.h
+++ b/src/quick/items/qquickshadereffectmesh_p.h
@@ -107,6 +107,48 @@ private:
QString m_log;
};
+class QQuickScaleGrid;
+class QQuickBorderImageMesh : public QQuickShaderEffectMesh
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQuickScaleGrid *border READ border CONSTANT)
+ Q_PROPERTY(QSize size READ size WRITE setSize NOTIFY sizeChanged)
+ Q_PROPERTY(TileMode horizontalTileMode READ horizontalTileMode WRITE setHorizontalTileMode NOTIFY horizontalTileModeChanged)
+ Q_PROPERTY(TileMode verticalTileMode READ verticalTileMode WRITE setVerticalTileMode NOTIFY verticalTileModeChanged)
+public:
+ QQuickBorderImageMesh(QObject *parent = 0);
+
+ bool validateAttributes(const QVector<QByteArray> &attributes, int *posIndex) override;
+ QSGGeometry *updateGeometry(QSGGeometry *geometry, int attrCount, int posIndex,
+ const QRectF &srcRect, const QRectF &rect) override;
+
+ QQuickScaleGrid *border();
+
+ enum TileMode { Stretch = Qt::StretchTile, Repeat = Qt::RepeatTile, Round = Qt::RoundTile };
+ Q_ENUM(TileMode)
+
+ QSize size() const;
+ void setSize(const QSize &size);
+
+ TileMode horizontalTileMode() const;
+ void setHorizontalTileMode(TileMode);
+
+ TileMode verticalTileMode() const;
+ void setVerticalTileMode(TileMode);
+
+Q_SIGNALS:
+ void sizeChanged();
+ void horizontalTileModeChanged();
+ void verticalTileModeChanged();
+
+private:
+ QQuickScaleGrid *m_border;
+ QSize m_size;
+ TileMode m_horizontalTileMode;
+ TileMode m_verticalTileMode;
+};
+
inline QColor qt_premultiply_color(const QColor &c)
{
return QColor::fromRgbF(c.redF() * c.alphaF(), c.greenF() * c.alphaF(), c.blueF() * c.alphaF(), c.alphaF());
diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp
index 025d5b7b6e..c82966cf6b 100644
--- a/src/quick/items/qquickspriteengine.cpp
+++ b/src/quick/items/qquickspriteengine.cpp
@@ -111,7 +111,7 @@ QQuickSpriteEngine::QQuickSpriteEngine(QObject *parent)
}
QQuickSpriteEngine::QQuickSpriteEngine(QList<QQuickSprite*> sprites, QObject *parent)
- : QQuickStochasticEngine(parent), m_startedImageAssembly(false), m_loaded(false)
+ : QQuickSpriteEngine(parent)
{
foreach (QQuickSprite* sprite, sprites)
m_states << (QQuickStochasticState*)sprite;
diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp
index 127b51948a..8b6cc221d5 100644
--- a/src/quick/items/qquicktextcontrol.cpp
+++ b/src/quick/items/qquicktextcontrol.cpp
@@ -1399,10 +1399,16 @@ QVariant QQuickTextControl::inputMethodQuery(Qt::InputMethodQuery property, QVar
switch (property) {
case Qt::ImCursorRectangle:
return cursorRect();
+ case Qt::ImAnchorRectangle:
+ return anchorRect();
case Qt::ImFont:
return QVariant(d->cursor.charFormat().font());
- case Qt::ImCursorPosition:
+ case Qt::ImCursorPosition: {
+ const QPointF pt = argument.toPointF();
+ if (!pt.isNull())
+ return QVariant(d->doc->documentLayout()->hitTest(pt, Qt::FuzzyHit) - block.position());
return QVariant(d->cursor.position() - block.position());
+ }
case Qt::ImSurroundingText:
return QVariant(block.text());
case Qt::ImCurrentSelection:
@@ -1527,6 +1533,17 @@ void QQuickTextControl::setCursorVisible(bool visible)
&& (d->interactionFlags & (Qt::TextEditable | Qt::TextSelectableByKeyboard)));
}
+QRectF QQuickTextControl::anchorRect() const
+{
+ Q_D(const QQuickTextControl);
+ QRectF rect;
+ QTextCursor cursor = d->cursor;
+ if (!cursor.isNull()) {
+ rect = d->rectForPosition(cursor.anchor());
+ }
+ return rect;
+}
+
QRectF QQuickTextControl::cursorRect(const QTextCursor &cursor) const
{
Q_D(const QQuickTextControl);
diff --git a/src/quick/items/qquicktextcontrol_p.h b/src/quick/items/qquicktextcontrol_p.h
index cee9cff064..602e457cb8 100644
--- a/src/quick/items/qquicktextcontrol_p.h
+++ b/src/quick/items/qquicktextcontrol_p.h
@@ -98,6 +98,7 @@ public:
void setOverwriteMode(bool overwrite);
bool cursorVisible() const;
void setCursorVisible(bool visible);
+ QRectF anchorRect() const;
QRectF cursorRect(const QTextCursor &cursor) const;
QRectF cursorRect() const;
QRectF selectionRect(const QTextCursor &cursor) const;
diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp
index a44f549b37..8bb788d008 100644
--- a/src/quick/items/qquicktextedit.cpp
+++ b/src/quick/items/qquicktextedit.cpp
@@ -541,7 +541,7 @@ void QQuickTextEdit::setFont(const QFont &font)
updateSize();
updateWholeDocument();
#ifndef QT_NO_IM
- updateInputMethod(Qt::ImCursorRectangle | Qt::ImFont);
+ updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorRectangle | Qt::ImFont);
#endif
}
emit fontChanged(d->sourceFont);
@@ -1729,6 +1729,7 @@ void QQuickTextEdit::select(int start, int end)
// QTBUG-11100
updateSelection();
+ updateInputMethod();
}
/*!
@@ -1901,7 +1902,11 @@ QVariant QQuickTextEdit::inputMethodQuery(Qt::InputMethodQuery property, QVarian
v = (int)d->effectiveInputMethodHints();
break;
default:
+ if (property == Qt::ImCursorPosition && !argument.isNull())
+ argument = QVariant(argument.toPointF() - QPointF(d->xoff, d->yoff));
v = d->control->inputMethodQuery(property, argument);
+ if (property == Qt::ImCursorRectangle || property == Qt::ImAnchorRectangle)
+ v = QVariant(v.toRectF().translated(d->xoff, d->yoff));
break;
}
return v;
diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp
index 8bf854aac2..f361d46424 100644
--- a/src/quick/items/qquicktextinput.cpp
+++ b/src/quick/items/qquicktextinput.cpp
@@ -401,7 +401,7 @@ void QQuickTextInput::setFont(const QFont &font)
d->updateLayout();
updateCursorRectangle();
#ifndef QT_NO_IM
- updateInputMethod(Qt::ImCursorRectangle | Qt::ImFont);
+ updateInputMethod(Qt::ImCursorRectangle | Qt::ImFont | Qt::ImAnchorRectangle);
#endif
}
emit fontChanged(d->sourceFont);
@@ -1044,6 +1044,36 @@ void QQuickTextInput::q_validatorChanged()
}
#endif // QT_NO_VALIDATOR
+QRectF QQuickTextInputPrivate::anchorRectangle() const
+{
+ QRectF rect;
+ int a;
+ // Unfortunately we cannot use selectionStart() and selectionEnd()
+ // since they always assume that the selectionStart is logically before selectionEnd.
+ // To rely on that would cause havoc if the user was interactively moving the end selection
+ // handle to become before the start selection
+ if (m_selstart == m_selend)
+ // This is to handle the case when there is "no selection" while moving the handle onto the
+ // same position as the other handle (in which case it would hide the selection handles)
+ a = m_cursor;
+ else
+ a = m_selstart == m_cursor ? m_selend : m_selstart;
+ if (a >= 0) {
+#ifndef QT_NO_IM
+ a += m_preeditCursor;
+#endif
+ if (m_echoMode == QQuickTextInput::NoEcho)
+ a = 0;
+ QTextLine l = m_textLayout.lineForTextPosition(a);
+ if (l.isValid()) {
+ qreal x = l.cursorToX(a) - hscroll;
+ qreal y = l.y() - vscroll;
+ rect.setRect(x, y, 1, l.height());
+ }
+ }
+ return rect;
+}
+
void QQuickTextInputPrivate::checkIsValid()
{
Q_Q(QQuickTextInput);
@@ -1889,10 +1919,16 @@ QVariant QQuickTextInput::inputMethodQuery(Qt::InputMethodQuery property, QVaria
return QVariant((int) d->effectiveInputMethodHints());
case Qt::ImCursorRectangle:
return cursorRectangle();
+ case Qt::ImAnchorRectangle:
+ return d->anchorRectangle();
case Qt::ImFont:
return font();
- case Qt::ImCursorPosition:
+ case Qt::ImCursorPosition: {
+ const QPointF pt = argument.toPointF();
+ if (!pt.isNull())
+ return QVariant(d->positionAt(pt));
return QVariant(d->m_cursor);
+ }
case Qt::ImSurroundingText:
if (d->m_echoMode == PasswordEchoOnEdit && !d->m_passwordEchoEditing) {
return QVariant(displayText());
@@ -2689,7 +2725,7 @@ void QQuickTextInput::updateCursorRectangle(bool scroll)
d->cursorItem->setHeight(r.height());
}
#ifndef QT_NO_IM
- updateInputMethod(Qt::ImCursorRectangle);
+ updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorRectangle);
#endif
}
@@ -3223,8 +3259,8 @@ void QQuickTextInputPrivate::setSelection(int start, int length)
emit q->selectionChanged();
emitCursorPositionChanged();
#ifndef QT_NO_IM
- q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorPosition
- | Qt::ImCursorPosition | Qt::ImCurrentSelection);
+ q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorRectangle | Qt::ImCursorPosition | Qt::ImAnchorPosition
+ | Qt::ImCurrentSelection);
#endif
}
@@ -3422,8 +3458,8 @@ void QQuickTextInputPrivate::processInputMethodEvent(QInputMethodEvent *event)
if (selectionChange) {
emit q->selectionChanged();
- q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorPosition
- | Qt::ImCursorPosition | Qt::ImCurrentSelection);
+ q->updateInputMethod(Qt::ImCursorRectangle | Qt::ImAnchorRectangle
+ | Qt::ImCurrentSelection);
}
}
#endif // QT_NO_IM
diff --git a/src/quick/items/qquicktextinput_p_p.h b/src/quick/items/qquicktextinput_p_p.h
index d5a138945d..e6bd29bf67 100644
--- a/src/quick/items/qquicktextinput_p_p.h
+++ b/src/quick/items/qquicktextinput_p_p.h
@@ -342,6 +342,8 @@ public:
int selectionStart() const { return hasSelectedText() ? m_selstart : -1; }
int selectionEnd() const { return hasSelectedText() ? m_selend : -1; }
+ QRectF anchorRectangle() const;
+
int positionAt(qreal x, qreal y, QTextLine::CursorPosition position) const;
int positionAt(const QPointF &point, QTextLine::CursorPosition position = QTextLine::CursorBetweenCharacters) const {
return positionAt(point.x(), point.y(), position);
diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp
index 3ce96b673d..1101b88992 100644
--- a/src/quick/items/qquickview.cpp
+++ b/src/quick/items/qquickview.cpp
@@ -194,9 +194,8 @@ QQuickView::QQuickView(QWindow *parent)
*/
QQuickView::QQuickView(const QUrl &source, QWindow *parent)
-: QQuickWindow(*(new QQuickViewPrivate), parent)
+ : QQuickView(parent)
{
- d_func()->init();
setSource(source);
}
diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp
index fda01a72f2..2d38314a0a 100644
--- a/src/quick/items/qquickwindow.cpp
+++ b/src/quick/items/qquickwindow.cpp
@@ -1148,10 +1148,8 @@ void QQuickWindowPrivate::cleanup(QSGNode *n)
Constructs a window for displaying a QML scene with parent window \a parent.
*/
QQuickWindow::QQuickWindow(QWindow *parent)
- : QWindow(*(new QQuickWindowPrivate), parent)
+ : QQuickWindow(*new QQuickWindowPrivate, parent)
{
- Q_D(QQuickWindow);
- d->init(this);
}
diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp
index 124df8f676..c624d162a9 100644
--- a/src/quick/items/qquickwindowmodule.cpp
+++ b/src/quick/items/qquickwindowmodule.cpp
@@ -77,18 +77,16 @@ QQuickWindowQmlImpl::QQuickWindowQmlImpl(QWindow *parent)
void QQuickWindowQmlImpl::setVisible(bool visible)
{
Q_D(QQuickWindowQmlImpl);
- if (!d->complete)
- d->visible = visible;
- else if (!transientParent() || transientParent()->isVisible())
+ d->visible = visible;
+ if (d->complete && (!transientParent() || transientParent()->isVisible()))
QQuickWindow::setVisible(visible);
}
void QQuickWindowQmlImpl::setVisibility(Visibility visibility)
{
Q_D(QQuickWindowQmlImpl);
- if (!d->complete)
- d->visibility = visibility;
- else
+ d->visibility = visibility;
+ if (d->complete)
QQuickWindow::setVisibility(visibility);
}