reworked how shaped windows with svg backgrounds are obtained:
there is a new function PanelSvg::mask() that returns a qbitmap of the areas of the svg with alpha=0 that can be used to create the mask of the window, at the moment used in tooltip and dialog (krunner still to come). so now windows that uses svg backgrounds should always set PanelSvg::mask() as their own mask, regardless if composite is active or not. In this commit there are also two (identical) svgs for opaque tooltips and dialogs with pixelated rounded borders that looks good without antialiasing (and unlike the previous version they are vector based now). svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=782727
This commit is contained in:
parent
d9706ec25a
commit
afdb5e84a0
@ -28,6 +28,7 @@
|
|||||||
#ifdef Q_WS_X11
|
#ifdef Q_WS_X11
|
||||||
#include <QX11Info>
|
#include <QX11Info>
|
||||||
#endif
|
#endif
|
||||||
|
#include <QBitmap>
|
||||||
#include <QGraphicsView>
|
#include <QGraphicsView>
|
||||||
#include <QtGui/QGraphicsSceneEvent>
|
#include <QtGui/QGraphicsSceneEvent>
|
||||||
|
|
||||||
@ -95,6 +96,8 @@ void Dialog::paintEvent(QPaintEvent *e)
|
|||||||
void Dialog::resizeEvent(QResizeEvent *e)
|
void Dialog::resizeEvent(QResizeEvent *e)
|
||||||
{
|
{
|
||||||
d->background->resize(e->size());
|
d->background->resize(e->size());
|
||||||
|
|
||||||
|
setMask(d->background->mask());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dialog::position(QGraphicsSceneEvent *event, const QRectF boundingRect, QPointF scenePos)
|
void Dialog::position(QGraphicsSceneEvent *event, const QRectF boundingRect, QPointF scenePos)
|
||||||
|
161
svgpanel.cpp
161
svgpanel.cpp
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include <QPainter>
|
#include <QPainter>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
|
#include <QBitmap>
|
||||||
|
|
||||||
#include <KDebug>
|
#include <KDebug>
|
||||||
|
|
||||||
@ -42,6 +43,8 @@ public:
|
|||||||
delete cachedBackground;
|
delete cachedBackground;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void generateBackground();
|
||||||
|
|
||||||
BorderFlags bFlags;
|
BorderFlags bFlags;
|
||||||
QPixmap *cachedBackground;
|
QPixmap *cachedBackground;
|
||||||
Svg *background;
|
Svg *background;
|
||||||
@ -153,32 +156,41 @@ qreal SvgPanel::marginSize(const Plasma::MarginEdge edge) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgPanel::paint(QPainter* painter, const QRectF& rect)
|
QBitmap SvgPanel::mask() const
|
||||||
{
|
{
|
||||||
bool origined = d->bFlags & ContentAtOrigin;
|
|
||||||
const int topWidth = d->background->elementSize("top").width();
|
|
||||||
const int leftHeight = d->background->elementSize("left").height();
|
|
||||||
const int topOffset = origined ? 0 - d->topHeight : 0;
|
|
||||||
const int leftOffset = origined ? 0 - d->leftWidth : 0;
|
|
||||||
|
|
||||||
if (!d->cachedBackground) {
|
if (!d->cachedBackground) {
|
||||||
const int contentWidth = d->panelSize.width() - d->leftWidth - d->rightWidth;
|
d->generateBackground();
|
||||||
const int contentHeight = d->panelSize.height() - d->topHeight - d->bottomHeight;
|
}
|
||||||
|
|
||||||
|
return d->cachedBackground->alphaChannel().createMaskFromColor(Qt::black);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SvgPanel::Private::generateBackground()
|
||||||
|
{
|
||||||
|
bool origined = bFlags & ContentAtOrigin;
|
||||||
|
const int topWidth = background->elementSize("top").width();
|
||||||
|
const int leftHeight = background->elementSize("left").height();
|
||||||
|
const int topOffset = origined ? 0 - topHeight : 0;
|
||||||
|
const int leftOffset = origined ? 0 - leftWidth : 0;
|
||||||
|
|
||||||
|
if (!cachedBackground) {
|
||||||
|
const int contentWidth = panelSize.width() - leftWidth - rightWidth;
|
||||||
|
const int contentHeight = panelSize.height() - topHeight - bottomHeight;
|
||||||
int contentTop = 0;
|
int contentTop = 0;
|
||||||
int contentLeft = 0;
|
int contentLeft = 0;
|
||||||
int rightOffset = contentWidth;
|
int rightOffset = contentWidth;
|
||||||
int bottomOffset = contentHeight;
|
int bottomOffset = contentHeight;
|
||||||
|
|
||||||
delete d->cachedBackground;
|
delete cachedBackground;
|
||||||
d->cachedBackground = new QPixmap(d->leftWidth + contentWidth + d->rightWidth,
|
cachedBackground = new QPixmap(leftWidth + contentWidth + rightWidth,
|
||||||
d->topHeight + contentHeight + d->bottomHeight);
|
topHeight + contentHeight + bottomHeight);
|
||||||
d->cachedBackground->fill(Qt::transparent);
|
cachedBackground->fill(Qt::transparent);
|
||||||
QPainter p(d->cachedBackground);
|
QPainter p(cachedBackground);
|
||||||
p.setCompositionMode(QPainter::CompositionMode_Source);
|
p.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
p.setRenderHint(QPainter::SmoothPixmapTransform);
|
||||||
|
|
||||||
if (origined) {
|
if (origined) {
|
||||||
p.translate(d->leftWidth, d->topHeight);
|
p.translate(leftWidth, topHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME: This is a hack to fix a drawing problems with svg files where a thin transparent border is drawn around the svg image.
|
//FIXME: This is a hack to fix a drawing problems with svg files where a thin transparent border is drawn around the svg image.
|
||||||
@ -188,124 +200,124 @@ void SvgPanel::paint(QPainter* painter, const QRectF& rect)
|
|||||||
|
|
||||||
//CENTER
|
//CENTER
|
||||||
if (contentHeight > 0 && contentWidth > 0) {
|
if (contentHeight > 0 && contentWidth > 0) {
|
||||||
QSizeF scaledSize = QSizeF(d->panelSize.width() -
|
QSizeF scaledSize = QSizeF(panelSize.width() -
|
||||||
(d->leftWidth + d->rightWidth) +
|
(leftWidth + rightWidth) +
|
||||||
d->panelSize.width()*(((qreal)(d->leftWidth + d->rightWidth)) / d->panelSize.width()),
|
panelSize.width()*(((qreal)(leftWidth + rightWidth)) / panelSize.width()),
|
||||||
d->panelSize.height() -
|
panelSize.height() -
|
||||||
(d->topHeight + d->bottomHeight) +
|
(topHeight + bottomHeight) +
|
||||||
d->panelSize.height()*(((qreal)(d->topHeight + d->bottomHeight)) / d->panelSize.height()));
|
panelSize.height()*(((qreal)(topHeight + bottomHeight)) / panelSize.height()));
|
||||||
|
|
||||||
d->background->resize(scaledSize.width(), scaledSize.height());
|
background->resize(scaledSize.width(), scaledSize.height());
|
||||||
d->background->paint(&p, QRect(contentLeft - d->leftWidth, contentTop - d->topHeight,
|
background->paint(&p, QRect(contentLeft - leftWidth, contentTop - topHeight,
|
||||||
contentWidth + d->leftWidth*2, contentHeight + d->topHeight*2),
|
contentWidth + leftWidth*2, contentHeight + topHeight*2),
|
||||||
"center");
|
"center");
|
||||||
d->background->resize();
|
background->resize();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Corners
|
// Corners
|
||||||
if (d->bFlags & DrawTopBorder) {
|
if (bFlags & DrawTopBorder) {
|
||||||
if (!origined) {
|
if (!origined) {
|
||||||
contentTop = d->topHeight;
|
contentTop = topHeight;
|
||||||
bottomOffset += d->topHeight;
|
bottomOffset += topHeight;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawLeftBorder) {
|
if (bFlags & DrawLeftBorder) {
|
||||||
d->background->paint(&p, QRect(leftOffset, topOffset, d->leftWidth, d->topHeight), "topleft");
|
background->paint(&p, QRect(leftOffset, topOffset, leftWidth, topHeight), "topleft");
|
||||||
|
|
||||||
if (!origined) {
|
if (!origined) {
|
||||||
contentLeft = d->leftWidth;
|
contentLeft = leftWidth;
|
||||||
rightOffset = contentWidth + d->leftWidth;
|
rightOffset = contentWidth + leftWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawRightBorder) {
|
if (bFlags & DrawRightBorder) {
|
||||||
d->background->paint(&p, QRect(rightOffset, topOffset, d->rightWidth, d->topHeight), "topright");
|
background->paint(&p, QRect(rightOffset, topOffset, rightWidth, topHeight), "topright");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawBottomBorder) {
|
if (bFlags & DrawBottomBorder) {
|
||||||
if (d->bFlags & DrawLeftBorder) {
|
if (bFlags & DrawLeftBorder) {
|
||||||
d->background->paint(&p, QRect(leftOffset, bottomOffset, d->leftWidth, d->bottomHeight), "bottomleft");
|
background->paint(&p, QRect(leftOffset, bottomOffset, leftWidth, bottomHeight), "bottomleft");
|
||||||
|
|
||||||
if (!origined) {
|
if (!origined) {
|
||||||
contentLeft = d->leftWidth;
|
contentLeft = leftWidth;
|
||||||
rightOffset = contentWidth + d->leftWidth;
|
rightOffset = contentWidth + leftWidth;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawRightBorder) {
|
if (bFlags & DrawRightBorder) {
|
||||||
d->background->paint(&p, QRect(rightOffset, bottomOffset, d->rightWidth, d->bottomHeight), "bottomright");
|
background->paint(&p, QRect(rightOffset, bottomOffset, rightWidth, bottomHeight), "bottomright");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sides
|
// Sides
|
||||||
if (d->stretchBorders) {
|
if (stretchBorders) {
|
||||||
if (d->bFlags & DrawLeftBorder) {
|
if (bFlags & DrawLeftBorder) {
|
||||||
d->background->paint(&p, QRect(leftOffset, contentTop, d->leftWidth, contentHeight), "left");
|
background->paint(&p, QRect(leftOffset, contentTop, leftWidth, contentHeight), "left");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawRightBorder) {
|
if (bFlags & DrawRightBorder) {
|
||||||
d->background->paint(&p, QRect(rightOffset, contentTop, d->rightWidth, contentHeight), "right");
|
background->paint(&p, QRect(rightOffset, contentTop, rightWidth, contentHeight), "right");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawTopBorder) {
|
if (bFlags & DrawTopBorder) {
|
||||||
d->background->paint(&p, QRect(contentLeft, topOffset, contentWidth, d->topHeight), "top");
|
background->paint(&p, QRect(contentLeft, topOffset, contentWidth, topHeight), "top");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawBottomBorder) {
|
if (bFlags & DrawBottomBorder) {
|
||||||
d->background->paint(&p, QRect(contentLeft, bottomOffset, contentWidth, d->bottomHeight), "bottom");
|
background->paint(&p, QRect(contentLeft, bottomOffset, contentWidth, bottomHeight), "bottom");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (d->bFlags & DrawLeftBorder) {
|
if (bFlags & DrawLeftBorder) {
|
||||||
QPixmap left(d->leftWidth, leftHeight);
|
QPixmap left(leftWidth, leftHeight);
|
||||||
left.fill(Qt::transparent);
|
left.fill(Qt::transparent);
|
||||||
|
|
||||||
{
|
{
|
||||||
QPainter sidePainter(&left);
|
QPainter sidePainter(&left);
|
||||||
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
d->background->paint(&sidePainter, QPoint(0, 0), "left");
|
background->paint(&sidePainter, QPoint(0, 0), "left");
|
||||||
}
|
}
|
||||||
|
|
||||||
p.drawTiledPixmap(QRect(leftOffset, contentTop, d->leftWidth, contentHeight), left);
|
p.drawTiledPixmap(QRect(leftOffset, contentTop, leftWidth, contentHeight), left);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawRightBorder) {
|
if (bFlags & DrawRightBorder) {
|
||||||
QPixmap right(d->rightWidth, leftHeight);
|
QPixmap right(rightWidth, leftHeight);
|
||||||
right.fill(Qt::transparent);
|
right.fill(Qt::transparent);
|
||||||
|
|
||||||
{
|
{
|
||||||
QPainter sidePainter(&right);
|
QPainter sidePainter(&right);
|
||||||
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
d->background->paint(&sidePainter, QPoint(0, 0), "right");
|
background->paint(&sidePainter, QPoint(0, 0), "right");
|
||||||
}
|
}
|
||||||
|
|
||||||
p.drawTiledPixmap(QRect(rightOffset, contentTop, d->rightWidth, contentHeight), right);
|
p.drawTiledPixmap(QRect(rightOffset, contentTop, rightWidth, contentHeight), right);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawTopBorder) {
|
if (bFlags & DrawTopBorder) {
|
||||||
QPixmap top(topWidth, d->topHeight);
|
QPixmap top(topWidth, topHeight);
|
||||||
top.fill(Qt::transparent);
|
top.fill(Qt::transparent);
|
||||||
|
|
||||||
{
|
{
|
||||||
QPainter sidePainter(&top);
|
QPainter sidePainter(&top);
|
||||||
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
d->background->paint(&sidePainter, QPoint(0, 0), "top");
|
background->paint(&sidePainter, QPoint(0, 0), "top");
|
||||||
}
|
}
|
||||||
|
|
||||||
p.drawTiledPixmap(QRect(contentLeft, topOffset, contentWidth, d->topHeight), top);
|
p.drawTiledPixmap(QRect(contentLeft, topOffset, contentWidth, topHeight), top);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->bFlags & DrawBottomBorder) {
|
if (bFlags & DrawBottomBorder) {
|
||||||
QPixmap bottom(topWidth, d->bottomHeight);
|
QPixmap bottom(topWidth, bottomHeight);
|
||||||
bottom.fill(Qt::transparent);
|
bottom.fill(Qt::transparent);
|
||||||
|
|
||||||
{
|
{
|
||||||
QPainter sidePainter(&bottom);
|
QPainter sidePainter(&bottom);
|
||||||
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
sidePainter.setCompositionMode(QPainter::CompositionMode_Source);
|
||||||
d->background->paint(&sidePainter, QPoint(0, 0), "bottom");
|
background->paint(&sidePainter, QPoint(0, 0), "bottom");
|
||||||
}
|
}
|
||||||
|
|
||||||
p.drawTiledPixmap(QRect(contentLeft, bottomOffset, contentWidth, d->bottomHeight), bottom);
|
p.drawTiledPixmap(QRect(contentLeft, bottomOffset, contentWidth, bottomHeight), bottom);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,9 +325,22 @@ void SvgPanel::paint(QPainter* painter, const QRectF& rect)
|
|||||||
//resize(contentWidth, contentHeight);
|
//resize(contentWidth, contentHeight);
|
||||||
//paint(&p, QRect(contentLeft, contentTop, contentWidth, contentHeight), "center");
|
//paint(&p, QRect(contentLeft, contentTop, contentWidth, contentHeight), "center");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//p2->drawPixmap(paintRect, *cachedBackground, paintRect.translated(-leftOffset,-topOffset));
|
void SvgPanel::paint(QPainter* painter, const QRectF& rect)
|
||||||
painter->drawPixmap(rect, *d->cachedBackground, rect.translated(-d->pos.x()-leftOffset,-d->pos.y()-topOffset));
|
{
|
||||||
|
if (!d->cachedBackground) {
|
||||||
|
d->generateBackground();
|
||||||
|
}
|
||||||
|
|
||||||
|
//FIXME: this is redundant with generatebackground for now
|
||||||
|
bool origined = d->bFlags & ContentAtOrigin;
|
||||||
|
const int topWidth = d->background->elementSize("top").width();
|
||||||
|
const int leftHeight = d->background->elementSize("left").height();
|
||||||
|
const int topOffset = origined ? 0 - d->topHeight : 0;
|
||||||
|
const int leftOffset = origined ? 0 - d->leftWidth : 0;
|
||||||
|
|
||||||
|
painter->drawPixmap(rect, *d->cachedBackground, rect.translated(-d->pos.x()-leftOffset,-d->pos.y()-topOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
void SvgPanel::updateSizes()
|
void SvgPanel::updateSizes()
|
||||||
|
@ -122,6 +122,12 @@ class PLASMA_EXPORT SvgPanel : public QObject
|
|||||||
*/
|
*/
|
||||||
QPointF pos() const;
|
QPointF pos() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a monochrome mask that tightly contains the fully opaque areas of the svg
|
||||||
|
* @return a monochrome bitmap of opaque areas
|
||||||
|
*/
|
||||||
|
QBitmap mask() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Paints the loaded SVG with the elements that represents the border
|
* Paints the loaded SVG with the elements that represents the border
|
||||||
* @arg painter the QPainter to use
|
* @arg painter the QPainter to use
|
||||||
|
@ -280,6 +280,11 @@ QFontMetrics Theme::fontMetrics() const
|
|||||||
return QFontMetrics(d->generalFont);
|
return QFontMetrics(d->generalFont);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Theme::compositingActive() const
|
||||||
|
{
|
||||||
|
return d->compositingActive;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#include <theme.moc>
|
#include <theme.moc>
|
||||||
|
5
theme.h
5
theme.h
@ -130,6 +130,11 @@ class PLASMA_EXPORT Theme : public QObject
|
|||||||
*/
|
*/
|
||||||
Q_INVOKABLE QFontMetrics fontMetrics() const;
|
Q_INVOKABLE QFontMetrics fontMetrics() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns if the window compositing is active or not
|
||||||
|
*/
|
||||||
|
Q_INVOKABLE bool compositingActive() const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* Emitted when the user changes the theme. SVGs should be reloaded at
|
* Emitted when the user changes the theme. SVGs should be reloaded at
|
||||||
|
@ -346,20 +346,7 @@ void ToolTip::resizeEvent(QResizeEvent *e)
|
|||||||
QWidget::resizeEvent(e);
|
QWidget::resizeEvent(e);
|
||||||
d->background->resize(size());
|
d->background->resize(size());
|
||||||
|
|
||||||
if (KWindowSystem::compositingActive()) {
|
setMask(d->background->mask());
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QBitmap mask(width(), height());
|
|
||||||
QPainter maskPainter(&mask);
|
|
||||||
|
|
||||||
mask.fill(Qt::white);
|
|
||||||
|
|
||||||
maskPainter.setBrush(Qt::black);
|
|
||||||
maskPainter.setPen(Qt::black);
|
|
||||||
|
|
||||||
maskPainter.drawPath(roundedRectangle(mask.rect().adjusted(-1,-1,-1,-1), 10));
|
|
||||||
setMask(mask);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ToolTip::paintEvent(QPaintEvent *e)
|
void ToolTip::paintEvent(QPaintEvent *e)
|
||||||
@ -371,13 +358,6 @@ void ToolTip::paintEvent(QPaintEvent *e)
|
|||||||
painter.fillRect(rect(), Qt::transparent);
|
painter.fillRect(rect(), Qt::transparent);
|
||||||
|
|
||||||
d->background->paint(&painter, rect());
|
d->background->paint(&painter, rect());
|
||||||
|
|
||||||
//Stroke border if there is no compositing
|
|
||||||
if (!KWindowSystem::compositingActive()) {
|
|
||||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver );
|
|
||||||
painter.setPen(Plasma::Theme::self()->textColor());
|
|
||||||
painter.drawPath(roundedRectangle(rect().adjusted(.5,.5,-.5,-.5), 10));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user