1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the QtDeclarative module of the Qt Toolkit.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "qquickview.h"
43 #include "qquickview_p.h"
45 #include "qquickcanvas_p.h"
46 #include "qquickitem_p.h"
47 #include "qquickitemchangelistener_p.h"
49 #include <private/qdeclarativedebugtrace_p.h>
50 #include <private/qdeclarativeinspectorservice_p.h>
52 #include <QtDeclarative/qdeclarativeengine.h>
53 #include <private/qdeclarativeengine_p.h>
54 #include <QtCore/qbasictimer.h>
57 // XXX todo - This whole class should probably be merged with QDeclarativeView for
58 // maximum seamlessness
61 DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
63 void QQuickViewPrivate::init()
67 QDeclarativeEnginePrivate::get(&engine)->sgContext = QQuickCanvasPrivate::context;
69 engine.setIncubationController(q->incubationController());
71 if (QDeclarativeDebugService::isDebuggingEnabled())
72 QDeclarativeInspectorService::instance()->addView(q);
75 QQuickViewPrivate::QQuickViewPrivate()
76 : root(0), component(0), resizeMode(QQuickView::SizeViewToRootObject), initialSize(0,0)
80 QQuickViewPrivate::~QQuickViewPrivate()
82 if (QDeclarativeDebugService::isDebuggingEnabled())
83 QDeclarativeInspectorService::instance()->removeView(q_func());
88 void QQuickViewPrivate::execute()
99 if (!source.isEmpty()) {
100 component = new QDeclarativeComponent(&engine, source, q);
101 if (!component->isLoading()) {
102 q->continueExecute();
104 QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)),
105 q, SLOT(continueExecute()));
110 void QQuickViewPrivate::itemGeometryChanged(QQuickItem *resizeItem, const QRectF &newGeometry, const QRectF &oldGeometry)
113 if (resizeItem == root && resizeMode == QQuickView::SizeViewToRootObject) {
114 // wait for both width and height to be changed
115 resizetimer.start(0,q);
117 QQuickItemChangeListener::itemGeometryChanged(resizeItem, newGeometry, oldGeometry);
120 QQuickView::QQuickView(QWindow *parent, Qt::WindowFlags f)
121 : QQuickCanvas(*(new QQuickViewPrivate), parent)
127 QQuickView::QQuickView(const QUrl &source, QWindow *parent, Qt::WindowFlags f)
128 : QQuickCanvas(*(new QQuickViewPrivate), parent)
135 QQuickView::~QQuickView()
139 void QQuickView::setSource(const QUrl& url)
146 QUrl QQuickView::source() const
148 Q_D(const QQuickView);
152 QDeclarativeEngine* QQuickView::engine() const
154 Q_D(const QQuickView);
155 return const_cast<QDeclarativeEngine *>(&d->engine);
158 QDeclarativeContext* QQuickView::rootContext() const
160 Q_D(const QQuickView);
161 return d->engine.rootContext();
164 QQuickView::Status QQuickView::status() const
166 Q_D(const QQuickView);
168 return QQuickView::Null;
170 return QQuickView::Status(d->component->status());
173 QList<QDeclarativeError> QQuickView::errors() const
175 Q_D(const QQuickView);
177 return d->component->errors();
178 return QList<QDeclarativeError>();
181 void QQuickView::setResizeMode(ResizeMode mode)
184 if (d->resizeMode == mode)
188 if (d->resizeMode == SizeViewToRootObject) {
189 QQuickItemPrivate *p = QQuickItemPrivate::get(d->root);
190 p->removeItemChangeListener(d, QQuickItemPrivate::Geometry);
194 d->resizeMode = mode;
200 void QQuickViewPrivate::initResize()
203 if (resizeMode == QQuickView::SizeViewToRootObject) {
204 QQuickItemPrivate *p = QQuickItemPrivate::get(root);
205 p->addItemChangeListener(this, QQuickItemPrivate::Geometry);
211 void QQuickViewPrivate::updateSize()
217 if (resizeMode == QQuickView::SizeViewToRootObject) {
218 QSize newSize = QSize(root->width(), root->height());
219 if (newSize.isValid() && newSize != q->size()) {
222 } else if (resizeMode == QQuickView::SizeRootObjectToView) {
223 if (!qFuzzyCompare(q->width(), root->width()))
224 root->setWidth(q->width());
225 if (!qFuzzyCompare(q->height(), root->height()))
226 root->setHeight(q->height());
230 QSize QQuickViewPrivate::rootObjectSize() const
232 QSize rootObjectSize(0,0);
233 int widthCandidate = -1;
234 int heightCandidate = -1;
236 widthCandidate = root->width();
237 heightCandidate = root->height();
239 if (widthCandidate > 0) {
240 rootObjectSize.setWidth(widthCandidate);
242 if (heightCandidate > 0) {
243 rootObjectSize.setHeight(heightCandidate);
245 return rootObjectSize;
248 QQuickView::ResizeMode QQuickView::resizeMode() const
250 Q_D(const QQuickView);
251 return d->resizeMode;
257 void QQuickView::continueExecute()
260 disconnect(d->component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), this, SLOT(continueExecute()));
262 if (d->component->isError()) {
263 QList<QDeclarativeError> errorList = d->component->errors();
264 foreach (const QDeclarativeError &error, errorList) {
267 emit statusChanged(status());
271 QObject *obj = d->component->create();
273 if (d->component->isError()) {
274 QList<QDeclarativeError> errorList = d->component->errors();
275 foreach (const QDeclarativeError &error, errorList) {
278 emit statusChanged(status());
282 d->setRootObject(obj);
283 emit statusChanged(status());
290 void QQuickViewPrivate::setRootObject(QObject *obj)
295 if (QQuickItem *sgItem = qobject_cast<QQuickItem *>(obj)) {
297 sgItem->setParentItem(q->QQuickCanvas::rootItem());
299 qWarning() << "QQuickView only supports loading of root objects that derive from QQuickItem." << endl
301 << "If your example is using QML 2, (such as qmlscene) and the .qml file you" << endl
302 << "loaded has 'import QtQuick 1.0' or 'import Qt 4.7', this error will occur." << endl
304 << "To load files with 'import QtQuick 1.0' with QML 2, specify:" << endl
305 << " QMLSCENE_IMPORT_NAME=quick1" << endl
306 << "on as an environment variable prior to launching the application." << endl
308 << "To load files with 'import Qt 4.7' with QML 2, specify:" << endl
309 << " QMLSCENE_IMPORT_NAME=qt" << endl
310 << "on as an environment variable prior to launching the application." << endl;
315 initialSize = rootObjectSize();
316 if ((resizeMode == QQuickView::SizeViewToRootObject || !q->width() || !q->height())
317 && initialSize != q->size()) {
318 q->resize(initialSize);
326 If the \l {QTimerEvent} {timer event} \a e is this
327 view's resize timer, sceneResized() is emitted.
329 void QQuickView::timerEvent(QTimerEvent* e)
332 if (!e || e->timerId() == d->resizetimer.timerId()) {
334 d->resizetimer.stop();
340 Preferred size follows the root object geometry.
342 QSize QQuickView::sizeHint() const
344 Q_D(const QQuickView);
345 QSize rootObjectSize = d->rootObjectSize();
346 if (rootObjectSize.isEmpty()) {
349 return rootObjectSize;
353 QSize QQuickView::initialSize() const
355 Q_D(const QQuickView);
356 return d->initialSize;
359 QQuickItem *QQuickView::rootObject() const
361 Q_D(const QQuickView);
367 This function handles the \l {QResizeEvent} {resize event}
370 void QQuickView::resizeEvent(QResizeEvent *e)
373 if (d->resizeMode == SizeRootObjectToView)
376 QQuickCanvas::resizeEvent(e);
379 void QQuickView::keyPressEvent(QKeyEvent *e)
381 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
383 QQuickCanvas::keyPressEvent(e);
386 void QQuickView::keyReleaseEvent(QKeyEvent *e)
388 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
390 QQuickCanvas::keyReleaseEvent(e);
393 void QQuickView::mouseMoveEvent(QMouseEvent *e)
395 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
397 QQuickCanvas::mouseMoveEvent(e);
400 void QQuickView::mousePressEvent(QMouseEvent *e)
402 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
404 QQuickCanvas::mousePressEvent(e);
407 void QQuickView::mouseReleaseEvent(QMouseEvent *e)
409 QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
411 QQuickCanvas::mouseReleaseEvent(e);