Plasma
glapplet.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2007 Zack Rusin <zack@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this program; if not, write to the 00016 * Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "glapplet.h" 00021 00022 #include <QtOpenGL/QGLPixelBuffer> 00023 #include <QtGui/QPainter> 00024 #include <QtGui/QImage> 00025 00026 namespace Plasma { 00027 00028 class GLAppletPrivate 00029 { 00030 public: 00031 GLAppletPrivate() 00032 { 00033 init(); 00034 } 00035 ~GLAppletPrivate() 00036 { 00037 delete pbuf; 00038 delete dummy; 00039 } 00040 void init() 00041 { 00042 dummy = new QGLWidget((QWidget *) 0); 00043 QGLFormat format = QGLFormat::defaultFormat(); 00044 format.setSampleBuffers(true); 00045 format.setAlphaBufferSize(8); 00046 //dummy size construction 00047 pbuf = new QGLPixelBuffer(300, 300, format, dummy); 00048 if (pbuf->isValid()) { 00049 pbuf->makeCurrent(); 00050 } 00051 } 00052 void updateGlSize(const QSize &size) 00053 { 00054 if (size.width() > pbuf->width() || 00055 size.height() > pbuf->height()) { 00056 QGLFormat format = pbuf->format(); 00057 delete pbuf; 00058 pbuf = new QGLPixelBuffer(size, format, dummy); 00059 } 00060 } 00061 00062 public: 00063 QGLPixelBuffer *pbuf; 00064 QGLWidget *dummy; 00065 }; 00066 00067 GLApplet::GLApplet(QGraphicsItem *parent, 00068 const QString &serviceId, 00069 int appletId) 00070 : Applet(parent, serviceId, appletId), 00071 d(new GLAppletPrivate) 00072 { 00073 if (!d->dummy->isValid() || 00074 !QGLPixelBuffer::hasOpenGLPbuffers() || 00075 !d->pbuf->isValid()) { 00076 setFailedToLaunch(true, i18n("This system does not support OpenGL widgets.")); 00077 } 00078 } 00079 00080 GLApplet::GLApplet(QObject *parent, const QVariantList &args) 00081 : Applet(parent, args), 00082 d(new GLAppletPrivate) 00083 { 00084 if (!d->dummy->isValid() || 00085 !QGLPixelBuffer::hasOpenGLPbuffers() || 00086 !d->pbuf->isValid()) { 00087 setFailedToLaunch(true, i18n("This system does not support OpenGL widgets.")); 00088 } 00089 } 00090 00091 GLApplet::~GLApplet() 00092 { 00093 delete d; 00094 } 00095 00096 GLuint GLApplet::bindTexture(const QImage &image, GLenum target) 00097 { 00098 Q_ASSERT(d->pbuf); 00099 if (!d->dummy->isValid()) { 00100 return 0; 00101 } 00102 return d->dummy->bindTexture(image, target); 00103 } 00104 00105 void GLApplet::deleteTexture(GLuint textureId) 00106 { 00107 Q_ASSERT(d->pbuf); 00108 d->dummy->deleteTexture(textureId); 00109 } 00110 00111 void GLApplet::paintGLInterface(QPainter *painter, 00112 const QStyleOptionGraphicsItem *option) 00113 { 00114 Q_UNUSED(painter) 00115 Q_UNUSED(option) 00116 } 00117 00118 static inline QPainterPath headerPath(const QRectF &r, int roundness, 00119 int headerHeight=10) 00120 { 00121 QPainterPath path; 00122 int xRnd = roundness; 00123 int yRnd = roundness; 00124 if (r.width() > r.height()) { 00125 xRnd = int(roundness * r.height() / r.width()); 00126 } else { 00127 yRnd = int(roundness * r.width() / r.height()); 00128 } 00129 00130 if(xRnd >= 100) { // fix ranges 00131 xRnd = 99; 00132 } 00133 if(yRnd >= 100) { 00134 yRnd = 99; 00135 } 00136 if(xRnd <= 0 || yRnd <= 0) { // add normal rectangle 00137 path.addRect(r); 00138 return path; 00139 } 00140 00141 QRectF rect = r.normalized(); 00142 00143 if (rect.isNull()) { 00144 return path; 00145 } 00146 00147 qreal x = rect.x(); 00148 qreal y = rect.y(); 00149 qreal w = rect.width(); 00150 qreal h = rect.height(); 00151 qreal rxx = w * xRnd / 200; 00152 qreal ryy = h * yRnd / 200; 00153 // were there overflows? 00154 if (rxx < 0) { 00155 rxx = w / 200 * xRnd; 00156 } 00157 if (ryy < 0) { 00158 ryy = h / 200 * yRnd; 00159 } 00160 qreal rxx2 = 2 * rxx; 00161 qreal ryy2 = 2 * ryy; 00162 00163 path.arcMoveTo(x, y, rxx2, ryy2, 90); 00164 path.arcTo(x, y, rxx2, ryy2, 90, 90); 00165 QPointF pt = path.currentPosition(); 00166 path.lineTo(x, pt.y() + headerHeight); 00167 path.lineTo(x + w, pt.y() + headerHeight); 00168 path.lineTo(x + w, pt.y()); 00169 path.arcTo(x + w - rxx2, y, rxx2, ryy2, 0, 90); 00170 path.closeSubpath(); 00171 00172 return path; 00173 } 00174 00175 void GLApplet::paintInterface(QPainter *painter, 00176 const QStyleOptionGraphicsItem *option, 00177 const QRect &contentsRect) 00178 { 00179 Q_UNUSED(contentsRect) 00180 Q_ASSERT(d->pbuf); 00181 if ((!d->dummy->isValid() || 00182 !d->pbuf->isValid())) { 00183 if (!hasFailedToLaunch()) { 00184 setFailedToLaunch(true, i18n("Your machine does not support OpenGL widgets.")); 00185 } 00186 00187 return; 00188 } 00189 d->pbuf->makeCurrent(); 00190 00191 // handle background filling 00192 glClearColor(0, 0, 0, 0); 00193 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 00194 00195 QMatrix m = painter->worldMatrix(); 00196 QRect deviceRect = m.mapRect(QRect(QPoint(23, 25), boundingRect().size().toSize())); 00197 d->updateGlSize(deviceRect.size()); 00198 00199 // redirect this widget's painting into the pbuffer 00200 QPainter p(d->pbuf); 00201 paintGLInterface(&p, option); 00202 00203 // draw the pbuffer contents to the backingstore 00204 QImage image = d->pbuf->toImage(); 00205 painter->drawImage(0, 0, image); 00206 } 00207 00208 void GLApplet::makeCurrent() 00209 { 00210 if (!d->dummy->isValid() || !d->pbuf->isValid()) { 00211 d->dummy->makeCurrent(); 00212 } 00213 } 00214 00215 } // Plasma namespace 00216 00217 #include "glapplet.moc"
KDE 4.6 API Reference