2 * Copyright 2008 by Aaron Seigo <aseigo@kde.org>
3 * Copyright 2008 Marco Martin <notmart@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Library General Public License as
7 * published by the Free Software Foundation; either version 2, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details
15 * You should have received a copy of the GNU Library General Public
16 * License along with this program; if not, write to the
17 * Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
31 class SvgPanel::Private
35 : bFlags(DrawAllBorders
|ContentAtOrigin
),
36 cachedBackground(0), pos(0,0)
42 delete cachedBackground
;
46 QPixmap
*cachedBackground
;
57 //size of the svg where the size of the "center"
58 //element is contentWidth x contentHeight
59 bool noBorderPadding
: 1;
60 bool stretchBorders
: 1;
63 SvgPanel::SvgPanel(const QString
& imagePath
, QObject
* parent
)
67 d
->background
= new Svg(imagePath
, this);
68 connect(d
->background
, SIGNAL(repaintNeeded()), this, SLOT(updateSizes()));
71 d
->panelSize
= d
->background
->size();
79 void SvgPanel::setFile(const QString
& imagePath
)
81 if (imagePath
== d
->background
->file()) {
85 d
->background
->setFile(imagePath
);
89 QString
SvgPanel::file() const
91 return d
->background
->file();
94 void SvgPanel::setBorderFlags(const BorderFlags flags
)
96 if (flags
== d
->bFlags
) {
104 SvgPanel::BorderFlags
SvgPanel::borderFlags() const
109 void SvgPanel::setPos(const QPointF
& pos
)
114 QPointF
SvgPanel::pos() const
120 void SvgPanel::resize(const QSizeF
& size
)
122 if (!size
.isValid() || size
.width() < 1 || size
.height() < 1 || size
== d
->panelSize
) {
130 qreal
SvgPanel::marginSize(const Plasma::MarginEdge edge
) const
132 if (d
->noBorderPadding
) {
137 case Plasma::TopMargin
:
141 case Plasma::LeftMargin
:
145 case Plasma::RightMargin
:
146 return d
->rightWidth
;
149 //Plasma::BottomMargin
151 return d
->bottomHeight
;
156 void SvgPanel::paint(QPainter
* painter
, const QRectF
& rect
)
158 bool origined
= d
->bFlags
& ContentAtOrigin
;
159 const int topWidth
= d
->background
->elementSize("top").width();
160 const int leftHeight
= d
->background
->elementSize("left").height();
161 const int topOffset
= origined
? 0 - d
->topHeight
: 0;
162 const int leftOffset
= origined
? 0 - d
->leftWidth
: 0;
164 if (!d
->cachedBackground
) {
165 const int contentWidth
= d
->panelSize
.width() - d
->leftWidth
- d
->rightWidth
;
166 const int contentHeight
= d
->panelSize
.height() - d
->topHeight
- d
->bottomHeight
;
169 int rightOffset
= contentWidth
;
170 int bottomOffset
= contentHeight
;
172 delete d
->cachedBackground
;
173 d
->cachedBackground
= new QPixmap(d
->leftWidth
+ contentWidth
+ d
->rightWidth
,
174 d
->topHeight
+ contentHeight
+ d
->bottomHeight
);
175 d
->cachedBackground
->fill(Qt::transparent
);
176 QPainter
p(d
->cachedBackground
);
177 p
.setCompositionMode(QPainter::CompositionMode_Source
);
178 p
.setRenderHint(QPainter::SmoothPixmapTransform
);
181 p
.translate(d
->leftWidth
, d
->topHeight
);
184 //FIXME: This is a hack to fix a drawing problems with svg files where a thin transparent border is drawn around the svg image.
185 // the transparent border around the svg seems to vary in size depending on the size of the svg and as a result increasing the
186 // svg image by 2 all around didn't resolve the issue. For now it resizes based on the border size.
190 if (contentHeight
> 0 && contentWidth
> 0) {
191 QSizeF scaledSize
= QSizeF(d
->panelSize
.width() -
192 (d
->leftWidth
+ d
->rightWidth
) +
193 d
->panelSize
.width()*(((qreal
)(d
->leftWidth
+ d
->rightWidth
)) / d
->panelSize
.width()),
194 d
->panelSize
.height() -
195 (d
->topHeight
+ d
->bottomHeight
) +
196 d
->panelSize
.height()*(((qreal
)(d
->topHeight
+ d
->bottomHeight
)) / d
->panelSize
.height()));
198 d
->background
->resize(scaledSize
.width(), scaledSize
.height());
199 d
->background
->paint(&p
, QRect(contentLeft
- d
->leftWidth
, contentTop
- d
->topHeight
,
200 contentWidth
+ d
->leftWidth
*2, contentHeight
+ d
->topHeight
*2),
202 d
->background
->resize();
206 if (d
->bFlags
& DrawTopBorder
) {
208 contentTop
= d
->topHeight
;
209 bottomOffset
+= d
->topHeight
;
212 if (d
->bFlags
& DrawLeftBorder
) {
213 d
->background
->paint(&p
, QRect(leftOffset
, topOffset
, d
->leftWidth
, d
->topHeight
), "topleft");
216 contentLeft
= d
->leftWidth
;
217 rightOffset
= contentWidth
+ d
->leftWidth
;
221 if (d
->bFlags
& DrawRightBorder
) {
222 d
->background
->paint(&p
, QRect(rightOffset
, topOffset
, d
->rightWidth
, d
->topHeight
), "topright");
226 if (d
->bFlags
& DrawBottomBorder
) {
227 if (d
->bFlags
& DrawLeftBorder
) {
228 d
->background
->paint(&p
, QRect(leftOffset
, bottomOffset
, d
->leftWidth
, d
->bottomHeight
), "bottomleft");
231 contentLeft
= d
->leftWidth
;
232 rightOffset
= contentWidth
+ d
->leftWidth
;
236 if (d
->bFlags
& DrawRightBorder
) {
237 d
->background
->paint(&p
, QRect(rightOffset
, bottomOffset
, d
->rightWidth
, d
->bottomHeight
), "bottomright");
242 if (d
->stretchBorders
) {
243 if (d
->bFlags
& DrawLeftBorder
) {
244 d
->background
->paint(&p
, QRect(leftOffset
, contentTop
, d
->leftWidth
, contentHeight
), "left");
247 if (d
->bFlags
& DrawRightBorder
) {
248 d
->background
->paint(&p
, QRect(rightOffset
, contentTop
, d
->rightWidth
, contentHeight
), "right");
251 if (d
->bFlags
& DrawTopBorder
) {
252 d
->background
->paint(&p
, QRect(contentLeft
, topOffset
, contentWidth
, d
->topHeight
), "top");
255 if (d
->bFlags
& DrawBottomBorder
) {
256 d
->background
->paint(&p
, QRect(contentLeft
, bottomOffset
, contentWidth
, d
->bottomHeight
), "bottom");
259 if (d
->bFlags
& DrawLeftBorder
) {
260 QPixmap
left(d
->leftWidth
, leftHeight
);
261 left
.fill(Qt::transparent
);
264 QPainter
sidePainter(&left
);
265 sidePainter
.setCompositionMode(QPainter::CompositionMode_Source
);
266 d
->background
->paint(&sidePainter
, QPoint(0, 0), "left");
269 p
.drawTiledPixmap(QRect(leftOffset
, contentTop
, d
->leftWidth
, contentHeight
), left
);
272 if (d
->bFlags
& DrawRightBorder
) {
273 QPixmap
right(d
->rightWidth
, leftHeight
);
274 right
.fill(Qt::transparent
);
277 QPainter
sidePainter(&right
);
278 sidePainter
.setCompositionMode(QPainter::CompositionMode_Source
);
279 d
->background
->paint(&sidePainter
, QPoint(0, 0), "right");
282 p
.drawTiledPixmap(QRect(rightOffset
, contentTop
, d
->rightWidth
, contentHeight
), right
);
285 if (d
->bFlags
& DrawTopBorder
) {
286 QPixmap
top(topWidth
, d
->topHeight
);
287 top
.fill(Qt::transparent
);
290 QPainter
sidePainter(&top
);
291 sidePainter
.setCompositionMode(QPainter::CompositionMode_Source
);
292 d
->background
->paint(&sidePainter
, QPoint(0, 0), "top");
295 p
.drawTiledPixmap(QRect(contentLeft
, topOffset
, contentWidth
, d
->topHeight
), top
);
298 if (d
->bFlags
& DrawBottomBorder
) {
299 QPixmap
bottom(topWidth
, d
->bottomHeight
);
300 bottom
.fill(Qt::transparent
);
303 QPainter
sidePainter(&bottom
);
304 sidePainter
.setCompositionMode(QPainter::CompositionMode_Source
);
305 d
->background
->paint(&sidePainter
, QPoint(0, 0), "bottom");
308 p
.drawTiledPixmap(QRect(contentLeft
, bottomOffset
, contentWidth
, d
->bottomHeight
), bottom
);
312 // re-enable this once Qt's svg rendering is un-buggered
313 //resize(contentWidth, contentHeight);
314 //paint(&p, QRect(contentLeft, contentTop, contentWidth, contentHeight), "center");
317 //p2->drawPixmap(paintRect, *cachedBackground, paintRect.translated(-leftOffset,-topOffset));
318 painter
->drawPixmap(rect
, *d
->cachedBackground
, rect
.translated(-d
->pos
.x()-leftOffset
,-d
->pos
.y()-topOffset
));
321 void SvgPanel::updateSizes()
323 delete d
->cachedBackground
;
324 d
->cachedBackground
= 0;
325 d
->background
->resize();
326 if (d
->bFlags
& DrawTopBorder
) {
327 d
->topHeight
= d
->background
->elementSize("top").height();
332 if (d
->bFlags
& DrawLeftBorder
) {
333 d
->leftWidth
= d
->background
->elementSize("left").width();
338 if (d
->bFlags
& DrawRightBorder
) {
339 d
->rightWidth
= d
->background
->elementSize("right").width();
344 if (d
->bFlags
& DrawBottomBorder
) {
345 d
->bottomHeight
= d
->background
->elementSize("bottom").height();
350 //since it's rectangular, topWidth and bottomWidth must be the same
351 d
->noBorderPadding
= d
->background
->elementExists("hint-no-border-padding");
352 d
->stretchBorders
= d
->background
->elementExists("hint-stretch-borders");
353 emit
repaintNeeded();
356 } // Plasma namespace
358 #include "svgpanel.moc"