aboutsummaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
authorGunnar Sletta <gunnar.sletta@nokia.com>2011-05-23 13:51:45 +0200
committerGunnar Sletta <gunnar.sletta@nokia.com>2011-05-23 13:51:45 +0200
commitf0819b0c3f80fb4f6abad8f00ef94cf52dd6c123 (patch)
treecaada59a27fe48c7cc40a729e50d77c811062afc /src/declarative
parenta12c55f1b3b2ec76c2e8d1c080897c55e0528b11 (diff)
parente430f1336881850a73a54a291e0276160d568212 (diff)
Merge branch 'qtquick2' of scm.dev.nokia.troll.no:qt/qtdeclarative-staging into qtquick2
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/items/qsgtextinput.cpp143
-rw-r--r--src/declarative/items/qsgtextinput_p.h4
-rw-r--r--src/declarative/items/qsgtextinput_p_p.h9
-rw-r--r--src/declarative/items/qsgtextnode.cpp250
-rw-r--r--src/declarative/items/qsgtextnode_p.h15
-rw-r--r--src/declarative/scenegraph/qsgcontext.cpp2
-rw-r--r--src/declarative/scenegraph/qsgcontext_p.h2
-rw-r--r--src/declarative/util/qdeclarativepixmapcache.cpp2
8 files changed, 377 insertions, 50 deletions
diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp
index 1db4474d4a..a0c3c3e0ef 100644
--- a/src/declarative/items/qsgtextinput.cpp
+++ b/src/declarative/items/qsgtextinput.cpp
@@ -52,13 +52,15 @@
#include <QtGui/qinputcontext.h>
#include <QTextBoundaryFinder>
#include <qstyle.h>
+#include <qsgtextnode_p.h>
+#include <qsgsimplerectnode.h>
QT_BEGIN_NAMESPACE
QWidgetPrivate *qt_widget_private(QWidget *widget);
QSGTextInput::QSGTextInput(QSGItem* parent)
-: QSGImplicitSizePaintedItem(*(new QSGTextInputPrivate), parent)
+: QSGImplicitSizeItem(*(new QSGTextInputPrivate), parent)
{
Q_D(QSGTextInput);
d->init();
@@ -616,7 +618,7 @@ void QSGTextInput::keyPressEvent(QKeyEvent* ev)
d->control->processKeyEvent(ev);
}
if (!ev->isAccepted())
- QSGPaintedItem::keyPressEvent(ev);
+ QSGImplicitSizeItem::keyPressEvent(ev);
}
void QSGTextInput::inputMethodEvent(QInputMethodEvent *ev)
@@ -631,7 +633,7 @@ void QSGTextInput::inputMethodEvent(QInputMethodEvent *ev)
d->updateHorizontalScroll();
}
if (!ev->isAccepted())
- QSGPaintedItem::inputMethodEvent(ev);
+ QSGImplicitSizeItem::inputMethodEvent(ev);
if (wasComposing != (d->control->preeditAreaText().length() > 0))
emit inputMethodComposingChanged();
@@ -647,7 +649,7 @@ void QSGTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
d->control->selectWordAtPos(cursor);
event->setAccepted(true);
} else {
- QSGPaintedItem::mouseDoubleClickEvent(event);
+ QSGImplicitSizeItem::mouseDoubleClickEvent(event);
}
}
@@ -692,7 +694,7 @@ void QSGTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode);
event->setAccepted(true);
} else {
- QSGPaintedItem::mouseMoveEvent(event);
+ QSGImplicitSizeItem::mouseMoveEvent(event);
}
}
@@ -715,7 +717,7 @@ void QSGTextInput::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
d->clickCausedFocus = false;
d->control->processEvent(event);
if (!event->isAccepted())
- QSGPaintedItem::mouseReleaseEvent(event);
+ QSGImplicitSizeItem::mouseReleaseEvent(event);
}
bool QSGTextInputPrivate::sendMouseEventToInputContext(
@@ -781,7 +783,7 @@ bool QSGTextInput::event(QEvent* ev)
handled = d->control->processEvent(ev);
}
if(!handled)
- handled = QSGPaintedItem::event(ev);
+ handled = QSGImplicitSizeItem::event(ev);
return handled;
}
@@ -793,7 +795,7 @@ void QSGTextInput::geometryChanged(const QRectF &newGeometry,
updateSize();
d->updateHorizontalScroll();
}
- QSGPaintedItem::geometryChanged(newGeometry, oldGeometry);
+ QSGImplicitSizeItem::geometryChanged(newGeometry, oldGeometry);
}
int QSGTextInputPrivate::calculateTextWidth()
@@ -860,20 +862,46 @@ void QSGTextInputPrivate::updateHorizontalScroll()
}
}
-void QSGTextInput::paint(QPainter *p)
-{
- // XXX todo
- QRect r(0, 0, width(), height());
-
+//void QSGTextInput::paint(QPainter *p)
+//{
+// // XXX todo
+// QRect r(0, 0, width(), height());
+
+// Q_D(QSGTextInput);
+// p->setRenderHint(QPainter::TextAntialiasing, true);
+// p->save();
+// p->setPen(QPen(d->color));
+// int flags = QLineControl::DrawText;
+// if(!isReadOnly() && d->cursorVisible && !d->cursorItem)
+// flags |= QLineControl::DrawCursor;
+// if (d->control->hasSelectedText())
+// flags |= QLineControl::DrawSelections;
+// QPoint offset = QPoint(0,0);
+// QFontMetrics fm = QFontMetrics(d->font);
+// QRect br(boundingRect().toRect());
+// if (d->autoScroll) {
+// // the y offset is there to keep the baseline constant in case we have script changes in the text.
+// offset = br.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
+// } else {
+// offset = QPoint(d->hscroll, 0);
+// }
+// d->control->draw(p, offset, r, flags);
+// p->restore();
+//}
+
+QSGNode *QSGTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
+{
+ Q_UNUSED(data);
Q_D(QSGTextInput);
- p->setRenderHint(QPainter::TextAntialiasing, true);
- p->save();
- p->setPen(QPen(d->color));
- int flags = QLineControl::DrawText;
- if(!isReadOnly() && d->cursorVisible && !d->cursorItem)
- flags |= QLineControl::DrawCursor;
- if (d->control->hasSelectedText())
- flags |= QLineControl::DrawSelections;
+
+ QSGTextNode *node = static_cast<QSGTextNode *>(oldNode);
+ if (node == 0)
+ node = new QSGTextNode(QSGItemPrivate::get(this)->sceneGraphContext());
+ d->textNode = node;
+
+ node->deleteContent();
+ node->setMatrix(QMatrix4x4());
+
QPoint offset = QPoint(0,0);
QFontMetrics fm = QFontMetrics(d->font);
QRect br(boundingRect().toRect());
@@ -883,8 +911,26 @@ void QSGTextInput::paint(QPainter *p)
} else {
offset = QPoint(d->hscroll, 0);
}
- d->control->draw(p, offset, r, flags);
- p->restore();
+
+ // ### Thread of text layout :/
+ QTextLayout *textLayout = d->control->textLayout();
+ node->addTextLayout(offset, textLayout, d->color,
+ QSGText::Normal, QColor(),
+ d->selectionColor, d->selectedTextColor,
+ d->control->selectionStart(),
+ d->control->selectionEnd() - 1); // selectionEnd() returns first char after
+ // selection
+
+ if (!isReadOnly() && d->cursorItem == 0) {
+ offset.rx() += d->control->cursorToX();
+ node->setCursor(QRectF(offset, QSizeF(d->control->cursorWidth(), br.height())), d->color);
+ if (!d->cursorVisible
+ || (!d->control->cursorBlinkStatus() && d->control->cursorBlinkPeriod() > 0)) {
+ d->hideCursor();
+ }
+ }
+
+ return node;
}
QVariant QSGTextInput::inputMethodQuery(Qt::InputMethodQuery property) const
@@ -1123,7 +1169,7 @@ void QSGTextInput::focusInEvent(QFocusEvent *event)
openSoftwareInputPanel();
}
}
- QSGPaintedItem::focusInEvent(event);
+ QSGImplicitSizeItem::focusInEvent(event);
}
void QSGTextInput::itemChange(ItemChange change, const ItemChangeData &value)
@@ -1156,6 +1202,7 @@ void QSGTextInputPrivate::init()
q->setSmooth(smooth);
q->setAcceptedMouseButtons(Qt::LeftButton);
q->setFlag(QSGItem::ItemAcceptsInputMethod);
+ q->setFlag(QSGItem::ItemHasContents);
q->connect(control, SIGNAL(cursorPositionChanged(int,int)),
q, SLOT(cursorPosChanged()));
q->connect(control, SIGNAL(selectionChanged()),
@@ -1246,19 +1293,56 @@ void QSGTextInput::q_textChanged()
}
}
+void QSGTextInputPrivate::showCursor()
+{
+ if (textNode != 0 && textNode->cursorNode() != 0)
+ textNode->cursorNode()->setColor(color);
+}
+
+void QSGTextInputPrivate::hideCursor()
+{
+ if (textNode != 0 && textNode->cursorNode() != 0)
+ textNode->cursorNode()->setColor(QColor(0, 0, 0, 0));
+}
+
void QSGTextInput::updateRect(const QRect &r)
{
Q_D(QSGTextInput);
- if(r == QRect())
+ if (!isComponentComplete())
+ return;
+
+ if (r.isEmpty()) {
update();
- else
- update(QRect(r.x() - d->hscroll, r.y(), r.width(), r.height()));
+ } else { // Cursor update
+ QSGSimpleRectNode *cursorNode = d->textNode->cursorNode();
+ if (cursorNode != 0) {
+ QPoint offset = QPoint(0,0);
+ QFontMetrics fm = QFontMetrics(d->font);
+ QRect br(boundingRect().toRect());
+ if (d->autoScroll) {
+ // the y offset is there to keep the baseline constant in case we have script changes in the text.
+ offset = br.topLeft() - QPoint(d->hscroll, d->control->ascent() - fm.ascent());
+ } else {
+ offset = QPoint(d->hscroll, 0);
+ }
+ offset.rx() += d->control->cursorToX();
+
+ cursorNode->setRect(QRectF(offset, QSizeF(d->control->cursorWidth(), br.height())));
+
+ if (!d->cursorVisible
+ || (!d->control->cursorBlinkStatus() && d->control->cursorBlinkPeriod() > 0)) {
+ d->hideCursor();
+ } else {
+ d->showCursor();
+ }
+ }
+ }
}
QRectF QSGTextInput::boundingRect() const
{
Q_D(const QSGTextInput);
- QRectF r = QSGPaintedItem::boundingRect();
+ QRectF r = QSGImplicitSizeItem::boundingRect();
int cursorWidth = d->cursorItem ? d->cursorItem->width() : d->control->cursorWidth();
@@ -1274,8 +1358,7 @@ void QSGTextInput::updateSize(bool needsRedraw)
int w = width();
int h = height();
setImplicitHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text.
- setImplicitWidth(d->calculateTextWidth());
- setContentsSize(QSize(width(), height()));
+ setImplicitWidth(d->calculateTextWidth());
if(w==width() && h==height() && needsRedraw)
update();
}
diff --git a/src/declarative/items/qsgtextinput_p.h b/src/declarative/items/qsgtextinput_p.h
index ccea485e99..d2bc9e3961 100644
--- a/src/declarative/items/qsgtextinput_p.h
+++ b/src/declarative/items/qsgtextinput_p.h
@@ -54,7 +54,7 @@ QT_MODULE(Declarative)
class QSGTextInputPrivate;
class QValidator;
-class Q_AUTOTEST_EXPORT QSGTextInput : public QSGImplicitSizePaintedItem
+class Q_AUTOTEST_EXPORT QSGTextInput : public QSGImplicitSizeItem
{
Q_OBJECT
Q_ENUMS(HAlignment)
@@ -204,7 +204,6 @@ public:
bool hasAcceptableInput() const;
- void paint(QPainter *p);
QVariant inputMethodQuery(Qt::InputMethodQuery property) const;
QRectF boundingRect() const;
@@ -260,6 +259,7 @@ protected:
bool event(QEvent *e);
void focusInEvent(QFocusEvent *event);
virtual void itemChange(ItemChange, const ItemChangeData &);
+ QSGNode *updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data);
public Q_SLOTS:
void selectAll();
diff --git a/src/declarative/items/qsgtextinput_p_p.h b/src/declarative/items/qsgtextinput_p_p.h
index 6561d28a31..6f69be5d69 100644
--- a/src/declarative/items/qsgtextinput_p_p.h
+++ b/src/declarative/items/qsgtextinput_p_p.h
@@ -65,7 +65,9 @@
QT_BEGIN_NAMESPACE
-class Q_AUTOTEST_EXPORT QSGTextInputPrivate : public QSGImplicitSizePaintedItemPrivate
+class QSGTextNode;
+
+class Q_AUTOTEST_EXPORT QSGTextInputPrivate : public QSGImplicitSizeItemPrivate
{
Q_DECLARE_PUBLIC(QSGTextInput)
public:
@@ -76,7 +78,7 @@ public:
hscroll(0), oldScroll(0), oldValidity(false), focused(false), focusOnPress(true),
showInputPanelOnFocus(true), clickCausedFocus(false), cursorVisible(false),
autoScroll(true), selectByMouse(false), canPaste(false), hAlignImplicit(true),
- selectPressed(false)
+ selectPressed(false), textNode(0)
{
#ifdef Q_OS_SYMBIAN
if (QSysInfo::symbianVersion() == QSysInfo::SV_SF_1 || QSysInfo::symbianVersion() == QSysInfo::SV_SF_3) {
@@ -106,6 +108,8 @@ public:
int calculateTextWidth();
bool sendMouseEventToInputContext(QGraphicsSceneMouseEvent *event, QEvent::Type eventType);
void updateInputMethodHints();
+ void hideCursor();
+ void showCursor();
QLineControl* control;
@@ -122,6 +126,7 @@ public:
QPointer<QDeclarativeComponent> cursorComponent;
QPointer<QSGItem> cursorItem;
QPointF pressPos;
+ QSGTextNode *textNode;
int lastSelectionStart;
int lastSelectionEnd;
diff --git a/src/declarative/items/qsgtextnode.cpp b/src/declarative/items/qsgtextnode.cpp
index 33325a14ab..f48b65f168 100644
--- a/src/declarative/items/qsgtextnode.cpp
+++ b/src/declarative/items/qsgtextnode.cpp
@@ -47,6 +47,7 @@
#include <private/qsgcontext_p.h>
+#include <QtCore/qpoint.h>
#include <qmath.h>
#include <qtextdocument.h>
#include <qtextlayout.h>
@@ -64,7 +65,7 @@ QT_BEGIN_NAMESPACE
Creates an empty QSGTextNode
*/
QSGTextNode::QSGTextNode(QSGContext *context)
-: m_context(context)
+ : m_context(context), m_cursorNode(0)
{
#if defined(QML_RUNTIME_TESTING)
description = QLatin1String("text");
@@ -184,21 +185,245 @@ void QSGTextNode::addTextDocument(const QPointF &position, QTextDocument *textDo
}
}
-void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color,
- QSGText::TextStyle style, const QColor &styleColor)
+void QSGTextNode::setCursor(const QRectF &rect, const QColor &color)
{
- QList<QGlyphRun> glyphsList(textLayout->glyphRuns());
- for (int i=0; i<glyphsList.size(); ++i) {
- QGlyphRun glyphs = glyphsList.at(i);
- QRawFont font = glyphs.rawFont();
- addGlyphs(position + QPointF(0, font.ascent()), glyphs, color, style, styleColor);
+ if (m_cursorNode != 0)
+ delete m_cursorNode;
+
+ m_cursorNode = new QSGSimpleRectNode(rect, color);
+ appendChildNode(m_cursorNode);
+}
+
+QSGGlyphNode *QSGTextNode::addGlyphsAndDecoration(const QPointF &position, const QGlyphRun &glyphRun,
+ const QColor &color, QSGText::TextStyle style,
+ const QColor &styleColor,
+ const QPointF &decorationPosition)
+{
+ QSGGlyphNode *node = addGlyphs(position, glyphRun, color, style, styleColor);
+
+ if (glyphRun.strikeOut() || glyphRun.overline() || glyphRun.underline()) {
+ QRectF rect = glyphRun.boundingRect();
+ qreal width = rect.right() - decorationPosition.x();
+
+ addTextDecorations(decorationPosition, glyphRun.rawFont(), color, width,
+ glyphRun.overline(), glyphRun.strikeOut(), glyphRun.underline());
}
+ return node;
+}
+
+namespace {
+
+ struct BinaryTreeNode {
+ enum SelectionState {
+ Unselected,
+ Selected
+ };
+
+ BinaryTreeNode()
+ : selectionState(Unselected)
+ , leftChildIndex(-1)
+ , rightChildIndex(-1)
+ {
+
+ }
+
+ BinaryTreeNode(const QGlyphRun &g, SelectionState selState, const QRectF &brect)
+ : glyphRun(g)
+ , boundingRect(brect)
+ , selectionState(selState)
+ , leftChildIndex(-1)
+ , rightChildIndex(-1)
+ {
+ }
+
+ QGlyphRun glyphRun;
+ QRectF boundingRect;
+ SelectionState selectionState;
+
+ int leftChildIndex;
+ int rightChildIndex;
+
+ static void insert(QVarLengthArray<BinaryTreeNode> *binaryTree,
+ const QGlyphRun &glyphRun,
+ SelectionState selectionState)
+ {
+ int newIndex = binaryTree->size();
+ QRectF searchRect = glyphRun.boundingRect();
+
+ binaryTree->append(BinaryTreeNode(glyphRun, selectionState, searchRect));
+ if (newIndex == 0)
+ return;
+
+ int searchIndex = 0;
+ forever {
+ BinaryTreeNode *node = binaryTree->data() + searchIndex;
+ if (searchRect.left() < node->boundingRect.left()) {
+ if (node->leftChildIndex < 0) {
+ node->leftChildIndex = newIndex;
+ break;
+ } else {
+ searchIndex = node->leftChildIndex;
+ }
+ } else {
+ if (node->rightChildIndex < 0) {
+ node->rightChildIndex = newIndex;
+ break;
+ } else {
+ searchIndex = node->rightChildIndex;
+ }
+ }
+ }
+ }
+
+ static void inOrder(const QVarLengthArray<BinaryTreeNode> &binaryTree,
+ QVarLengthArray<int> *sortedIndexes,
+ int currentIndex = 0)
+ {
+ Q_ASSERT(currentIndex < binaryTree.size());
+
+ const BinaryTreeNode *node = binaryTree.data() + currentIndex;
+ if (node->leftChildIndex >= 0)
+ inOrder(binaryTree, sortedIndexes, node->leftChildIndex);
+
+ sortedIndexes->append(currentIndex);
+
+ if (node->rightChildIndex >= 0)
+ inOrder(binaryTree, sortedIndexes, node->rightChildIndex);
+ }
+ };
+}
+
+void QSGTextNode::addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color,
+ QSGText::TextStyle style, const QColor &styleColor,
+ const QColor &selectionColor, const QColor &selectedTextColor,
+ int selectionStart, int selectionEnd)
+{
QFont font = textLayout->font();
- QRawFont rawFont = QRawFont::fromFont(font);
- if (font.strikeOut() || font.underline() || font.overline()) {
- addTextDecorations(position, rawFont, color, textLayout->boundingRect().width(),
- font.overline(), font.strikeOut(), font.underline());
+ bool overline = font.overline();
+ bool underline = font.underline();
+ bool strikeOut = font.strikeOut();
+ QRawFont decorationRawFont = QRawFont::fromFont(font);
+
+ if (selectionStart < 0 || selectionEnd < 0) {
+ for (int i=0; i<textLayout->lineCount(); ++i) {
+ QTextLine line = textLayout->lineAt(i);
+
+ QList<QGlyphRun> glyphRuns = line.glyphRuns();
+ for (int j=0; j<glyphRuns.size(); ++j) {
+ QGlyphRun glyphRun = glyphRuns.at(j);
+ QPointF pos(position + QPointF(0, glyphRun.rawFont().ascent()));
+ addGlyphs(pos, glyphRun, color, style, styleColor);
+ }
+
+ addTextDecorations(QPointF(line.x(), line.y() + decorationRawFont.ascent()),
+ decorationRawFont, color, line.naturalTextWidth(),
+ overline, strikeOut, underline);
+ }
+
+ } else {
+ QVarLengthArray<BinaryTreeNode> binaryNodes;
+ for (int i=0; i<textLayout->lineCount(); ++i) {
+ QTextLine line = textLayout->lineAt(i);
+
+ // Make a list of glyph runs sorted on left-most x coordinate to make it possible
+ // to find the correct selection rects
+ if (line.textStart() < selectionStart) {
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(line.textStart(),
+ qMin(selectionStart - line.textStart(),
+ line.textLength()));
+ for (int j=0; j<glyphRuns.size(); ++j) {
+ const QGlyphRun &glyphRun = glyphRuns.at(j);
+ BinaryTreeNode::insert(&binaryNodes, glyphRun, BinaryTreeNode::Unselected);
+ }
+ }
+
+ int lineEnd = line.textStart() + line.textLength();
+
+ // Add selected text
+ if (lineEnd >= selectionStart && selectionStart >= line.textStart()) {
+ QList<QGlyphRun> selectedGlyphRuns = line.glyphRuns(selectionStart,
+ selectionEnd - selectionStart + 1);
+ for (int j=0; j<selectedGlyphRuns.size(); ++j) {
+ const QGlyphRun &selectedGlyphRun = selectedGlyphRuns.at(j);
+ BinaryTreeNode::insert(&binaryNodes, selectedGlyphRun, BinaryTreeNode::Selected);
+ }
+ }
+
+ // If there is selected text in this line, add regular text after selection
+ if (selectionEnd >= line.textStart() && selectionEnd < lineEnd) {
+ QList<QGlyphRun> glyphRuns = line.glyphRuns(selectionEnd + 1, lineEnd - selectionEnd);
+ for (int j=0; j<glyphRuns.size(); ++j) {
+ const QGlyphRun &glyphRun = glyphRuns.at(j);
+ BinaryTreeNode::insert(&binaryNodes, glyphRun, BinaryTreeNode::Unselected);
+ }
+ }
+
+ // Go through glyph runs sorted by x position and add glyph nodes/text decoration
+ // and selection rects to the graph
+ QVarLengthArray<int> sortedIndexes;
+ BinaryTreeNode::inOrder(binaryNodes, &sortedIndexes);
+
+ Q_ASSERT(sortedIndexes.size() == binaryNodes.size());
+
+ BinaryTreeNode::SelectionState currentSelectionState = BinaryTreeNode::Unselected;
+ QRectF currentRect = QRectF(line.x(), line.y(), 1, 1);
+ for (int i=0; i<=sortedIndexes.size(); ++i) {
+ BinaryTreeNode *node = 0;
+ if (i < sortedIndexes.size()) {
+ int sortedIndex = sortedIndexes.at(i);
+ Q_ASSERT(sortedIndex < binaryNodes.size());
+
+ node = binaryNodes.data() + sortedIndex;
+ const QGlyphRun &glyphRun = node->glyphRun;
+
+ QColor currentColor = node->selectionState == BinaryTreeNode::Unselected
+ ? color
+ : selectedTextColor;
+
+ QPointF pos(position + QPointF(0, glyphRun.rawFont().ascent()));
+ addGlyphs(pos, glyphRun, currentColor, style, styleColor);
+
+ if (i == 0)
+ currentSelectionState = node->selectionState;
+ }
+
+ // If we've reached an unselected node from a selected node, we add the
+ // selection rect to the graph, and we add decoration every time the
+ // selection state changes, because that means the text color changes
+ if (node == 0 || node->selectionState != currentSelectionState) {
+ if (node != 0)
+ currentRect.setRight(node->boundingRect.left());
+ else
+ currentRect.setWidth(line.naturalTextWidth() - (currentRect.x() - line.x()));
+ currentRect.setY(line.y());
+ currentRect.setHeight(line.height());
+
+ // Draw selection all the way up to the left edge of the unselected item
+ if (currentSelectionState == BinaryTreeNode::Selected)
+ prependChildNode(new QSGSimpleRectNode(currentRect, selectionColor));
+
+ if (overline || underline || strikeOut) {
+ QColor currentColor = currentSelectionState == BinaryTreeNode::Unselected
+ ? color
+ : selectedTextColor;
+ addTextDecorations(currentRect.topLeft() + QPointF(0, decorationRawFont.ascent()),
+ decorationRawFont, currentColor, currentRect.width(),
+ overline, strikeOut, underline);
+ }
+
+ if (node != 0) {
+ currentSelectionState = node->selectionState;
+ currentRect = node->boundingRect;
+ }
+ } else {
+ if (currentRect.isEmpty())
+ currentRect = node->boundingRect;
+ else
+ currentRect = currentRect.united(node->boundingRect);
+ }
+ }
+ }
}
}
@@ -378,6 +603,7 @@ void QSGTextNode::deleteContent()
{
while (childCount() > 0)
delete childAtIndex(0);
+ m_cursorNode = 0;
}
#if 0
diff --git a/src/declarative/items/qsgtextnode_p.h b/src/declarative/items/qsgtextnode_p.h
index 7a49f51dbe..ece80bdce0 100644
--- a/src/declarative/items/qsgtextnode_p.h
+++ b/src/declarative/items/qsgtextnode_p.h
@@ -54,6 +54,7 @@ class QColor;
class QTextDocument;
class QSGContext;
class QRawFont;
+class QSGSimpleRectNode;
class QSGTextNode : public QSGTransformNode
{
@@ -65,18 +66,30 @@ public:
void deleteContent();
void addTextLayout(const QPointF &position, QTextLayout *textLayout, const QColor &color = QColor(),
- QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
+ QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor(),
+ const QColor &selectionColor = QColor(), const QColor &selectedTextColor = QColor(),
+ int selectionStart = -1, int selectionEnd = -1);
void addTextDocument(const QPointF &position, QTextDocument *textDocument, const QColor &color = QColor(),
QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
+ void setCursor(const QRectF &rect, const QColor &color);
+ QSGSimpleRectNode *cursorNode() const { return m_cursorNode; }
+
private:
void addTextBlock(const QPointF &position, QTextDocument *textDocument, const QTextBlock &block,
const QColor &overrideColor, QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
QSGGlyphNode *addGlyphs(const QPointF &position, const QGlyphRun &glyphs, const QColor &color,
QSGText::TextStyle style = QSGText::Normal, const QColor &styleColor = QColor());
+ QSGGlyphNode *addGlyphsAndDecoration(const QPointF &position, const QGlyphRun &glyphs,
+ const QColor &color,
+ QSGText::TextStyle style = QSGText::Normal,
+ const QColor &styleColor = QColor(),
+ const QPointF &decorationPosition = QPointF());
+
void addTextDecorations(const QPointF &position, const QRawFont &font, const QColor &color,
qreal width, bool hasOverline, bool hasStrikeOut, bool hasUnderline);
QSGContext *m_context;
+ QSGSimpleRectNode *m_cursorNode;
};
QT_END_NAMESPACE
diff --git a/src/declarative/scenegraph/qsgcontext.cpp b/src/declarative/scenegraph/qsgcontext.cpp
index dd35c06ecc..e36d432e40 100644
--- a/src/declarative/scenegraph/qsgcontext.cpp
+++ b/src/declarative/scenegraph/qsgcontext.cpp
@@ -164,7 +164,7 @@ QSGEngine *QSGContext::engine() const
The texture can be considered as deleted after this function has
been called.
*/
-void QSGContext::schdelueTextureForCleanup(QSGTexture *texture)
+void QSGContext::scheduleTextureForCleanup(QSGTexture *texture)
{
Q_D(QSGContext);
d->textureMutex.lock();
diff --git a/src/declarative/scenegraph/qsgcontext_p.h b/src/declarative/scenegraph/qsgcontext_p.h
index 59522b6f73..1344ac705d 100644
--- a/src/declarative/scenegraph/qsgcontext_p.h
+++ b/src/declarative/scenegraph/qsgcontext_p.h
@@ -104,7 +104,7 @@ public:
static QSGContext *createDefaultContext();
- void schdelueTextureForCleanup(QSGTexture *texture);
+ void scheduleTextureForCleanup(QSGTexture *texture);
void cleanupTextures();
void setFlashModeEnabled(bool enabled);
diff --git a/src/declarative/util/qdeclarativepixmapcache.cpp b/src/declarative/util/qdeclarativepixmapcache.cpp
index ddb0032644..fa3be223a7 100644
--- a/src/declarative/util/qdeclarativepixmapcache.cpp
+++ b/src/declarative/util/qdeclarativepixmapcache.cpp
@@ -228,7 +228,7 @@ public:
~QDeclarativePixmapData()
{
if (texture && context) {
- context->schdelueTextureForCleanup(texture);
+ context->scheduleTextureForCleanup(texture);
}
}