diff options
author | Fabien Freling <fabien.freling@nokia.com> | 2010-10-08 16:37:25 (GMT) |
---|---|---|
committer | Fabien Freling <fabien.freling@nokia.com> | 2010-10-08 16:37:59 (GMT) |
commit | 1966b88611bb45d18d586847eeb3597d6e022eb7 (patch) | |
tree | 0bba3169a8bc44761686fd967f1cb25e4beca97a /src/gui/painting | |
parent | 392ecc76cdbcef37ee492400a1b783106a37ad36 (diff) | |
download | Qt-1966b88611bb45d18d586847eeb3597d6e022eb7.zip Qt-1966b88611bb45d18d586847eeb3597d6e022eb7.tar.gz Qt-1966b88611bb45d18d586847eeb3597d6e022eb7.tar.bz2 |
Experimental support of the unified toolbar with
the raster engine on Mac OS X.
Task-number: QTBUG-12615
Reviewed-by: Samuel Rødal
Diffstat (limited to 'src/gui/painting')
-rw-r--r-- | src/gui/painting/painting.pri | 6 | ||||
-rw-r--r-- | src/gui/painting/qunifiedtoolbarsurface_mac.cpp | 233 | ||||
-rw-r--r-- | src/gui/painting/qunifiedtoolbarsurface_mac_p.h | 95 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface.cpp | 4 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface_p.h | 2 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface_raster.cpp | 41 | ||||
-rw-r--r-- | src/gui/painting/qwindowsurface_raster_p.h | 2 |
7 files changed, 377 insertions, 6 deletions
diff --git a/src/gui/painting/painting.pri b/src/gui/painting/painting.pri index 793d380..10c6f40 100644 --- a/src/gui/painting/painting.pri +++ b/src/gui/painting/painting.pri @@ -247,6 +247,12 @@ symbian { QMAKE_CXXFLAGS.ARMCC *= -O3 } +mac { + HEADERS += painting/qunifiedtoolbarsurface_mac_p.h + SOURCES += painting/qunifiedtoolbarsurface_mac.cpp +} + + NEON_SOURCES += painting/qdrawhelper_neon.cpp NEON_HEADERS += painting/qdrawhelper_neon_p.h NEON_ASM += ../3rdparty/pixman/pixman-arm-neon-asm.S painting/qdrawhelper_neon_asm.S diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac.cpp b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp new file mode 100644 index 0000000..722355e --- /dev/null +++ b/src/gui/painting/qunifiedtoolbarsurface_mac.cpp @@ -0,0 +1,233 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qunifiedtoolbarsurface_mac_p.h" +#include <private/qt_cocoa_helpers_mac_p.h> +#include <private/qbackingstore_p.h> + +#include <QDebug> + +QT_BEGIN_NAMESPACE + +QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget) + : QRasterWindowSurface(widget, false), d_ptr(new QUnifiedToolbarSurfacePrivate) +{ + d_ptr->image = 0; + d_ptr->inSetGeometry = false; + setStaticContentsSupport(true); + + setGeometry(QRect(QPoint(0, 0), QSize(widget->width(), 100))); // FIXME: Fix height. +} + +QUnifiedToolbarSurface::~QUnifiedToolbarSurface() +{ + if (d_ptr->image) + delete d_ptr->image; +} + +QPaintDevice *QUnifiedToolbarSurface::paintDevice() +{ + return &d_ptr->image->image; +} + +void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, const QPoint &offset) +{ + if (object != 0) { + if (object->isWidgetType()) { + QWidget *widget = qobject_cast<QWidget *>(object); + widget->d_func()->unifiedSurface = this; + widget->d_func()->isInUnifiedToolbar = true; + widget->d_func()->toolbar_offset = offset; + } + + for (int i = 0; i < object->children().size(); ++i) { + recursiveRedirect(object->children().at(i), offset); + } + } +} + +void QUnifiedToolbarSurface::insertToolbar(QWidget *toolbar, const QPoint &offset) +{ + setGeometry(QRect(QPoint(0, 0), QSize(offset.x() + toolbar->width(), 100))); // FIXME + recursiveRedirect(toolbar, offset); +// toolbar->d_func()->toolbar_offset = offset; +} + +void QUnifiedToolbarSurface::setGeometry(const QRect &rect) +{ + QWindowSurface::setGeometry(rect); + Q_D(QUnifiedToolbarSurface); + d->inSetGeometry = true; + if (d->image == 0 || d->image->width() < rect.width() || d->image->height() < rect.height()) + prepareBuffer(QImage::Format_ARGB32_Premultiplied, window()); + d->inSetGeometry = false; +} + +void QUnifiedToolbarSurface::beginPaint(const QRegion &rgn) +{ + QPainter p(&d_ptr->image->image); + p.setCompositionMode(QPainter::CompositionMode_Source); + const QVector<QRect> rects = rgn.rects(); + const QColor blank = Qt::transparent; + for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) { + p.fillRect(*it, blank); + } +} + +void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion &rgn, const QPoint &offset) +{ + Q_D(QUnifiedToolbarSurface); + + if (!d->image || rgn.rectCount() == 0) { + return; + } + + Q_UNUSED(offset); + + // Get a context for the widget. + CGContextRef context; + if (!(widget->d_func()->hasOwnContext)) { + widget->d_func()->ut_rg = rgn; + widget->d_func()->ut_pt = offset; + qt_mac_display(widget); + return; + } else { + context = widget->d_func()->cgContext; + widget->render(widget->d_func()->unifiedSurface->paintDevice(), widget->d_func()->toolbar_offset, QRegion(), QWidget::DrawChildren); + } + + CGContextSaveGState(context); + + int areaX = widget->geometry().x() + widget->d_func()->toolbar_offset.x(); + int areaY = widget->geometry().y() + widget->d_func()->toolbar_offset.y(); + int areaWidth = widget->geometry().width(); + int areaHeight = widget->geometry().height(); + const CGRect area = CGRectMake(areaX, areaY, areaWidth, areaHeight); + + // Clip to region. + const QVector<QRect> &rects = rgn.rects(); + for (int i = 0; i < rects.size(); ++i) { + const QRect &rect = rects.at(i); + // CGContextAddRect(context, CGRectMake(rect.x(), rect.y(), rect.width(), rect.height())); + CGContextAddRect(context, CGRectMake(0, 0, 1000, 1000)); //FIXME: Set correct size. + } + CGContextAddRect(context, area); + CGContextClip(context); + + + CGImageRef image = CGBitmapContextCreateImage(d->image->cg); + CGImageRef subImage = CGImageCreateWithImageInRect(image, area); + + const CGRect drawingArea = CGRectMake(0, 0, areaWidth, areaHeight); + qt_mac_drawCGImage(context, &drawingArea, subImage); + + CGImageRelease(subImage); + CGImageRelease(image); + + CGContextFlush(context); + + // Restore context. + CGContextRestoreGState(context); + widget->d_func()->hasOwnContext = false; +} + +void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget) +{ + Q_D(QUnifiedToolbarSurface); + + int width = geometry().width(); + int height = geometry().height(); + if (d->image) { + width = qMax(d->image->width(), width); + height = qMax(d->image->height(), height); + } + + if (width == 0 || height == 0) { + delete d->image; + d->image = 0; + return; + } + + QNativeImage *oldImage = d->image; + + d->image = new QNativeImage(width, height, format, false, widget); + + if (oldImage && d->inSetGeometry && hasStaticContents()) { + // Make sure we use the const version of bits() (no detach). + const uchar *src = const_cast<const QImage &>(oldImage->image).bits(); + uchar *dst = d->image->image.bits(); + + const int srcBytesPerLine = oldImage->image.bytesPerLine(); + const int dstBytesPerLine = d->image->image.bytesPerLine(); + const int bytesPerPixel = oldImage->image.depth() >> 3; + + QRegion staticRegion(staticContents()); + // Make sure we're inside the boundaries of the old image. + staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height()); + const QVector<QRect> &rects = staticRegion.rects(); + const QRect *srcRect = rects.constData(); + + // Copy the static content of the old image into the new one. + int numRectsLeft = rects.size(); + do { + const int bytesOffset = srcRect->x() * bytesPerPixel; + const int dy = srcRect->y(); + + // Adjust src and dst to point to the right offset. + const uchar *s = src + dy * srcBytesPerLine + bytesOffset; + uchar *d = dst + dy * dstBytesPerLine + bytesOffset; + const int numBytes = srcRect->width() * bytesPerPixel; + + int numScanLinesLeft = srcRect->height(); + do { + ::memcpy(d, s, numBytes); + d += dstBytesPerLine; + s += srcBytesPerLine; + } while (--numScanLinesLeft); + + ++srcRect; + } while (--numRectsLeft); + } + + delete oldImage; +} + +QT_END_NAMESPACE diff --git a/src/gui/painting/qunifiedtoolbarsurface_mac_p.h b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h new file mode 100644 index 0000000..d7805e8 --- /dev/null +++ b/src/gui/painting/qunifiedtoolbarsurface_mac_p.h @@ -0,0 +1,95 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the QtGui module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QUNIFIEDTOOLBARSURFACE_MAC_P_H +#define QUNIFIEDTOOLBARSURFACE_MAC_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <private/qwindowsurface_raster_p.h> +#include <QWidget> +#include <private/qwidget_p.h> +#include <private/qnativeimage_p.h> + +QT_BEGIN_NAMESPACE + +class QNativeImage; + + +class QUnifiedToolbarSurfacePrivate +{ +public: + QNativeImage *image; + uint inSetGeometry : 1; +}; + +class Q_GUI_EXPORT QUnifiedToolbarSurface : public QRasterWindowSurface +{ +public: + QUnifiedToolbarSurface(QWidget *widget); + ~QUnifiedToolbarSurface(); + + void flush(QWidget *widget, const QRegion ®ion, const QPoint &offset); + void setGeometry(const QRect &rect); + void beginPaint(const QRegion &rgn); + void insertToolbar(QWidget *toolbar, const QPoint &offset); + +private: + QPaintDevice *paintDevice(); + void prepareBuffer(QImage::Format format, QWidget *widget); + void recursiveRedirect(QObject *widget, const QPoint &offset); + + Q_DECLARE_PRIVATE(QUnifiedToolbarSurface) + QScopedPointer<QUnifiedToolbarSurfacePrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QUNIFIEDTOOLBARSURFACE_MAC_P_H diff --git a/src/gui/painting/qwindowsurface.cpp b/src/gui/painting/qwindowsurface.cpp index 02a8b80..8cf3977 100644 --- a/src/gui/painting/qwindowsurface.cpp +++ b/src/gui/painting/qwindowsurface.cpp @@ -114,11 +114,11 @@ public: /*! Constructs an empty surface for the given top-level \a window. */ -QWindowSurface::QWindowSurface(QWidget *window) +QWindowSurface::QWindowSurface(QWidget *window, bool setDefaultSurface) : d_ptr(new QWindowSurfacePrivate(window)) { if (!QApplicationPrivate::runtime_graphics_system) { - if(window) + if(setDefaultSurface && window) window->setWindowSurface(this); } } diff --git a/src/gui/painting/qwindowsurface_p.h b/src/gui/painting/qwindowsurface_p.h index 6171ae8..ab84527 100644 --- a/src/gui/painting/qwindowsurface_p.h +++ b/src/gui/painting/qwindowsurface_p.h @@ -67,7 +67,7 @@ class QWindowSurfacePrivate; class Q_GUI_EXPORT QWindowSurface { public: - QWindowSurface(QWidget *window); + QWindowSurface(QWidget *window, bool setDefaultSurface = true); virtual ~QWindowSurface(); QWidget *window() const; diff --git a/src/gui/painting/qwindowsurface_raster.cpp b/src/gui/painting/qwindowsurface_raster.cpp index 6a2cb1e..99f8597 100644 --- a/src/gui/painting/qwindowsurface_raster.cpp +++ b/src/gui/painting/qwindowsurface_raster.cpp @@ -64,6 +64,9 @@ #ifdef Q_WS_MAC #include <private/qt_cocoa_helpers_mac_p.h> +#include <QMainWindow> +#include <private/qmainwindowlayout_p.h> +#include <QToolBar> #endif QT_BEGIN_NAMESPACE @@ -82,8 +85,8 @@ public: uint inSetGeometry : 1; }; -QRasterWindowSurface::QRasterWindowSurface(QWidget *window) - : QWindowSurface(window), d_ptr(new QRasterWindowSurfacePrivate) +QRasterWindowSurface::QRasterWindowSurface(QWidget *window, bool setDefaultSurface) + : QWindowSurface(window, setDefaultSurface), d_ptr(new QRasterWindowSurfacePrivate) { #ifdef Q_WS_X11 d_ptr->gc = XCreateGC(X11->display, window->handle(), 0, 0); @@ -248,6 +251,23 @@ void QRasterWindowSurface::flush(QWidget *widget, const QRegion &rgn, const QPoi #ifdef Q_WS_MAC + // Unified toolbar hack. + QMainWindow* mWindow = qobject_cast<QMainWindow*>(widget->window()); + if (mWindow) { + QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout()); + QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList; + + for (int i = 0; i < toolbarList.size(); ++i) { + QToolBar* toolbar = toolbarList.at(i); + if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) { + QWidget* tbWidget = (QWidget*) toolbar; + if (tbWidget->d_func()->unifiedSurface) { + tbWidget->d_func()->unifiedSurface->flush(tbWidget, rgn, offset); + } + } + } + } + Q_UNUSED(offset); // Get a context for the widget. #ifndef QT_MAC_USE_COCOA @@ -318,6 +338,23 @@ void QRasterWindowSurface::setGeometry(const QRect &rect) prepareBuffer(QNativeImage::systemFormat(), window()); } d->inSetGeometry = false; +#ifdef Q_WS_MAC + QMainWindow* mWindow = qobject_cast<QMainWindow*>(window()); + if (mWindow) { + QMainWindowLayout *mLayout = qobject_cast<QMainWindowLayout*>(mWindow->layout()); + QList<QToolBar *> toolbarList = mLayout->qtoolbarsInUnifiedToolbarList; + + for (int i = 0; i < toolbarList.size(); ++i) { + QToolBar* toolbar = toolbarList.at(i); + if (mLayout->toolBarArea(toolbar) == Qt::TopToolBarArea) { + QWidget* tbWidget = (QWidget*) toolbar; + if (tbWidget->d_func()->unifiedSurface) { + tbWidget->d_func()->unifiedSurface->setGeometry(rect); + } + } + } + } +#endif // Q_WS_MAC } // from qwindowsurface.cpp diff --git a/src/gui/painting/qwindowsurface_raster_p.h b/src/gui/painting/qwindowsurface_raster_p.h index 2b932a9..a7c3b9f 100644 --- a/src/gui/painting/qwindowsurface_raster_p.h +++ b/src/gui/painting/qwindowsurface_raster_p.h @@ -97,7 +97,7 @@ class QNativeImage; class Q_GUI_EXPORT QRasterWindowSurface : public QWindowSurface { public: - QRasterWindowSurface(QWidget *widget); + QRasterWindowSurface(QWidget *widget, bool setDefaultSurface = true); ~QRasterWindowSurface(); QPaintDevice *paintDevice(); |