00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "arthurwidgets.h"
00025 #include <QApplication>
00026 #include <QPainter>
00027 #include <QPainterPath>
00028 #include <QPixmapCache>
00029 #include <QtEvents>
00030 #include <QTextDocument>
00031 #include <QAbstractTextDocumentLayout>
00032 #include <QFile>
00033 #include <QTextBrowser>
00034 #include <QBoxLayout>
00035
00036 extern QPixmap cached(const QString &img);
00037
00038 ArthurFrame::ArthurFrame(QWidget *parent)
00039 : QWidget(parent)
00040 , m_prefer_image(false)
00041 {
00042 #ifdef QT_OPENGL_SUPPORT
00043 glw = 0;
00044 m_use_opengl = false;
00045 QGLFormat f = QGLFormat::defaultFormat();
00046 f.setSampleBuffers(true);
00047 f.setStencil(true);
00048 f.setAlpha(true);
00049 f.setAlphaBufferSize(8);
00050 QGLFormat::setDefaultFormat(f);
00051 #endif
00052 m_document = 0;
00053 m_show_doc = false;
00054
00055 m_tile = QPixmap(100, 100);
00056 m_tile.fill(Qt::white);
00057 QPainter pt(&m_tile);
00058 QColor color(240, 240, 240);
00059 pt.fillRect(0, 0, 50, 50, color);
00060 pt.fillRect(50, 50, 50, 50, color);
00061 pt.end();
00062
00063
00064
00065
00066
00067 #ifdef Q_WS_X11
00068 QPixmap xRenderPixmap(1, 1);
00069 m_prefer_image = !xRenderPixmap.x11PictureHandle();
00070 #endif
00071 }
00072
00073
00074 #ifdef QT_OPENGL_SUPPORT
00075 void ArthurFrame::enableOpenGL(bool use_opengl)
00076 {
00077 m_use_opengl = use_opengl;
00078
00079 if (!glw) {
00080 glw = new GLWidget(this);
00081 glw->setAutoFillBackground(false);
00082 glw->disableAutoBufferSwap();
00083 QApplication::postEvent(this, new QResizeEvent(size(), size()));
00084 }
00085
00086 if (use_opengl) {
00087 glw->show();
00088 } else {
00089 glw->hide();
00090 }
00091 }
00092 #endif
00093
00094 void ArthurFrame::paintEvent(QPaintEvent *e)
00095 {
00096 static QImage *static_image = 0;
00097 QPainter painter;
00098 if (preferImage()
00099 #ifdef QT_OPENGL_SUPPORT
00100 && !m_use_opengl
00101 #endif
00102 ) {
00103 if (!static_image) {
00104 static_image = new QImage(size(), QImage::Format_RGB32);
00105 } else if (static_image->size() != size()) {
00106 delete static_image;
00107 static_image = new QImage(size(), QImage::Format_RGB32);
00108 }
00109 painter.begin(static_image);
00110
00111 int o = 10;
00112
00113 QBrush bg = palette().brush(QPalette::Background);
00114 painter.fillRect(0, 0, o, o, bg);
00115 painter.fillRect(width() - o, 0, o, o, bg);
00116 painter.fillRect(0, height() - o, o, o, bg);
00117 painter.fillRect(width() - o, height() - o, o, o, bg);
00118 } else {
00119 #ifdef QT_OPENGL_SUPPORT
00120 if (m_use_opengl) {
00121 painter.begin(glw);
00122 painter.fillRect(QRectF(0, 0, glw->width(), glw->height()), palette().color(backgroundRole()));
00123 } else {
00124 painter.begin(this);
00125 }
00126 #else
00127 painter.begin(this);
00128 #endif
00129 }
00130
00131 painter.setClipRect(e->rect());
00132
00133 painter.setRenderHint(QPainter::Antialiasing);
00134
00135 QPainterPath clipPath;
00136
00137 QRect r = rect();
00138 double left = r.x() + 1;
00139 double top = r.y() + 1;
00140 double right = r.right();
00141 double bottom = r.bottom();
00142 double radius2 = 8 * 2;
00143
00144 clipPath.moveTo(right - radius2, top);
00145 clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90);
00146 clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90);
00147 clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90);
00148 clipPath.arcTo(left, top, radius2, radius2, 180, -90);
00149 clipPath.closeSubpath();
00150
00151 painter.save();
00152 painter.setClipPath(clipPath, Qt::IntersectClip);
00153
00154 painter.drawTiledPixmap(rect(), m_tile);
00155
00156
00157
00158 paint(&painter);
00159
00160 painter.restore();
00161
00162 painter.save();
00163 if (m_show_doc)
00164 paintDescription(&painter);
00165 painter.restore();
00166
00167 int level = 180;
00168 painter.setPen(QPen(QColor(level, level, level), 2));
00169 painter.setBrush(Qt::NoBrush);
00170 painter.drawPath(clipPath);
00171
00172 if (preferImage()
00173 #ifdef QT_OPENGL_SUPPORT
00174 && !m_use_opengl
00175 #endif
00176 ) {
00177 painter.end();
00178 painter.begin(this);
00179 painter.drawImage(e->rect(), *static_image, e->rect());
00180 }
00181
00182 #ifdef QT_OPENGL_SUPPORT
00183 if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
00184 glw->swapBuffers();
00185 #endif
00186 }
00187
00188 void ArthurFrame::resizeEvent(QResizeEvent *e)
00189 {
00190 #ifdef QT_OPENGL_SUPPORT
00191 if (glw)
00192 glw->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
00193 #endif
00194 QWidget::resizeEvent(e);
00195 }
00196
00197 void ArthurFrame::setDescriptionEnabled(bool enabled)
00198 {
00199 if (m_show_doc != enabled) {
00200 m_show_doc = enabled;
00201 emit descriptionEnabledChanged(m_show_doc);
00202 update();
00203 }
00204 }
00205
00206 void ArthurFrame::loadDescription(const QString &fileName)
00207 {
00208 QFile textFile(fileName);
00209 QString text;
00210 if (!textFile.open(QFile::ReadOnly))
00211 text = QString("Unable to load resource file: '%1'").arg(fileName);
00212 else
00213 text = textFile.readAll();
00214 setDescription(text);
00215 }
00216
00217
00218 void ArthurFrame::setDescription(const QString &text)
00219 {
00220 m_document = new QTextDocument(this);
00221 m_document->setHtml(text);
00222 }
00223
00224 void ArthurFrame::paintDescription(QPainter *painter)
00225 {
00226 if (!m_document)
00227 return;
00228
00229 int pageWidth = qMax(width() - 100, 100);
00230 int pageHeight = qMax(height() - 100, 100);
00231 if (pageWidth != m_document->pageSize().width()) {
00232 m_document->setPageSize(QSize(pageWidth, pageHeight));
00233 }
00234
00235 QRect textRect(width() / 2 - pageWidth / 2,
00236 height() / 2 - pageHeight / 2,
00237 pageWidth,
00238 pageHeight);
00239 int pad = 10;
00240 QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
00241 painter->setPen(Qt::NoPen);
00242 painter->setBrush(QColor(0, 0, 0, 63));
00243 int shade = 10;
00244 painter->drawRect(clearRect.x() + clearRect.width() + 1,
00245 clearRect.y() + shade,
00246 shade,
00247 clearRect.height() + 1);
00248 painter->drawRect(clearRect.x() + shade,
00249 clearRect.y() + clearRect.height() + 1,
00250 clearRect.width() - shade + 1,
00251 shade);
00252
00253 painter->setRenderHint(QPainter::Antialiasing, false);
00254 painter->setBrush(QColor(255, 255, 255, 220));
00255 painter->setPen(Qt::black);
00256 painter->drawRect(clearRect);
00257
00258 painter->setClipRegion(textRect, Qt::IntersectClip);
00259 painter->translate(textRect.topLeft());
00260
00261 QAbstractTextDocumentLayout::PaintContext ctx;
00262
00263 QLinearGradient g(0, 0, 0, textRect.height());
00264 g.setColorAt(0, Qt::black);
00265 g.setColorAt(0.9, Qt::black);
00266 g.setColorAt(1, Qt::transparent);
00267
00268 QPalette pal = palette();
00269 pal.setBrush(QPalette::Text, g);
00270
00271 ctx.palette = pal;
00272 ctx.clip = QRect(0, 0, textRect.width(), textRect.height());
00273 m_document->documentLayout()->draw(painter, ctx);
00274 }
00275
00276 void ArthurFrame::loadSourceFile(const QString &sourceFile)
00277 {
00278 m_sourceFileName = sourceFile;
00279 }
00280
00281 void ArthurFrame::showSource()
00282 {
00283
00284 if (qFindChild<QTextBrowser *>(this))
00285 return;
00286
00287 QString contents;
00288 if (m_sourceFileName.isEmpty()) {
00289 contents = QString("No source for widget: '%1'").arg(objectName());
00290 } else {
00291 QFile f(m_sourceFileName);
00292 if (!f.open(QFile::ReadOnly))
00293 contents = QString("Could not open file: '%1'").arg(m_sourceFileName);
00294 else
00295 contents = f.readAll();
00296 }
00297
00298 contents.replace('&', "&");
00299 contents.replace('<', "<");
00300 contents.replace('>', ">");
00301
00302 QStringList keywords;
00303 keywords << "for " << "if " << "switch " << " int " << "#include " << "const"
00304 << "void " << "uint " << "case " << "double " << "#define " << "static"
00305 << "new" << "this";
00306
00307 foreach (QString keyword, keywords)
00308 contents.replace(keyword, QLatin1String("<font color=olive>") + keyword + QLatin1String("</font>"));
00309 contents.replace("(int ", "(<font color=olive><b>int </b></font>");
00310
00311 QStringList ppKeywords;
00312 ppKeywords << "#ifdef" << "#ifndef" << "#if" << "#endif" << "#else";
00313
00314 foreach (QString keyword, ppKeywords)
00315 contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>"));
00316
00317 contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>"));
00318
00319 QRegExp commentRe("(//.+)\\n");
00320 commentRe.setMinimal(true);
00321 contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n"));
00322
00323 QRegExp stringLiteralRe("(\".+\")");
00324 stringLiteralRe.setMinimal(true);
00325 contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>"));
00326
00327 QString html = contents;
00328 html.prepend("<html><pre>");
00329 html.append("</pre></html>");
00330
00331 QTextBrowser *sourceViewer = new QTextBrowser(0);
00332 sourceViewer->setWindowTitle("Source: " + m_sourceFileName.mid(5));
00333 sourceViewer->setParent(this, Qt::Dialog);
00334 sourceViewer->setAttribute(Qt::WA_DeleteOnClose);
00335 sourceViewer->setLineWrapMode(QTextEdit::NoWrap);
00336 sourceViewer->setHtml(html);
00337 sourceViewer->resize(600, 600);
00338 sourceViewer->show();
00339 }