Move some of the code and make some API public

It's unreasonable to use private API, so make everything public API so that
every user of FrameSvg have as much features exposed as possible.

Reviewed by David Edmundson
This commit is contained in:
Aleix Pol 2014-07-21 15:44:25 +02:00
parent 565b2b6f51
commit 47c7688d02
6 changed files with 65 additions and 80 deletions

View File

@ -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; i<oldNode->childCount(); ++i) {
FrameItemNode* it = static_cast<FrameItemNode*>(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"

View File

@ -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;

View File

@ -24,8 +24,6 @@
#include <QDebug>
#include <QPropertyAnimation>
#include "framesvgitem.h"
#include <kdeclarative/qmlobject.h>
ToolTipDialog::ToolTipDialog(QQuickItem *parent)

View File

@ -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<QString, FrameData *>::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"

View File

@ -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())

View File

@ -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<FrameSvg *, int> 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;