demos/shared/arthurwidgets.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the demonstration applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ****************************************************************************/
       
    41 
       
    42 #include "arthurwidgets.h"
       
    43 #include <QApplication>
       
    44 #include <QPainter>
       
    45 #include <QPainterPath>
       
    46 #include <QPixmapCache>
       
    47 #include <QtEvents>
       
    48 #include <QTextDocument>
       
    49 #include <QAbstractTextDocumentLayout>
       
    50 #include <QFile>
       
    51 #include <QTextBrowser>
       
    52 #include <QBoxLayout>
       
    53 
       
    54 #include <private/qpixmapdata_p.h>
       
    55 
       
    56 extern QPixmap cached(const QString &img);
       
    57 
       
    58 ArthurFrame::ArthurFrame(QWidget *parent)
       
    59     : QWidget(parent)
       
    60     , m_prefer_image(false)
       
    61 {
       
    62 #ifdef QT_OPENGL_SUPPORT
       
    63     glw = 0;
       
    64     m_use_opengl = false;
       
    65     QGLFormat f = QGLFormat::defaultFormat();
       
    66     f.setSampleBuffers(true);
       
    67     f.setStencil(true);
       
    68     f.setAlpha(true);
       
    69     f.setAlphaBufferSize(8);
       
    70     QGLFormat::setDefaultFormat(f);
       
    71 #endif
       
    72     m_document = 0;
       
    73     m_show_doc = false;
       
    74 
       
    75     m_tile = QPixmap(128, 128);
       
    76     m_tile.fill(Qt::white);
       
    77     QPainter pt(&m_tile);
       
    78     QColor color(230, 230, 230);
       
    79     pt.fillRect(0, 0, 64, 64, color);
       
    80     pt.fillRect(64, 64, 64, 64, color);
       
    81     pt.end();
       
    82 
       
    83 //     QPalette pal = palette();
       
    84 //     pal.setBrush(backgroundRole(), m_tile);
       
    85 //     setPalette(pal);
       
    86 
       
    87 #ifdef Q_WS_X11
       
    88     QPixmap xRenderPixmap(1, 1);
       
    89     m_prefer_image = xRenderPixmap.pixmapData()->classId() == QPixmapData::X11Class && !xRenderPixmap.x11PictureHandle();
       
    90 #endif
       
    91 }
       
    92 
       
    93 
       
    94 #ifdef QT_OPENGL_SUPPORT
       
    95 void ArthurFrame::enableOpenGL(bool use_opengl)
       
    96 {
       
    97     m_use_opengl = use_opengl;
       
    98 
       
    99     if (!glw) {
       
   100         glw = new GLWidget(this);
       
   101         glw->setAutoFillBackground(false);
       
   102         glw->disableAutoBufferSwap();
       
   103         QApplication::postEvent(this, new QResizeEvent(size(), size()));
       
   104     }
       
   105 
       
   106     if (use_opengl) {
       
   107         glw->show();
       
   108     } else {
       
   109         glw->hide();
       
   110     }
       
   111 
       
   112     update();
       
   113 }
       
   114 #endif
       
   115 
       
   116 void ArthurFrame::paintEvent(QPaintEvent *e)
       
   117 {
       
   118 #ifdef Q_WS_QWS
       
   119     static QPixmap *static_image = 0;
       
   120 #else
       
   121     static QImage *static_image = 0;
       
   122 #endif
       
   123     QPainter painter;
       
   124     if (preferImage()
       
   125 #ifdef QT_OPENGL_SUPPORT
       
   126         && !m_use_opengl
       
   127 #endif
       
   128         ) {
       
   129         if (!static_image || static_image->size() != size()) {
       
   130             delete static_image;
       
   131 #ifdef Q_WS_QWS
       
   132             static_image = new QPixmap(size());
       
   133 #else
       
   134             static_image = new QImage(size(), QImage::Format_RGB32);
       
   135 #endif
       
   136         }
       
   137         painter.begin(static_image);
       
   138 
       
   139         int o = 10;
       
   140 
       
   141         QBrush bg = palette().brush(QPalette::Background);
       
   142         painter.fillRect(0, 0, o, o, bg);
       
   143         painter.fillRect(width() - o, 0, o, o, bg);
       
   144         painter.fillRect(0, height() - o, o, o, bg);
       
   145         painter.fillRect(width() - o, height() - o, o, o, bg);
       
   146     } else {
       
   147 #ifdef QT_OPENGL_SUPPORT
       
   148         if (m_use_opengl) {
       
   149             painter.begin(glw);
       
   150             painter.fillRect(QRectF(0, 0, glw->width(), glw->height()), palette().color(backgroundRole()));
       
   151         } else {
       
   152             painter.begin(this);
       
   153         }
       
   154 #else
       
   155         painter.begin(this);
       
   156 #endif
       
   157     }
       
   158 
       
   159     painter.setClipRect(e->rect());
       
   160 
       
   161     painter.setRenderHint(QPainter::Antialiasing);
       
   162 
       
   163     QPainterPath clipPath;
       
   164 
       
   165     QRect r = rect();
       
   166     qreal left = r.x() + 1;
       
   167     qreal top = r.y() + 1;
       
   168     qreal right = r.right();
       
   169     qreal bottom = r.bottom();
       
   170     qreal radius2 = 8 * 2;
       
   171 
       
   172     clipPath.moveTo(right - radius2, top);
       
   173     clipPath.arcTo(right - radius2, top, radius2, radius2, 90, -90);
       
   174     clipPath.arcTo(right - radius2, bottom - radius2, radius2, radius2, 0, -90);
       
   175     clipPath.arcTo(left, bottom - radius2, radius2, radius2, 270, -90);
       
   176     clipPath.arcTo(left, top, radius2, radius2, 180, -90);
       
   177     clipPath.closeSubpath();
       
   178 
       
   179     painter.save();
       
   180     painter.setClipPath(clipPath, Qt::IntersectClip);
       
   181 
       
   182     painter.drawTiledPixmap(rect(), m_tile);
       
   183 
       
   184     // client painting
       
   185 
       
   186     paint(&painter);
       
   187 
       
   188     painter.restore();
       
   189 
       
   190     painter.save();
       
   191     if (m_show_doc)
       
   192         paintDescription(&painter);
       
   193     painter.restore();
       
   194 
       
   195     int level = 180;
       
   196     painter.setPen(QPen(QColor(level, level, level), 2));
       
   197     painter.setBrush(Qt::NoBrush);
       
   198     painter.drawPath(clipPath);
       
   199 
       
   200     if (preferImage()
       
   201 #ifdef QT_OPENGL_SUPPORT
       
   202         && !m_use_opengl
       
   203 #endif
       
   204         ) {
       
   205         painter.end();
       
   206         painter.begin(this);
       
   207 #ifdef Q_WS_QWS
       
   208         painter.drawPixmap(e->rect(), *static_image, e->rect());
       
   209 #else
       
   210         painter.drawImage(e->rect(), *static_image, e->rect());
       
   211 #endif
       
   212     }
       
   213 
       
   214 #ifdef QT_OPENGL_SUPPORT
       
   215     if (m_use_opengl && (inherits("PathDeformRenderer") || inherits("PathStrokeRenderer") || inherits("CompositionRenderer") || m_show_doc))
       
   216         glw->swapBuffers();
       
   217 #endif
       
   218 }
       
   219 
       
   220 void ArthurFrame::resizeEvent(QResizeEvent *e)
       
   221 {
       
   222 #ifdef QT_OPENGL_SUPPORT
       
   223     if (glw)
       
   224         glw->setGeometry(0, 0, e->size().width()-1, e->size().height()-1);
       
   225 #endif
       
   226     QWidget::resizeEvent(e);
       
   227 }
       
   228 
       
   229 void ArthurFrame::setDescriptionEnabled(bool enabled)
       
   230 {
       
   231     if (m_show_doc != enabled) {
       
   232         m_show_doc = enabled;
       
   233         emit descriptionEnabledChanged(m_show_doc);
       
   234         update();
       
   235     }
       
   236 }
       
   237 
       
   238 void ArthurFrame::loadDescription(const QString &fileName)
       
   239 {
       
   240     QFile textFile(fileName);
       
   241     QString text;
       
   242     if (!textFile.open(QFile::ReadOnly))
       
   243         text = QString("Unable to load resource file: '%1'").arg(fileName);
       
   244     else
       
   245         text = textFile.readAll();
       
   246     setDescription(text);
       
   247 }
       
   248 
       
   249 
       
   250 void ArthurFrame::setDescription(const QString &text)
       
   251 {
       
   252     m_document = new QTextDocument(this);
       
   253     m_document->setHtml(text);
       
   254 }
       
   255 
       
   256 void ArthurFrame::paintDescription(QPainter *painter)
       
   257 {
       
   258     if (!m_document)
       
   259         return;
       
   260 
       
   261     int pageWidth = qMax(width() - 100, 100);
       
   262     int pageHeight = qMax(height() - 100, 100);
       
   263     if (pageWidth != m_document->pageSize().width()) {
       
   264         m_document->setPageSize(QSize(pageWidth, pageHeight));
       
   265     }
       
   266 
       
   267     QRect textRect(width() / 2 - pageWidth / 2,
       
   268                    height() / 2 - pageHeight / 2,
       
   269                    pageWidth,
       
   270                    pageHeight);
       
   271     int pad = 10;
       
   272     QRect clearRect = textRect.adjusted(-pad, -pad, pad, pad);
       
   273     painter->setPen(Qt::NoPen);
       
   274     painter->setBrush(QColor(0, 0, 0, 63));
       
   275     int shade = 10;
       
   276     painter->drawRect(clearRect.x() + clearRect.width() + 1,
       
   277                       clearRect.y() + shade,
       
   278                       shade,
       
   279                       clearRect.height() + 1);
       
   280     painter->drawRect(clearRect.x() + shade,
       
   281                       clearRect.y() + clearRect.height() + 1,
       
   282                       clearRect.width() - shade + 1,
       
   283                       shade);
       
   284 
       
   285     painter->setRenderHint(QPainter::Antialiasing, false);
       
   286     painter->setBrush(QColor(255, 255, 255, 220));
       
   287     painter->setPen(Qt::black);
       
   288     painter->drawRect(clearRect);
       
   289 
       
   290     painter->setClipRegion(textRect, Qt::IntersectClip);
       
   291     painter->translate(textRect.topLeft());
       
   292 
       
   293     QAbstractTextDocumentLayout::PaintContext ctx;
       
   294 
       
   295     QLinearGradient g(0, 0, 0, textRect.height());
       
   296     g.setColorAt(0, Qt::black);
       
   297     g.setColorAt(0.9, Qt::black);
       
   298     g.setColorAt(1, Qt::transparent);
       
   299 
       
   300     QPalette pal = palette();
       
   301     pal.setBrush(QPalette::Text, g);
       
   302 
       
   303     ctx.palette = pal;
       
   304     ctx.clip = QRect(0, 0, textRect.width(), textRect.height());
       
   305     m_document->documentLayout()->draw(painter, ctx);
       
   306 }
       
   307 
       
   308 void ArthurFrame::loadSourceFile(const QString &sourceFile)
       
   309 {
       
   310     m_sourceFileName = sourceFile;
       
   311 }
       
   312 
       
   313 void ArthurFrame::showSource()
       
   314 {
       
   315     // Check for existing source
       
   316     if (qFindChild<QTextBrowser *>(this))
       
   317         return;
       
   318 
       
   319     QString contents;
       
   320     if (m_sourceFileName.isEmpty()) {
       
   321         contents = QString("No source for widget: '%1'").arg(objectName());
       
   322     } else {
       
   323         QFile f(m_sourceFileName);
       
   324         if (!f.open(QFile::ReadOnly))
       
   325             contents = QString("Could not open file: '%1'").arg(m_sourceFileName);
       
   326         else
       
   327             contents = f.readAll();
       
   328     }
       
   329 
       
   330     contents.replace('&', "&amp;");
       
   331     contents.replace('<', "&lt;");
       
   332     contents.replace('>', "&gt;");
       
   333 
       
   334     QStringList keywords;
       
   335     keywords << "for " << "if " << "switch " << " int " << "#include " << "const"
       
   336              << "void " << "uint " << "case " << "double " << "#define " << "static"
       
   337              << "new" << "this";
       
   338 
       
   339     foreach (QString keyword, keywords)
       
   340         contents.replace(keyword, QLatin1String("<font color=olive>") + keyword + QLatin1String("</font>"));
       
   341     contents.replace("(int ", "(<font color=olive><b>int </b></font>");
       
   342 
       
   343     QStringList ppKeywords;
       
   344     ppKeywords << "#ifdef" << "#ifndef" << "#if" << "#endif" << "#else";
       
   345 
       
   346     foreach (QString keyword, ppKeywords)
       
   347         contents.replace(keyword, QLatin1String("<font color=navy>") + keyword + QLatin1String("</font>"));
       
   348 
       
   349     contents.replace(QRegExp("(\\d\\d?)"), QLatin1String("<font color=navy>\\1</font>"));
       
   350 
       
   351     QRegExp commentRe("(//.+)\\n");
       
   352     commentRe.setMinimal(true);
       
   353     contents.replace(commentRe, QLatin1String("<font color=red>\\1</font>\n"));
       
   354 
       
   355     QRegExp stringLiteralRe("(\".+\")");
       
   356     stringLiteralRe.setMinimal(true);
       
   357     contents.replace(stringLiteralRe, QLatin1String("<font color=green>\\1</font>"));
       
   358 
       
   359     QString html = contents;
       
   360     html.prepend("<html><pre>");
       
   361     html.append("</pre></html>");
       
   362 
       
   363     QTextBrowser *sourceViewer = new QTextBrowser(0);
       
   364     sourceViewer->setWindowTitle("Source: " + m_sourceFileName.mid(5));
       
   365     sourceViewer->setParent(this, Qt::Dialog);
       
   366     sourceViewer->setAttribute(Qt::WA_DeleteOnClose);
       
   367     sourceViewer->setLineWrapMode(QTextEdit::NoWrap);
       
   368     sourceViewer->setHtml(html);
       
   369     sourceViewer->resize(600, 600);
       
   370     sourceViewer->show();
       
   371 }