1 // Commit: 55c4d94dfea78951f3371d3697a3cb28539b3012
2 /****************************************************************************
4 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
5 ** All rights reserved.
6 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 ** This file is part of the QtDeclarative module of the Qt Toolkit.
10 ** $QT_BEGIN_LICENSE:LGPL$
11 ** No Commercial Usage
12 ** This file contains pre-release code and may not be distributed.
13 ** You may use this file in accordance with the terms and conditions
14 ** contained in the Technology Preview License Agreement accompanying
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.
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights. These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
41 ****************************************************************************/
45 #include "qsgcanvas_p.h"
46 #include "qsgitem_p.h"
47 #include "qsgitemchangelistener_p.h"
49 #include <private/qdeclarativedebugtrace_p.h>
51 #include <QtDeclarative/qdeclarativeengine.h>
52 #include <private/qdeclarativeengine_p.h>
53 #include <QtCore/qbasictimer.h>
55 // XXX todo - This whole class should probably be merged with QDeclarativeView for
56 // maximum seamlessness
59 DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
61 class QSGViewPrivate : public QSGCanvasPrivate,
62 public QSGItemChangeListener
64 Q_DECLARE_PUBLIC(QSGView)
70 void itemGeometryChanged(QSGItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
73 void setRootObject(QObject *);
77 QSize rootObjectSize() const;
79 QPointer<QSGItem> root;
83 QDeclarativeEngine engine;
84 QDeclarativeComponent *component;
85 QBasicTimer resizetimer;
87 QSGView::ResizeMode resizeMode;
89 QElapsedTimer frameTimer;
92 void QSGViewPrivate::init()
94 q_func()->setSizePolicy(QSizePolicy::Preferred,QSizePolicy::Preferred);
95 QDeclarativeEnginePrivate::get(&engine)->sgContext = QSGCanvasPrivate::context;
98 QSGViewPrivate::QSGViewPrivate()
99 : root(0), component(0), resizeMode(QSGView::SizeViewToRootObject), initialSize(0,0)
103 QSGViewPrivate::~QSGViewPrivate()
108 void QSGViewPrivate::execute()
119 if (!source.isEmpty()) {
120 component = new QDeclarativeComponent(&engine, source, q);
121 if (!component->isLoading()) {
122 q->continueExecute();
124 QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
125 q, SLOT(continueExecute()));
130 void QSGViewPrivate::itemGeometryChanged(QSGItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
133 if (resizeItem == root && resizeMode == QSGView::SizeViewToRootObject) {
134 // wait for both width and height to be changed
135 resizetimer.start(0,q);
137 QSGItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
140 QSGView::QSGView(QWidget *parent, Qt::WindowFlags f)
141 : QSGCanvas(*(new QSGViewPrivate), parent, f)
146 QSGView::QSGView(const QGLFormat &format, QWidget *parent, Qt::WindowFlags f)
147 : QSGCanvas(*(new QSGViewPrivate), format, parent, f)
152 QSGView::QSGView(const QUrl &source, QWidget *parent, Qt::WindowFlags f)
153 : QSGCanvas(*(new QSGViewPrivate), parent, f)
159 QSGView::QSGView(const QUrl &source, const QGLFormat &format, QWidget *parent, Qt::WindowFlags f)
160 : QSGCanvas(*(new QSGViewPrivate), format, parent, f)
170 void QSGView::setSource(const QUrl& url)
177 QUrl QSGView::source() const
183 QDeclarativeEngine* QSGView::engine() const
186 return const_cast<QDeclarativeEngine *>(&d->engine);
189 QDeclarativeContext* QSGView::rootContext() const
192 return d->engine.rootContext();
195 QSGView::Status QSGView::status() const
199 return QSGView::Null;
201 return QSGView::Status(d->component->status());
204 QList<QDeclarativeError> QSGView::errors() const
208 return d->component->errors();
209 return QList<QDeclarativeError>();
212 void QSGView::setResizeMode(ResizeMode mode)
215 if (d->resizeMode == mode)
219 if (d->resizeMode == SizeViewToRootObject) {
220 QSGItemPrivate *p = QSGItemPrivate::get(d->root);
221 p->removeItemChangeListener(d, QSGItemPrivate::Geometry);
225 d->resizeMode = mode;
231 void QSGViewPrivate::initResize()
234 if (resizeMode == QSGView::SizeViewToRootObject) {
235 QSGItemPrivate *p = QSGItemPrivate::get(root);
236 p->addItemChangeListener(this, QSGItemPrivate::Geometry);
242 void QSGViewPrivate::updateSize()
248 if (resizeMode == QSGView::SizeViewToRootObject) {
249 QSize newSize = QSize(root->width(), root->height());
250 if (newSize.isValid() && newSize != q->size()) {
253 } else if (resizeMode == QSGView::SizeRootObjectToView) {
254 if (!qFuzzyCompare(q->width(), root->width()))
255 root->setWidth(q->width());
256 if (!qFuzzyCompare(q->height(), root->height()))
257 root->setHeight(q->height());
263 QSize QSGViewPrivate::rootObjectSize() const
265 QSize rootObjectSize(0,0);
266 int widthCandidate = -1;
267 int heightCandidate = -1;
269 widthCandidate = root->width();
270 heightCandidate = root->height();
272 if (widthCandidate > 0) {
273 rootObjectSize.setWidth(widthCandidate);
275 if (heightCandidate > 0) {
276 rootObjectSize.setHeight(heightCandidate);
278 return rootObjectSize;
281 QSGView::ResizeMode QSGView::resizeMode() const
284 return d->resizeMode;
290 void QSGView::continueExecute()
293 disconnect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute()));
295 if (d->component->isError()) {
296 QList<QDeclarativeError> errorList = d->component->errors();
297 foreach (const QDeclarativeError &error, errorList) {
300 emit statusChanged(status());
304 QObject *obj = d->component->create();
306 if(d->component->isError()) {
307 QList<QDeclarativeError> errorList = d->component->errors();
308 foreach (const QDeclarativeError &error, errorList) {
311 emit statusChanged(status());
315 d->setRootObject(obj);
316 emit statusChanged(status());
323 void QSGViewPrivate::setRootObject(QObject *obj)
328 if (QSGItem *sgItem = qobject_cast<QSGItem *>(obj)) {
330 sgItem->setParentItem(q->QSGCanvas::rootItem());
332 qWarning() << "QSGView only supports loading of root objects that derive from QSGItem." << endl
334 << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
335 << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
337 << "To load files with 'import QtQuick 1.0' with QML 2, specify:" << endl
338 << " QMLSCENE_IMPORT_NAME=quick1" << endl
339 << "on as an environment variable prior to launching the application." << endl
341 << "To load files with 'import Qt 4.7' with QML 2, specify:" << endl
342 << " QMLSCENE_IMPORT_NAME=qt" << endl
343 << "on as an environment variable prior to launching the application." << endl;
349 initialSize = rootObjectSize();
350 if (initialSize != q->size()) {
351 if (!(q->parentWidget() && q->parentWidget()->layout())) {
352 q->resize(initialSize);
361 If the \l {QTimerEvent} {timer event} \a e is this
362 view's resize timer, sceneResized() is emitted.
364 void QSGView::timerEvent(QTimerEvent* e)
367 if (!e || e->timerId() == d->resizetimer.timerId()) {
369 d->resizetimer.stop();
375 Preferred size follows the root object geometry.
377 QSize QSGView::sizeHint() const
380 QSize rootObjectSize = d->rootObjectSize();
381 if (rootObjectSize.isEmpty()) {
384 return rootObjectSize;
388 QSize QSGView::initialSize() const
391 return d->initialSize;
394 QSGItem *QSGView::rootObject() const
402 This function handles the \l {QResizeEvent} {resize event}
405 void QSGView::resizeEvent(QResizeEvent *e)
408 if (d->resizeMode == SizeRootObjectToView)
411 QSGCanvas::resizeEvent(e);
417 void QSGView::paintEvent(QPaintEvent *event)
421 if (frameRateDebug())
422 time = d->frameTimer.restart();
424 QSGCanvas::paintEvent(event);
426 if (frameRateDebug())
427 qDebug() << "paintEvent:" << d->frameTimer.elapsed() << "time since last frame:" << time;
430 void QSGView::keyPressEvent(QKeyEvent *e)
432 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
434 QSGCanvas::keyPressEvent(e);
437 void QSGView::keyReleaseEvent(QKeyEvent *e)
439 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
441 QSGCanvas::keyReleaseEvent(e);
444 void QSGView::mouseMoveEvent(QMouseEvent *e)
446 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
448 QSGCanvas::mouseMoveEvent(e);
451 void QSGView::mousePressEvent(QMouseEvent *e)
453 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
455 QSGCanvas::mousePressEvent(e);
458 void QSGView::mouseReleaseEvent(QMouseEvent *e)
460 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
462 QSGCanvas::mouseReleaseEvent(e);