diff options
Diffstat (limited to 'src/declarative/items/qsgtextinput.cpp')
-rw-r--r-- | src/declarative/items/qsgtextinput.cpp | 142 |
1 files changed, 110 insertions, 32 deletions
diff --git a/src/declarative/items/qsgtextinput.cpp b/src/declarative/items/qsgtextinput.cpp index 4b9aea1b21..222a9002e7 100644 --- a/src/declarative/items/qsgtextinput.cpp +++ b/src/declarative/items/qsgtextinput.cpp @@ -45,15 +45,20 @@ #include <private/qdeclarativeglobal_p.h> #include <private/qwidget_p.h> +#include <private/qsgdistancefieldglyphcache_p.h> #include <QtDeclarative/qdeclarativeinfo.h> #include <QtGui/qgraphicssceneevent.h> #include <QtGui/qinputcontext.h> #include <QTextBoundaryFinder> #include <qstyle.h> +#include <qsgtextnode_p.h> +#include <qsgsimplerectnode.h> QT_BEGIN_NAMESPACE +DEFINE_BOOL_CONFIG_OPTION(qmlDisableDistanceField, QML_DISABLE_DISTANCEFIELD) + QWidgetPrivate *qt_widget_private(QWidget *widget); /*! @@ -76,7 +81,7 @@ QWidgetPrivate *qt_widget_private(QWidget *widget); \sa TextEdit, Text, {declarative/text/textselection}{Text Selection example} */ QSGTextInput::QSGTextInput(QSGItem* parent) -: QSGImplicitSizePaintedItem(*(new QSGTextInputPrivate), parent) +: QSGImplicitSizeItem(*(new QSGTextInputPrivate), parent) { Q_D(QSGTextInput); d->init(); @@ -1055,7 +1060,7 @@ void QSGTextInput::keyPressEvent(QKeyEvent* ev) d->control->processKeyEvent(ev); } if (!ev->isAccepted()) - QSGPaintedItem::keyPressEvent(ev); + QSGImplicitSizeItem::keyPressEvent(ev); } void QSGTextInput::inputMethodEvent(QInputMethodEvent *ev) @@ -1068,7 +1073,7 @@ void QSGTextInput::inputMethodEvent(QInputMethodEvent *ev) d->control->processInputMethodEvent(ev); } if (!ev->isAccepted()) - QSGPaintedItem::inputMethodEvent(ev); + QSGImplicitSizeItem::inputMethodEvent(ev); if (wasComposing != (d->control->preeditAreaText().length() > 0)) emit inputMethodComposingChanged(); @@ -1084,7 +1089,7 @@ void QSGTextInput::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) d->control->selectWordAtPos(cursor); event->setAccepted(true); } else { - QSGPaintedItem::mouseDoubleClickEvent(event); + QSGImplicitSizeItem::mouseDoubleClickEvent(event); } } @@ -1129,7 +1134,7 @@ void QSGTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event) moveCursorSelection(d->xToPos(event->pos().x()), d->mouseSelectionMode); event->setAccepted(true); } else { - QSGPaintedItem::mouseMoveEvent(event); + QSGImplicitSizeItem::mouseMoveEvent(event); } } @@ -1152,7 +1157,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( @@ -1218,7 +1223,7 @@ bool QSGTextInput::event(QEvent* ev) handled = d->control->processEvent(ev); } if(!handled) - handled = QSGPaintedItem::event(ev); + handled = QSGImplicitSizeItem::event(ev); return handled; } @@ -1230,7 +1235,7 @@ void QSGTextInput::geometryChanged(const QRectF &newGeometry, updateSize(); updateCursorRectangle(); } - QSGPaintedItem::geometryChanged(newGeometry, oldGeometry); + QSGImplicitSizeItem::geometryChanged(newGeometry, oldGeometry); } int QSGTextInputPrivate::calculateTextWidth() @@ -1284,25 +1289,73 @@ void QSGTextInputPrivate::updateHorizontalScroll() } } -void QSGTextInput::paint(QPainter *p) +QSGNode *QSGTextInput::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data) { - // XXX todo - QRect r = boundingRect().toRect(); - + 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; - QFontMetrics fm = QFontMetrics(d->font); - // the y offset is there to keep the baseline constant in case we have script changes in the text. - QPoint offset(-d->hscroll, fm.ascent() - d->control->ascent()); - d->control->draw(p, offset, r, flags); - p->restore(); + + QSGTextNode *node = static_cast<QSGTextNode *>(oldNode); + if (node == 0) + node = new QSGTextNode(QSGItemPrivate::get(this)->sceneGraphContext()); + d->textNode = node; + + if (!d->textLayoutDirty) { + QSGSimpleRectNode *cursorNode = node->cursorNode(); + if (cursorNode != 0 && !isReadOnly()) { + QFontMetrics fm = QFontMetrics(d->font); + // the y offset is there to keep the baseline constant in case we have script changes in the text. + QPoint offset(-d->hscroll, fm.ascent() - d->control->ascent()); + offset.rx() += d->control->cursorToX(); + + QRect br(boundingRect().toRect()); + 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(); + } + } + } else { + node->deleteContent(); + node->setMatrix(QMatrix4x4()); + + 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); + } + + QTextLayout *textLayout = d->control->textLayout(); + if (!textLayout->text().isEmpty()) { + 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(); + } else { + d->showCursor(); + } + } + + d->textLayoutDirty = false; + } + + return node; } QVariant QSGTextInput::inputMethodQuery(Qt::InputMethodQuery property) const @@ -1754,7 +1807,7 @@ void QSGTextInput::focusInEvent(QFocusEvent *event) openSoftwareInputPanel(); } } - QSGPaintedItem::focusInEvent(event); + QSGImplicitSizeItem::focusInEvent(event); } void QSGTextInput::itemChange(ItemChange change, const ItemChangeData &value) @@ -1793,12 +1846,16 @@ bool QSGTextInput::isInputMethodComposing() const void QSGTextInputPrivate::init() { Q_Q(QSGTextInput); +#if defined(Q_WS_MAC) + control->setThreadChecks(true); +#endif control->setParent(q);//Now mandatory due to accessibility changes control->setCursorWidth(1); control->setPasswordCharacter(QLatin1Char('*')); 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()), @@ -1828,6 +1885,12 @@ void QSGTextInputPrivate::init() selectedTextColor = p.color(QPalette::HighlightedText); selectionColor = p.color(QPalette::Highlight); determineHorizontalAlignment(); + + if (!qmlDisableDistanceField()) { + QTextOption option = control->textLayout()->textOption(); + option.setUseDesignMetrics(true); + control->textLayout()->setTextOption(option); + } } void QSGTextInput::cursorPosChanged() @@ -1898,19 +1961,35 @@ 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()) - update(); - else - update(QRect(r.x() - d->hscroll, r.y(), r.width(), r.height())); + if (!isComponentComplete()) + return; + + if (r.isEmpty()) { + d->textLayoutDirty = true; + } + + update(); } 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(); @@ -1927,7 +2006,6 @@ void QSGTextInput::updateSize(bool needsRedraw) int h = height(); setImplicitHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text. setImplicitWidth(d->calculateTextWidth()); - setContentsSize(boundingRect().size().toSize()); if(w==width() && h==height() && needsRedraw) update(); } |