Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / workspace / libs / plasma / glapplet.cpp
blob70ec3279bd4a9549ae38d62f757d6a7ac6e19c8e
1 /*
2 * Copyright 2007 Zack Rusin <zack@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "glapplet.h"
22 #include <QtOpenGL/QGLPixelBuffer>
23 #include <QtGui/QPainter>
24 #include <QtGui/QImage>
26 namespace Plasma {
28 class GLApplet::Private
30 public:
31 Private()
33 init();
35 ~Private()
37 delete pbuf;
38 delete dummy;
40 void init()
42 dummy = new QGLWidget((QWidget *) 0);
43 QGLFormat format = QGLFormat::defaultFormat();
44 format.setSampleBuffers(true);
45 format.setAlphaBufferSize(8);
46 //dummy size construction
47 pbuf = new QGLPixelBuffer(300, 300, format, dummy);
48 if (pbuf->isValid()) {
49 pbuf->makeCurrent();
52 void updateGlSize(const QSize &size)
54 if (size.width() > pbuf->width() ||
55 size.height() > pbuf->height()) {
56 QGLFormat format = pbuf->format();
57 delete pbuf;
58 pbuf = new QGLPixelBuffer(size, format, dummy);
62 public:
63 QGLPixelBuffer *pbuf;
64 QGLWidget *dummy;
67 GLApplet::GLApplet(QGraphicsItem *parent,
68 const QString &serviceId,
69 int appletId)
70 : Applet(parent, serviceId, appletId),
71 d(new Private)
73 if (!d->dummy->isValid() ||
74 !QGLPixelBuffer::hasOpenGLPbuffers() ||
75 !d->pbuf->isValid()) {
76 setFailedToLaunch(true, i18n("This system does not support OpenGL applets."));
80 GLApplet::GLApplet(QObject *parent, const QVariantList &args)
81 : Applet(parent, args),
82 d(new Private)
84 if (!d->dummy->isValid() ||
85 !QGLPixelBuffer::hasOpenGLPbuffers() ||
86 !d->pbuf->isValid()) {
87 setFailedToLaunch(true, i18n("This system does not support OpenGL applets."));
91 GLApplet::~GLApplet()
93 delete d;
96 GLuint GLApplet::bindTexture(const QImage &image, GLenum target)
98 Q_ASSERT(d->pbuf);
99 if (!d->dummy->isValid())
100 return 0;
101 return d->dummy->bindTexture(image, target);
104 void GLApplet::deleteTexture(GLuint textureId)
106 Q_ASSERT(d->pbuf);
107 d->dummy->deleteTexture(textureId);
110 void GLApplet::paintGLInterface(QPainter *painter,
111 const QStyleOptionGraphicsItem *option)
113 Q_UNUSED(painter)
114 Q_UNUSED(option)
117 static inline QPainterPath headerPath(const QRectF &r, int roundness,
118 int headerHeight=10)
120 QPainterPath path;
121 int xRnd = roundness;
122 int yRnd = roundness;
123 if (r.width() > r.height())
124 xRnd = int(roundness * r.height()/r.width());
125 else
126 yRnd = int(roundness * r.width()/r.height());
128 if(xRnd >= 100) // fix ranges
129 xRnd = 99;
130 if(yRnd >= 100)
131 yRnd = 99;
132 if(xRnd <= 0 || yRnd <= 0) { // add normal rectangle
133 path.addRect(r);
134 return path;
137 QRectF rect = r.normalized();
139 if (rect.isNull())
140 return path;
142 qreal x = rect.x();
143 qreal y = rect.y();
144 qreal w = rect.width();
145 qreal h = rect.height();
146 qreal rxx = w*xRnd/200;
147 qreal ryy = h*yRnd/200;
148 // were there overflows?
149 if (rxx < 0)
150 rxx = w/200*xRnd;
151 if (ryy < 0)
152 ryy = h/200*yRnd;
153 qreal rxx2 = 2*rxx;
154 qreal ryy2 = 2*ryy;
156 path.arcMoveTo(x, y, rxx2, ryy2, 90);
157 path.arcTo(x, y, rxx2, ryy2, 90, 90);
158 QPointF pt = path.currentPosition();
159 path.lineTo(x, pt.y()+headerHeight);
160 path.lineTo(x+w, pt.y()+headerHeight);
161 path.lineTo(x+w, pt.y());
162 path.arcTo(x+w-rxx2, y, rxx2, ryy2, 0, 90);
163 path.closeSubpath();
165 return path;
168 void GLApplet::paintInterface(QPainter *painter,
169 const QStyleOptionGraphicsItem *option,
170 const QRect &contentsRect)
172 Q_UNUSED(contentsRect)
173 Q_ASSERT(d->pbuf);
174 if ((!d->dummy->isValid() ||
175 !d->pbuf->isValid())) {
176 if (!failedToLaunch()) {
177 setFailedToLaunch(true, i18n("Your machine does not support OpenGL applets."));
180 return;
182 d->pbuf->makeCurrent();
184 // handle background filling
185 glClearColor(0, 0, 0, 0);
186 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
188 QMatrix m = painter->worldMatrix();
189 QRect deviceRect = m.mapRect(QRect(QPoint(23, 25), contentSize().toSize()));
190 d->updateGlSize(deviceRect.size());
192 // redirect this widget's painting into the pbuffer
193 QPainter p(d->pbuf);
194 paintGLInterface(&p, option);
196 // draw the pbuffer contents to the backingstore
197 QImage image = d->pbuf->toImage();
198 painter->drawImage(0, 0, image);
201 void GLApplet::makeCurrent()
203 if (!d->dummy->isValid() ||
204 !d->pbuf->isValid())
205 d->dummy->makeCurrent();
208 } // Plasma namespace
210 #include "glapplet.moc"