Qt 4.8
qunifiedtoolbarsurface_mac.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2014 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the QtGui module of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:LGPL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia. For licensing terms and
14 ** conditions see http://qt.digia.com/licensing. For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Lesser General Public License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file. Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Digia gives you certain additional
26 ** rights. These rights are described in the Digia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** GNU General Public License Usage
30 ** Alternatively, this file may be used under the terms of the GNU
31 ** General Public License version 3.0 as published by the Free Software
32 ** Foundation and appearing in the file LICENSE.GPL included in the
33 ** packaging of this file. Please review the following information to
34 ** ensure the GNU General Public License version 3.0 requirements will be
35 ** met: http://www.gnu.org/copyleft/gpl.html.
36 **
37 **
38 ** $QT_END_LICENSE$
39 **
40 ****************************************************************************/
41 
43 #include <private/qt_cocoa_helpers_mac_p.h>
44 #include <private/qbackingstore_p.h>
45 #include <private/qmainwindowlayout_p.h>
46 
47 #include <QDebug>
48 
49 #ifdef QT_MAC_USE_COCOA
50 
52 
53 QUnifiedToolbarSurface::QUnifiedToolbarSurface(QWidget *widget)
54  : QRasterWindowSurface(widget, false), d_ptr(new QUnifiedToolbarSurfacePrivate)
55 {
56  d_ptr->image = 0;
57  d_ptr->inSetGeometry = false;
58 
59  setGeometry(QRect(QPoint(0, 0), QSize(widget->width(), 100))); // FIXME: Fix height.
60 }
61 
62 QUnifiedToolbarSurface::~QUnifiedToolbarSurface()
63 {
64  if (d_ptr->image)
65  delete d_ptr->image;
66 }
67 
68 QPaintDevice *QUnifiedToolbarSurface::paintDevice()
69 {
70  return &d_ptr->image->image;
71 }
72 
73 void QUnifiedToolbarSurface::recursiveRedirect(QObject *object, QWidget *parent_toolbar, const QPoint &offset)
74 {
75  if (object != 0) {
76  if (object->isWidgetType()) {
77  QWidget *widget = qobject_cast<QWidget *>(object);
78 
79  // We redirect the painting only if the widget is in the same window
80  // and is not a window in itself.
81  if (!(widget->windowType() & Qt::Window)) {
82  widget->d_func()->unifiedSurface = this;
83  widget->d_func()->isInUnifiedToolbar = true;
84  widget->d_func()->toolbar_offset = offset;
85  widget->d_func()->toolbar_ancestor = parent_toolbar;
86 
87  for (int i = 0; i < object->children().size(); ++i) {
88  recursiveRedirect(object->children().at(i), parent_toolbar, offset);
89  }
90  }
91  }
92  }
93 }
94 
95 void QUnifiedToolbarSurface::insertToolbar(QWidget *toolbar, const QPoint &offset)
96 {
97  setGeometry(QRect(QPoint(0, 0), QSize(offset.x() + toolbar->width(), 100))); // FIXME
98  recursiveRedirect(toolbar, toolbar, offset);
99 }
100 
101 // We basically undo what we set in recursiveRedirect().
102 void QUnifiedToolbarSurface::recursiveRemoval(QObject *object)
103 {
104  if (object != 0) {
105  if (object->isWidgetType()) {
106  QWidget *widget = qobject_cast<QWidget *>(object);
107 
108  // If it's a pop-up or something similar, we don't redirect it.
109  if (widget->windowType() & Qt::Window)
110  return;
111 
112  widget->d_func()->unifiedSurface = 0;
113  widget->d_func()->isInUnifiedToolbar = false;
114  widget->d_func()->toolbar_offset = QPoint();
115  widget->d_func()->toolbar_ancestor = 0;
116  }
117 
118  for (int i = 0; i < object->children().size(); ++i) {
119  recursiveRemoval(object->children().at(i));
120  }
121  }
122 }
123 
124 void QUnifiedToolbarSurface::removeToolbar(QToolBar *toolbar)
125 {
126  recursiveRemoval(toolbar);
127 }
128 
129 void QUnifiedToolbarSurface::setGeometry(const QRect &rect)
130 {
132  Q_D(QUnifiedToolbarSurface);
133  d->inSetGeometry = true;
134  if (d->image == 0 || d->image->width() < rect.width() || d->image->height() < rect.height())
136  d->inSetGeometry = false;
137 
138  // FIXME: set unified toolbar height.
139 }
140 
141 void QUnifiedToolbarSurface::beginPaint(const QRegion &rgn)
142 {
143  QPainter p(&d_ptr->image->image);
144  p.setCompositionMode(QPainter::CompositionMode_Source);
145  const QVector<QRect> rects = rgn.rects();
146  const QColor blank = Qt::transparent;
147  for (QVector<QRect>::const_iterator it = rects.begin(); it != rects.end(); ++it) {
148  p.fillRect(*it, blank);
149  }
150 }
151 
152 void QUnifiedToolbarSurface::updateToolbarOffset(QWidget *widget)
153 {
154  QMainWindowLayout *mlayout = qobject_cast<QMainWindowLayout*> (widget->window()->layout());
155  if (mlayout)
156  mlayout->updateUnifiedToolbarOffset();
157 }
158 
159 void QUnifiedToolbarSurface::flush(QWidget *widget, const QRegion &region, const QPoint &offset)
160 {
161  Q_UNUSED(region);
162  Q_UNUSED(offset);
163 
164  this->flush(widget);
165 }
166 
168 {
169  Q_D(QUnifiedToolbarSurface);
170 
171  if (!d->image)
172  return;
173 
174  if (widget->d_func()->flushRequested)
175  qt_mac_setNeedsDisplay(widget);
176 }
177 
178 void QUnifiedToolbarSurface::prepareBuffer(QImage::Format format, QWidget *widget)
179 {
180  Q_D(QUnifiedToolbarSurface);
181 
182  int width = geometry().width();
183  int height = 100; // FIXME
184  if (d->image) {
185  width = qMax(d->image->width(), width);
186  height = qMax(d->image->height(), height);
187  }
188 
189  if (width == 0 || height == 0) {
190  delete d->image;
191  d->image = 0;
192  return;
193  }
194 
195  QNativeImage *oldImage = d->image;
196 
197  d->image = new QNativeImage(width, height, format, false, widget);
198 
199  if (oldImage && d->inSetGeometry && hasStaticContents()) {
200  // Make sure we use the const version of bits() (no detach).
201  const uchar *src = const_cast<const QImage &>(oldImage->image).bits();
202  uchar *dst = d->image->image.bits();
203 
204  const int srcBytesPerLine = oldImage->image.bytesPerLine();
205  const int dstBytesPerLine = d->image->image.bytesPerLine();
206  const int bytesPerPixel = oldImage->image.depth() >> 3;
207 
208  QRegion staticRegion(staticContents());
209  // Make sure we're inside the boundaries of the old image.
210  staticRegion &= QRect(0, 0, oldImage->image.width(), oldImage->image.height());
211  const QVector<QRect> &rects = staticRegion.rects();
212  const QRect *srcRect = rects.constData();
213 
214  // Copy the static content of the old image into the new one.
215  int numRectsLeft = rects.size();
216  do {
217  const int bytesOffset = srcRect->x() * bytesPerPixel;
218  const int dy = srcRect->y();
219 
220  // Adjust src and dst to point to the right offset.
221  const uchar *s = src + dy * srcBytesPerLine + bytesOffset;
222  uchar *d = dst + dy * dstBytesPerLine + bytesOffset;
223  const int numBytes = srcRect->width() * bytesPerPixel;
224 
225  int numScanLinesLeft = srcRect->height();
226  do {
227  ::memcpy(d, s, numBytes);
228  d += dstBytesPerLine;
229  s += srcBytesPerLine;
230  } while (--numScanLinesLeft);
231 
232  ++srcRect;
233  } while (--numRectsLeft);
234  }
235 
236  delete oldImage;
237 }
238 
239 CGContextRef QUnifiedToolbarSurface::imageContext()
240 {
241  Q_D(QUnifiedToolbarSurface);
242  return d->image->cg;
243 }
244 
245 void QUnifiedToolbarSurface::renderToolbar(QWidget *widget, bool forceFlush)
246 {
247  QWidget *toolbar = widget->d_func()->toolbar_ancestor;
248 
249  updateToolbarOffset(toolbar);
250  QRect beginPaintRect(toolbar->d_func()->toolbar_offset.x(), toolbar->d_func()->toolbar_offset.y(), toolbar->geometry().width(), toolbar->geometry().height());
251  QRegion beginPaintRegion(beginPaintRect);
252 
253  beginPaint(beginPaintRegion);
254  toolbar->render(paintDevice(), toolbar->d_func()->toolbar_offset, QRegion(toolbar->geometry()), QWidget::DrawChildren);
255  toolbar->d_func()->flushRequested = true;
256 
257  if (forceFlush)
258  flush(toolbar);
259 }
260 
262 
263 #endif // QT_MAC_USE_COCOA
The QPainter class performs low-level painting on widgets and other paint devices.
Definition: qpainter.h:86
The QColor class provides colors based on RGB, HSV or CMYK values.
Definition: qcolor.h:67
double d
Definition: qnumeric_p.h:62
Format
The following image formats are available in Qt.
Definition: qimage.h:91
#define QT_END_NAMESPACE
This macro expands to.
Definition: qglobal.h:90
QPointer< QWidget > widget
int width
the width of the widget excluding any window frame
Definition: qwidget.h:166
#define it(className, varName)
The QWidget class is the base class of all user interface objects.
Definition: qwidget.h:150
static int bytesPerPixel(QImage::Format format)
virtual void setGeometry(const QRect &rect)
Sets the currently allocated area to be the given rect.
int width() const
Returns the width of the rectangle.
Definition: qrect.h:303
int bytesPerLine() const
Returns the number of bytes per image scanline.
Definition: qimage.cpp:1812
int height() const
Returns the height of the rectangle.
Definition: qrect.h:306
T * qobject_cast(QObject *object)
Definition: qobject.h:375
The QObject class is the base class of all Qt objects.
Definition: qobject.h:111
#define Q_D(Class)
Definition: qglobal.h:2482
int x
the x coordinate of the widget relative to its parent including any window frame
Definition: qwidget.h:161
NSToolbar * toolbar
Q_DECL_CONSTEXPR const T & qMax(const T &a, const T &b)
Definition: qglobal.h:1217
iterator end()
Returns an STL-style iterator pointing to the imaginary item after the last item in the vector...
Definition: qvector.h:250
unsigned char uchar
Definition: qglobal.h:994
NSWindow * window
#define QT_BEGIN_NAMESPACE
This macro expands to.
Definition: qglobal.h:89
The QToolBar class provides a movable panel that contains a set of controls.
Definition: qtoolbar.h:62
QSize size() const
Returns the size of the rectangle.
Definition: qrect.h:309
const T & at(int i) const
Returns the item at index position i in the list.
Definition: qlist.h:468
The QImage class provides a hardware-independent image representation that allows direct access to th...
Definition: qimage.h:87
The QRegion class specifies a clip region for a painter.
Definition: qregion.h:68
int depth() const
Returns the depth of the image.
Definition: qimage.cpp:1620
bool isWidgetType() const
Returns true if the object is a widget; otherwise returns false.
Definition: qobject.h:146
int width() const
Returns the width of the image.
Definition: qimage.cpp:1557
iterator begin()
Returns an STL-style iterator pointing to the first item in the vector.
Definition: qvector.h:247
int y() const
Returns the y-coordinate of the rectangle&#39;s top edge.
Definition: qrect.h:255
int y
the y coordinate of the widget relative to its parent and including any window frame ...
Definition: qwidget.h:162
int x() const
Returns the x-coordinate of the rectangle&#39;s left edge.
Definition: qrect.h:252
The QPoint class defines a point in the plane using integer precision.
Definition: qpoint.h:53
QVector< QRect > rects() const
Returns an array of non-overlapping rectangles that make up the region.
Definition: qregion.cpp:4412
The QRect class defines a rectangle in the plane using integer precision.
Definition: qrect.h:58
const QObjectList & children() const
Returns a list of child objects.
Definition: qobject.h:197
int height() const
Returns the height of the image.
Definition: qimage.cpp:1572
QWidget * window() const
Returns the window for this widget, i.e.
Definition: qwidget.cpp:4492
Q_CORE_EXPORT QTextStream & flush(QTextStream &s)
QLayout * layout() const
Returns the layout manager that is installed on this widget, or 0 if no layout manager is installed...
Definition: qwidget.cpp:10073
The QSize class defines the size of a two-dimensional object using integer point precision.
Definition: qsize.h:53
Qt::WindowType windowType() const
Returns the window type of this widget.
Definition: qwidget.h:937
int x() const
Returns the x coordinate of this point.
Definition: qpoint.h:128
struct CGContext * CGContextRef
void render(QPaintDevice *target, const QPoint &targetOffset=QPoint(), const QRegion &sourceRegion=QRegion(), RenderFlags renderFlags=RenderFlags(DrawWindowBackground|DrawChildren))
Renders the sourceRegion of this widget into the target using renderFlags to determine how to render...
Definition: qwidget.cpp:5372
#define Q_UNUSED(x)
Indicates to the compiler that the parameter with the specified name is not used in the body of a fun...
Definition: qglobal.h:1729
QRect geometry
the geometry of the widget relative to its parent and excluding the window frame
Definition: qwidget.h:158
QTextStream & flush(QTextStream &stream)
Calls QTextStream::flush() on stream and returns stream.