diff --git a/src/declarativeimports/core/framesvgitem.cpp b/src/declarativeimports/core/framesvgitem.cpp index b85a31ee5..c721f7ab9 100644 --- a/src/declarativeimports/core/framesvgitem.cpp +++ b/src/declarativeimports/core/framesvgitem.cpp @@ -68,21 +68,23 @@ public: } if (m_fitMode == Tile || m_fitMode == FastStretch) { - QString elementId = m_frameSvg->actualPrefix() + FrameSvgPrivate::borderToElementId(m_border); + QString elementId = m_frameSvg->frameSvg()->actualPrefix() + FrameSvg::borderToElementId(m_border); m_elementNativeSize = m_frameSvg->frameSvg()->elementSize(elementId); - updateTexture(m_elementNativeSize, elementId); + updateTexture(m_elementNativeSize, elementId, false); } } - void updateTexture(const QSize &size, const QString &elementId) + void updateTexture(const QSize &size, const QString &elementId, bool composeOverBorder) { QImage image = m_frameSvg->frameSvg()->image(size, elementId); + QString prefix = m_frameSvg->frameSvg()->actualPrefix(); + //in compose over border we paint the center over the full size //then blend in an alpha mask generated from the corners to //remove the garbage left in the corners - if (m_border == FrameSvg::NoBorder && m_fitMode == Stretch && m_frameSvg->frameData()->composeOverBorder) { + if (m_border == FrameSvg::NoBorder && m_fitMode == Stretch && composeOverBorder) { QPixmap pixmap = QPixmap::fromImage(image); QPainter p(&pixmap); p.setCompositionMode(QPainter::CompositionMode_DestinationIn); @@ -94,11 +96,9 @@ public: setTexture(texture); } - void reposition(const QRect& frameGeometry) + void reposition(const QRect& frameGeometry, QSize& fullSize) { - FrameData* frameData = m_frameSvg->frameData(); - - QRect nodeRect = FrameSvgPrivate::sectionRect(frameData, m_border, frameGeometry); + QRect nodeRect = FrameSvg::sectionRect(m_border, frameGeometry, fullSize); //ensure we're not passing a weird rectangle to updateTexturedRectGeometry if(!nodeRect.isValid() || nodeRect.isEmpty()) @@ -113,9 +113,18 @@ public: textureRect.setHeight(nodeRect.height() / m_elementNativeSize.height()); } } else if (m_fitMode == Stretch) { + QString prefix = m_frameSvg->frameSvg()->actualPrefix(); + bool composeOverBorder = (m_border == FrameSvg::NoBorder) && (m_frameSvg->frameSvg()->hasElement(prefix % "hint-compose-over-border") && + m_frameSvg->frameSvg()->hasElement("mask-" % prefix % "center")); + + QString elementId = prefix + FrameSvg::borderToElementId(m_border); + + if (composeOverBorder) { + nodeRect = QRect(QPoint(0,0), fullSize); + } + //re-render the SVG at new size - QString elementId = m_frameSvg->actualPrefix() + FrameSvgPrivate::borderToElementId(m_border); - updateTexture(nodeRect.size(), elementId); + updateTexture(nodeRect.size(), elementId, composeOverBorder); } // for fast stretch, we don't have to do anything QSGGeometry::updateTexturedRectGeometry(geometry(), nodeRect, textureRect); @@ -323,11 +332,6 @@ void FrameSvgItem::geometryChanged(const QRectF &newGeometry, void FrameSvgItem::doUpdate() { - FrameData *frame = frameData(); - if (!frame) { - return; - } - if (implicitWidth() <= 0) { setImplicitWidth(m_frameSvg->marginSize(Plasma::Types::LeftMargin) + m_frameSvg->marginSize(Plasma::Types::RightMargin)); } @@ -336,7 +340,8 @@ void FrameSvgItem::doUpdate() setImplicitHeight(m_frameSvg->marginSize(Plasma::Types::TopMargin) + m_frameSvg->marginSize(Plasma::Types::BottomMargin)); } - bool hasOverlay = !actualPrefix().startsWith(QLatin1String("mask-")) && m_frameSvg->hasElement(actualPrefix() % "overlay"); + QString prefix = m_frameSvg->actualPrefix(); + bool hasOverlay = !prefix.startsWith(QStringLiteral("mask-")) && m_frameSvg->hasElement(prefix % "overlay"); m_fastPath = !hasOverlay; m_textureChanged = true; update(); @@ -392,18 +397,14 @@ QSGNode *FrameSvgItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaint oldNode = 0; } - FrameData* frame = frameData(); - if (!frame) { - qWarning() << "no frame for" << imagePath() << prefix(); - delete oldNode; - return 0; - } - if (!oldNode) { oldNode = new QSGNode; - FrameItemNode::FitMode borderFitMode = frame->stretchBorders ? FrameItemNode::Stretch : FrameItemNode::Tile; - FrameItemNode::FitMode centerFitMode = frame->tileCenter ? FrameItemNode::Tile: FrameItemNode::Stretch; + QString prefix = m_frameSvg->actualPrefix(); + bool tileCenter = (m_frameSvg->hasElement("hint-tile-center") || m_frameSvg->hasElement(prefix % "hint-tile-center")); + bool stretchBorders = (m_frameSvg->hasElement("hint-stretch-borders") || m_frameSvg->hasElement(prefix % "hint-stretch-borders")); + FrameItemNode::FitMode borderFitMode = stretchBorders ? FrameItemNode::Stretch : FrameItemNode::Tile; + FrameItemNode::FitMode centerFitMode = tileCenter ? FrameItemNode::Tile: FrameItemNode::Stretch; new FrameItemNode(this, FrameSvg::NoBorder, centerFitMode, oldNode); //needs to be de first, in case of composeOverBorder new FrameItemNode(this, FrameSvg::TopBorder | FrameSvg::LeftBorder, FrameItemNode::FastStretch, oldNode); @@ -420,10 +421,11 @@ QSGNode *FrameSvgItem::updatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaint } if (m_sizeChanged) { - QRect geometry = m_frameSvg->d->contentGeometry(frame, QSize(width(), height())); + QSize frameSize(width(), height()); + QRect geometry = m_frameSvg->contentsRect().toRect(); for(int i = 0; ichildCount(); ++i) { FrameItemNode* it = static_cast(oldNode->childAtIndex(i)); - it->reposition(geometry); + it->reposition(geometry, frameSize); } m_sizeChanged = false; @@ -468,17 +470,6 @@ void FrameSvgItem::updateDevicePixelRatio() m_textureChanged = true; } -FrameData* FrameSvgItem::frameData() const -{ - //We need to do that prefix, otherwise we are fetching the requested prefix, which might be different - return m_frameSvg->d->frames.value(actualPrefix()); -} - -QString FrameSvgItem::actualPrefix() const -{ - return m_frameSvg->d->prefix; -} - } // Plasma namespace #include "framesvgitem.moc" diff --git a/src/declarativeimports/core/framesvgitem.h b/src/declarativeimports/core/framesvgitem.h index 672529994..0b39c7052 100644 --- a/src/declarativeimports/core/framesvgitem.h +++ b/src/declarativeimports/core/framesvgitem.h @@ -31,7 +31,6 @@ namespace Plasma { class FrameSvg; -class FrameData; class SVGTextureNode; class FrameSvgItemMargins : public QObject @@ -168,8 +167,6 @@ public: Q_INVOKABLE bool hasElementPrefix(const QString &prefix) const; virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *); - FrameData* frameData() const; - QString actualPrefix() const; protected: virtual void componentComplete(); @@ -186,7 +183,6 @@ private Q_SLOTS: void updateDevicePixelRatio(); private: - Plasma::FrameSvg *m_frameSvg; FrameSvgItemMargins *m_margins; FrameSvgItemMargins *m_fixedMargins; diff --git a/src/declarativeimports/core/tooltipdialog.cpp b/src/declarativeimports/core/tooltipdialog.cpp index e62ed6e7f..872f9692f 100644 --- a/src/declarativeimports/core/tooltipdialog.cpp +++ b/src/declarativeimports/core/tooltipdialog.cpp @@ -24,8 +24,6 @@ #include #include -#include "framesvgitem.h" - #include ToolTipDialog::ToolTipDialog(QQuickItem *parent) diff --git a/src/plasma/framesvg.cpp b/src/plasma/framesvg.cpp index d3a61b9c0..0a03d14c1 100644 --- a/src/plasma/framesvg.cpp +++ b/src/plasma/framesvg.cpp @@ -474,14 +474,9 @@ void FrameSvg::getFixedMargins(qreal &left, qreal &top, qreal &right, qreal &bot QRectF FrameSvg::contentsRect() const { - QSizeF size(frameSize()); - - if (size.isValid()) { - QRectF rect(QPointF(0, 0), size); - FrameData *frame = d->frames[d->prefix]; - - return rect.adjusted(frame->leftMargin, frame->topMargin, - -frame->rightMargin, -frame->bottomMargin); + QHash::const_iterator it = d->frames.constFind(d->prefix); + if (it != d->frames.constEnd()) { + return d->contentGeometry(*it, (*it)->frameSize); } else { return QRectF(); } @@ -814,7 +809,7 @@ void FrameSvgPrivate::generateFrameBackground(FrameData *frame) p.setRenderHint(QPainter::SmoothPixmapTransform); QRect contentRect = contentGeometry(frame, size); - paintCenter(p, frame, contentRect.size(), size); + paintCenter(p, frame, contentRect, size); paintCorner(p, frame, FrameSvg::LeftBorder|FrameSvg::TopBorder, contentRect); paintCorner(p, frame, FrameSvg::RightBorder|FrameSvg::TopBorder, contentRect); @@ -831,7 +826,7 @@ void FrameSvgPrivate::generateFrameBackground(FrameData *frame) paintBorder(p, frame, FrameSvg::BottomBorder, QSize(topWidth, frame->bottomHeight), contentRect); } -QRect FrameSvgPrivate::sectionRect(FrameData* frame, Plasma::FrameSvg::EnabledBorders borders, const QRect& contentRect) +QRect FrameSvg::sectionRect(Plasma::FrameSvg::EnabledBorders borders, const QRect& contentRect, const QSize& fullSize) { //don't use QRect corner methods here, they have semantics that might come as unexpected. //prefer constructing the points explicitly. e.g. from QRect::topRight docs: @@ -839,23 +834,23 @@ QRect FrameSvgPrivate::sectionRect(FrameData* frame, Plasma::FrameSvg::EnabledBo switch(borders) { case FrameSvg::NoBorder: - return frame->composeOverBorder ? QRect(0,0, contentRect.width()+frame->leftWidth+frame->rightWidth, contentRect.height()+frame->topHeight+frame->bottomHeight) : contentRect; + return contentRect; case FrameSvg::TopBorder: - return QRect(QPoint(contentRect.left(), 0), QSize(contentRect.width(), frame->topHeight)); + return QRect(QPoint(contentRect.left(), 0), QSize(contentRect.width(), contentRect.top())); case FrameSvg::BottomBorder: - return QRect(QPoint(contentRect.left(), contentRect.bottom()+1), QSize(contentRect.width(), frame->bottomHeight)); + return QRect(QPoint(contentRect.left(), contentRect.bottom()+1), QSize(contentRect.width(), fullSize.height()-contentRect.bottom()-1)); case FrameSvg::LeftBorder: - return QRect(QPoint(0, contentRect.top()), QSize(frame->leftWidth, contentRect.height())); + return QRect(QPoint(0, contentRect.top()), QSize(contentRect.left(), contentRect.height())); case FrameSvg::RightBorder: - return QRect(QPoint(contentRect.right()+1, contentRect.top()), QSize(frame->rightWidth, contentRect.height())); + return QRect(QPoint(contentRect.right()+1, contentRect.top()), QSize(fullSize.width()-contentRect.right()-1, contentRect.height())); case FrameSvg::TopBorder | FrameSvg::LeftBorder: - return QRect(QPoint(0, 0), QSize(frame->leftWidth, frame->topHeight)); + return QRect(QPoint(0, 0), QSize(contentRect.left(), contentRect.top())); case FrameSvg::TopBorder | FrameSvg::RightBorder: - return QRect(QPoint(contentRect.right()+1, 0), QSize(frame->rightWidth, frame->topHeight)); + return QRect(QPoint(contentRect.right()+1, 0), QSize(fullSize.width()-contentRect.right()-1, contentRect.top())); case FrameSvg::BottomBorder | FrameSvg::LeftBorder: - return QRect(QPoint(0, contentRect.bottom()+1), QSize(frame->leftWidth, frame->bottomHeight)); + return QRect(QPoint(0, contentRect.bottom()+1), QSize(contentRect.left(), fullSize.height()-contentRect.bottom()-1)); case FrameSvg::BottomBorder | FrameSvg::RightBorder: - return QRect(QPoint(contentRect.right()+1, contentRect.bottom()+1), QSize(frame->rightWidth, frame->bottomHeight)); + return QRect(QPoint(contentRect.right()+1, contentRect.bottom()+1), QSize(fullSize.width()-contentRect.right()-1, fullSize.height()-contentRect.bottom()-1)); default: qWarning() << "unrecognized border" << borders; return QRect(); @@ -878,9 +873,9 @@ QRect FrameSvgPrivate::contentGeometry(FrameData* frame, const QSize& size) cons return contentRect; } -void FrameSvgPrivate::paintCenter(QPainter& p, FrameData* frame, const QSize& contentSize, const QSize& fullSize) +void FrameSvgPrivate::paintCenter(QPainter& p, FrameData* frame, const QRect& contentRect, const QSize& fullSize) { - if (!contentSize.isEmpty()) { + if (!contentRect.isEmpty()) { const QString centerElementId = prefix % "center"; if (frame->tileCenter) { QSize centerTileSize = q->elementSize(centerElementId); @@ -894,15 +889,14 @@ void FrameSvgPrivate::paintCenter(QPainter& p, FrameData* frame, const QSize& co if (frame->composeOverBorder) { p.drawTiledPixmap(QRect(QPoint(0, 0), fullSize), center); } else { - p.drawTiledPixmap(QRect(QPoint(frame->leftWidth, frame->topHeight), contentSize), center); + p.drawTiledPixmap(FrameSvg::sectionRect(FrameSvg::NoBorder, contentRect, fullSize), center); } } else { if (frame->composeOverBorder) { q->paint(&p, QRect(QPoint(0, 0), fullSize), centerElementId); } else { - q->paint(&p, QRect(QPoint(frame->leftWidth, frame->topHeight), contentSize), - centerElementId); + q->paint(&p, FrameSvg::sectionRect(FrameSvg::NoBorder, contentRect, fullSize), centerElementId); } } } @@ -916,10 +910,10 @@ void FrameSvgPrivate::paintCenter(QPainter& p, FrameData* frame, const QSize& co void FrameSvgPrivate::paintBorder(QPainter& p, FrameData* frame, const FrameSvg::EnabledBorders borders, const QSize& size, const QRect& contentRect) const { - QString side = prefix % borderToElementId(borders); + QString side = prefix % FrameSvg::borderToElementId(borders); if (frame->enabledBorders & borders && q->hasElement(side) && !size.isEmpty()) { if (frame->stretchBorders) { - q->paint(&p, sectionRect(frame, borders, contentRect), side); + q->paint(&p, FrameSvg::sectionRect(borders, contentRect, frame->frameSize), side); } else { QPixmap px(size); px.fill(Qt::transparent); @@ -928,20 +922,20 @@ void FrameSvgPrivate::paintBorder(QPainter& p, FrameData* frame, const FrameSvg: sidePainter.setCompositionMode(QPainter::CompositionMode_Source); q->paint(&sidePainter, QRect(QPoint(0, 0), size), side); - p.drawTiledPixmap(sectionRect(frame, borders, contentRect), px); + p.drawTiledPixmap(FrameSvg::sectionRect(borders, contentRect, frame->frameSize), px); } } } void FrameSvgPrivate::paintCorner(QPainter& p, FrameData* frame, Plasma::FrameSvg::EnabledBorders border, const QRect& contentRect) const { - QString corner = prefix % borderToElementId(border); + QString corner = prefix % FrameSvg::borderToElementId(border); if (frame->enabledBorders & border && q->hasElement(corner)) { - q->paint(&p, sectionRect(frame, border, contentRect), corner); + q->paint(&p, FrameSvg::sectionRect(border, contentRect, frame->frameSize), corner); } } -QString FrameSvgPrivate::borderToElementId(FrameSvg::EnabledBorders borders) +QString FrameSvg::borderToElementId(FrameSvg::EnabledBorders borders) { switch(borders) { case FrameSvg::NoBorder: @@ -1159,6 +1153,11 @@ int FrameData::refcount() const return references.count(); } +QString FrameSvg::actualPrefix() const +{ + return d->prefix; +} + } // Plasma namespace #include "moc_framesvg.cpp" diff --git a/src/plasma/framesvg.h b/src/plasma/framesvg.h index fb67be10f..201e93ed9 100644 --- a/src/plasma/framesvg.h +++ b/src/plasma/framesvg.h @@ -287,10 +287,13 @@ public: */ Q_INVOKABLE void paintFrame(QPainter *painter, const QPointF &pos = QPointF(0, 0)); + QString actualPrefix() const; + static QString borderToElementId(FrameSvg::EnabledBorders borders); + static QRect sectionRect(Plasma::FrameSvg::EnabledBorders borders, const QRect& contentRect, const QSize& fullSize); + protected: FrameSvgPrivate *const d; friend class FrameData; - friend class FrameSvgItem; Q_PRIVATE_SLOT(d, void updateSizes()) Q_PRIVATE_SLOT(d, void updateNeeded()) diff --git a/src/plasma/private/framesvg_p.h b/src/plasma/private/framesvg_p.h index d263b619a..560e1b21c 100644 --- a/src/plasma/private/framesvg_p.h +++ b/src/plasma/private/framesvg_p.h @@ -32,7 +32,7 @@ namespace Plasma { -class PLASMA_EXPORT FrameData +class FrameData { public: FrameData(FrameSvg *svg, const QString &p) @@ -126,7 +126,7 @@ public: QHash references; }; -class PLASMA_EXPORT FrameSvgPrivate +class FrameSvgPrivate { public: FrameSvgPrivate(FrameSvg *psvg) @@ -150,9 +150,7 @@ public: QSizeF frameSize(FrameData *frame) const; void paintBorder(QPainter& p, FrameData* frame, Plasma::FrameSvg::EnabledBorders border, const QSize& originalSize, const QRect& output) const; void paintCorner(QPainter& p, FrameData* frame, Plasma::FrameSvg::EnabledBorders border, const QRect& output) const; - void paintCenter(QPainter& p, FrameData* frame, const QSize& contentSize, const QSize& fullSize); - static QString borderToElementId(Plasma::FrameSvg::EnabledBorders borders); - static QRect sectionRect(FrameData* frame, Plasma::FrameSvg::EnabledBorders borders, const QRect& contentRect); + void paintCenter(QPainter& p, FrameData* frame, const QRect& contentRect, const QSize& fullSize); QRect contentGeometry(FrameData* frame, const QSize& size) const; Types::Location location;