diff --git a/CMakeLists.txt b/CMakeLists.txt index 25274ffcd..9b16d8e7e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -31,6 +31,7 @@ set(plasma_LIB_SRCS datacontainer.cpp dataengine.cpp dataenginemanager.cpp + dialog.cpp layouts/boxlayout.cpp layouts/borderlayout.cpp layouts/freelayout.cpp @@ -111,6 +112,7 @@ set(plasma_LIB_INCLUDES datacontainer.h dataengine.h dataenginemanager.h + dialog.h phase.h plasma.h plasma_export.h diff --git a/dialog.cpp b/dialog.cpp new file mode 100644 index 000000000..d42c84905 --- /dev/null +++ b/dialog.cpp @@ -0,0 +1,196 @@ +/*************************************************************************** + * Copyright (C) 2007 by Alexis Ménard * + * Copyright (C) 2007 Sebastian Kuegler * + * Copyright (C) 2006 Aaron Seigo * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#include "dialog.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + + + +namespace Plasma +{ + + +Dialog::Dialog( QWidget * parent, Qt::WindowFlags f ) + : QWidget(parent, f), + m_cachedBackground(0) +{ + m_background = new Plasma::Svg("dialogs/background", this); + + const int topHeight = m_background->elementSize("top").height(); + const int leftWidth = m_background->elementSize("left").width(); + const int rightWidth = m_background->elementSize("right").width(); + const int bottomHeight = m_background->elementSize("bottom").height(); + setContentsMargins(leftWidth, topHeight, rightWidth, bottomHeight); + + connect(m_background, SIGNAL(repaintNeeded()), this, SLOT(update())); +} + +Dialog::~Dialog() +{ +} + +void Dialog::paintEvent(QPaintEvent *e) +{ + QPainter p(this); + p.setRenderHint(QPainter::Antialiasing); + p.setClipRect(e->rect()); + p.setCompositionMode(QPainter::CompositionMode_Source ); + p.fillRect(rect(), Qt::transparent); + paintBackground(&p, e->rect()); +} + +void Dialog::paintBackground(QPainter* painter, const QRect &exposedRect) +{ + if (!m_cachedBackground || m_cachedBackground->size() != rect().size()) { + const int contentWidth = rect().width(); + const int contentHeight = rect().height(); + + m_background->resize(); + + const int topHeight = m_background->elementSize("top").height(); + const int topWidth = m_background->elementSize("top").width(); + const int leftWidth = m_background->elementSize("left").width(); + const int leftHeight = m_background->elementSize("left").height(); + const int rightHeight = m_background->elementSize("right").height(); + const int rightWidth = m_background->elementSize("right").width(); + const int bottomHeight = m_background->elementSize("bottom").height(); + const int bottomWidth = m_background->elementSize("bottom").width(); + + const int topOffset = 0; + const int leftOffset = 0; + const int rightOffset = contentWidth - rightWidth; + const int bottomOffset = contentHeight - bottomHeight; + const int contentTop = topHeight; + const int contentLeft = leftWidth; + + delete m_cachedBackground; + m_cachedBackground = new QPixmap(contentWidth, contentHeight); + m_cachedBackground->fill(Qt::transparent); + QPainter p(m_cachedBackground); + p.setCompositionMode(QPainter::CompositionMode_Source); + p.setRenderHint(QPainter::SmoothPixmapTransform); + + //FIXME: This is a hack to fix a drawing problems with svg files where a thin transparent border is drawn around the svg image. + // the transparent border around the svg seems to vary in size depending on the size of the svg and as a result increasing the + // svn image by 2 all around didn't resolve the issue. For now it resizes based on the border size. + + m_background->resize(contentWidth, contentHeight); + m_background->paint(&p, QRect(contentLeft, contentTop, contentWidth, contentHeight), "center"); + m_background->resize(); + + m_background->paint(&p, QRect(leftOffset, topOffset, leftWidth, topHeight), "topleft"); + m_background->paint(&p, QRect(rightOffset, topOffset, rightWidth, topHeight), "topright"); + m_background->paint(&p, QRect(leftOffset, bottomOffset, leftWidth, bottomHeight), "bottomleft"); + m_background->paint(&p, QRect(rightOffset, bottomOffset, rightWidth, bottomHeight), "bottomright"); + + if (m_background->elementExists("hint-stretch-borders")) { + m_background->paint(&p, QRect(leftOffset, contentTop, leftWidth, contentHeight), "left"); + m_background->paint(&p, QRect(rightOffset, contentTop, rightWidth, contentHeight), "right"); + m_background->paint(&p, QRect(contentLeft, topOffset, contentWidth, topHeight), "top"); + m_background->paint(&p, QRect(contentLeft, bottomOffset, contentWidth, bottomHeight), "bottom"); + } else { + QPixmap left(leftWidth, leftHeight); + left.fill(Qt::transparent); + { + QPainter sidePainter(&left); + sidePainter.setCompositionMode(QPainter::CompositionMode_Source); + m_background->paint(&sidePainter, QPoint(0, 0), "left"); + } + p.drawTiledPixmap(QRect(leftOffset, contentTop, leftWidth, contentHeight - topHeight - bottomHeight), left); + + QPixmap right(rightWidth, rightHeight); + right.fill(Qt::transparent); + { + QPainter sidePainter(&right); + sidePainter.setCompositionMode(QPainter::CompositionMode_Source); + m_background->paint(&sidePainter, QPoint(0, 0), "right"); + } + p.drawTiledPixmap(QRect(rightOffset, contentTop, rightWidth, contentHeight - topHeight - bottomHeight), right); + + QPixmap top(topWidth, topHeight); + top.fill(Qt::transparent); + { + QPainter sidePainter(&top); + sidePainter.setCompositionMode(QPainter::CompositionMode_Source); + m_background->paint(&sidePainter, QPoint(0, 0), "top"); + } + p.drawTiledPixmap(QRect(contentLeft, topOffset, contentWidth - rightWidth - leftWidth, topHeight), top); + + QPixmap bottom(bottomWidth, bottomHeight); + bottom.fill(Qt::transparent); + { + QPainter sidePainter(&bottom); + sidePainter.setCompositionMode(QPainter::CompositionMode_Source); + m_background->paint(&sidePainter, QPoint(0, 0), "bottom"); + } + p.drawTiledPixmap(QRect(contentLeft, bottomOffset, contentWidth - rightWidth - leftWidth, bottomHeight), bottom); + } + + // re-enable this once Qt's svg rendering is un-buggered + //background->resize(contentWidth, contentHeight); + //background->paint(&p, QRect(contentLeft, contentTop, contentWidth, contentHeight), "center"); + } + + painter->drawPixmap(exposedRect, *m_cachedBackground, exposedRect); +} + +void Dialog::position(QGraphicsSceneMouseEvent *event, const QRectF boundingRect, QPointF scenePos) +{ + QWidget *viewWidget = event->widget() ? event->widget()->parentWidget() : 0; + //QPointF scenePos = mapToScene(boundingRect.topLeft()); + QGraphicsView *view = qobject_cast(viewWidget); + if (view) { + QPoint viewPos = view->mapFromScene(scenePos); + QPoint globalPos = view->mapToGlobal(viewPos); + if ((globalPos.ry()-height())< 0) { + + //scenePos = mapToScene(boundingRect.bottomLeft()); + scenePos = QPointF(scenePos.x() + boundingRect.width(), scenePos.y() + boundingRect.height()); + viewPos = view->mapFromScene(scenePos); + globalPos = view->mapToGlobal(viewPos)+QPoint(0,10); + } + else { + globalPos.ry() -= (height()+10); + } + if ((globalPos.rx() + width()) > view->width()) { + globalPos.rx()-=((globalPos.rx() + width())-view->width()); + } + move(globalPos); + kDebug() << globalPos; + } +} + +} +#include "dialog.moc" diff --git a/dialog.h b/dialog.h new file mode 100644 index 000000000..803c59d1e --- /dev/null +++ b/dialog.h @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright (C) 2007 by Alexis Ménard * + * Copyright (C) 2007 Sebastian Kuegler * + * Copyright (C) 2006 Aaron Seigo * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . * + ***************************************************************************/ + +#ifndef PLASMA_DIALOG_H +#define PLASMA_DIALOG_H + +#include +#include + +#include + + + +namespace Plasma +{ + class Svg; + +/** + * @short A dialog that uses the Plasma style + * + * Dialog provides a dialog-like widget that can be used to display additional + * information. + * + * Dialog uses the plasma theme, and usually has no window decoration. It's meant + * as an interim solution to display widgets as extension to plasma applets, for + * example when you click on an applet like the devicenotifier or the clock, the + * widget that is then displayed, is a Dialog. + */ +class PLASMA_EXPORT Dialog : public QWidget +{ + Q_OBJECT + + public: + /** + * @arg parent the parent widget, for plasmoids, this is usually 0. + * @arg f the Qt::WindowFlags, default is to not show a windowborder. + */ + explicit Dialog( QWidget * parent = 0,Qt::WindowFlags f = Qt::Window ); + virtual ~Dialog(); + /** + * @arg event the event that is used to position the dialog. Usually, you want + * to pass this on from the mouseevent. + * @arg boundingRect the boundingRect() from the applet. + * @arg scenePos the absolute position on the scene. + */ + void position(QGraphicsSceneMouseEvent *event, const QRectF boundingRect, QPointF scenePos); + + protected: + /** + * Reimplemented from QWidget + */ + void paintEvent( QPaintEvent *e ); + + private: + /** + * Paints the plasma-themed background + */ + void paintBackground(QPainter* painter, const QRect &exposedRect); + /** + * Holds the background SVG, to be re-rendered when the cache is invalidated, + * for example by resizing the dialogue. + */ + Plasma::Svg *m_background; + /** + * Holds a pixmap of the rendered SVG background so we don't need to re-render + * it when not necessary. + */ + QPixmap *m_cachedBackground; +}; + +} // Plasma namespace + +#endif