src/declarative/util/qdeclarativeview.cpp
changeset 33 3e2da88830cd
parent 30 5dc02b23752f
child 37 758a864f9613
equal deleted inserted replaced
30:5dc02b23752f 33:3e2da88830cd
    43 
    43 
    44 #include <qdeclarative.h>
    44 #include <qdeclarative.h>
    45 #include <qdeclarativeitem.h>
    45 #include <qdeclarativeitem.h>
    46 #include <qdeclarativeengine.h>
    46 #include <qdeclarativeengine.h>
    47 #include <qdeclarativecontext.h>
    47 #include <qdeclarativecontext.h>
    48 #include <qdeclarativedebug_p.h>
       
    49 #include <qdeclarativedebugservice_p.h>
       
    50 #include <qdeclarativeglobal_p.h>
    48 #include <qdeclarativeglobal_p.h>
    51 #include <qdeclarativeguard_p.h>
    49 #include <qdeclarativeguard_p.h>
       
    50 
       
    51 #include <private/qdeclarativedebugtrace_p.h>
    52 
    52 
    53 #include <qscriptvalueiterator.h>
    53 #include <qscriptvalueiterator.h>
    54 #include <qdebug.h>
    54 #include <qdebug.h>
    55 #include <qtimer.h>
    55 #include <qtimer.h>
    56 #include <qevent.h>
    56 #include <qevent.h>
    64 #include <qgraphicswidget.h>
    64 #include <qgraphicswidget.h>
    65 #include <qbasictimer.h>
    65 #include <qbasictimer.h>
    66 #include <QtCore/qabstractanimation.h>
    66 #include <QtCore/qabstractanimation.h>
    67 #include <private/qgraphicsview_p.h>
    67 #include <private/qgraphicsview_p.h>
    68 #include <private/qdeclarativeitem_p.h>
    68 #include <private/qdeclarativeitem_p.h>
       
    69 #include <private/qabstractanimation_p.h>
    69 #include <private/qdeclarativeitemchangelistener_p.h>
    70 #include <private/qdeclarativeitemchangelistener_p.h>
    70 
    71 
    71 QT_BEGIN_NAMESPACE
    72 QT_BEGIN_NAMESPACE
    72 
    73 
    73 DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
    74 DEFINE_BOOL_CONFIG_OPTION(frameRateDebug, QML_SHOW_FRAMERATE)
    74 
    75 
    75 class QDeclarativeViewDebugServer;
    76 class QDeclarativeScene : public QGraphicsScene
    76 class FrameBreakAnimation : public QAbstractAnimation
       
    77 {
    77 {
    78 public:
    78 public:
    79     FrameBreakAnimation(QDeclarativeViewDebugServer *s)
    79     QDeclarativeScene();
    80     : QAbstractAnimation((QObject*)s), server(s)
    80 
    81     {
    81 protected:
    82         start();
    82     virtual void keyPressEvent(QKeyEvent *);
    83     }
    83     virtual void keyReleaseEvent(QKeyEvent *);
    84 
    84 
    85     virtual int duration() const { return -1; }
    85     virtual void mouseMoveEvent(QGraphicsSceneMouseEvent *);
    86     virtual void updateCurrentTime(int msecs);
    86     virtual void mousePressEvent(QGraphicsSceneMouseEvent *);
    87 
    87     virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *);
    88 private:
       
    89     QDeclarativeViewDebugServer *server;
       
    90 };
    88 };
    91 
    89 
    92 class QDeclarativeViewDebugServer : public QDeclarativeDebugService
    90 QDeclarativeScene::QDeclarativeScene()
    93 {
    91 {
    94 public:
    92 }
    95     QDeclarativeViewDebugServer(QObject *parent = 0) : QDeclarativeDebugService(QLatin1String("CanvasFrameRate"), parent), breaks(0)
    93 
    96     {
    94 void QDeclarativeScene::keyPressEvent(QKeyEvent *e)
    97         timer.start();
    95 {
    98         new FrameBreakAnimation(this);
    96     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
    99     }
    97 
   100 
    98     QGraphicsScene::keyPressEvent(e);
   101     void addTiming(int pe, int tbf)
    99 }
   102     {
   100 
   103         if (!isEnabled())
   101 void QDeclarativeScene::keyReleaseEvent(QKeyEvent *e)
   104             return;
   102 {
   105 
   103     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Key);
   106         bool isFrameBreak = breaks > 1;
   104 
   107         breaks = 0;
   105     QGraphicsScene::keyReleaseEvent(e);
   108         int e = timer.elapsed();
   106 }
   109         QByteArray data;
   107 
   110         QDataStream ds(&data, QIODevice::WriteOnly);
   108 void QDeclarativeScene::mouseMoveEvent(QGraphicsSceneMouseEvent *e)
   111         ds << (int)pe << (int)tbf << (int)e
   109 {
   112            << (bool)isFrameBreak;
   110     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
   113         sendMessage(data);
   111 
   114     }
   112     QGraphicsScene::mouseMoveEvent(e);
   115 
   113 }
   116     void frameBreak() { ++breaks; }
   114 
   117 
   115 void QDeclarativeScene::mousePressEvent(QGraphicsSceneMouseEvent *e)
   118 private:
   116 {
   119     QTime timer;
   117     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
   120     int breaks;
   118 
   121 };
   119     QGraphicsScene::mousePressEvent(e);
   122 
   120 }
   123 Q_GLOBAL_STATIC(QDeclarativeViewDebugServer, qfxViewDebugServer);
   121 
   124 
   122 void QDeclarativeScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *e)
   125 void FrameBreakAnimation::updateCurrentTime(int msecs)
   123 {
   126 {
   124     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::Mouse);
   127     Q_UNUSED(msecs);
   125 
   128     server->frameBreak();
   126     QGraphicsScene::mouseReleaseEvent(e);
   129 }
   127 }
   130 
   128 
   131 class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarativeItemChangeListener
   129 class QDeclarativeViewPrivate : public QGraphicsViewPrivate, public QDeclarativeItemChangeListener
   132 {
   130 {
   133     Q_DECLARE_PUBLIC(QDeclarativeView)
   131     Q_DECLARE_PUBLIC(QDeclarativeView)
   134 public:
   132 public:
   135     QDeclarativeViewPrivate()
   133     QDeclarativeViewPrivate()
   136         : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject) {}
   134         : root(0), declarativeItemRoot(0), graphicsWidgetRoot(0), component(0), resizeMode(QDeclarativeView::SizeViewToRootObject), initialSize(0,0) {}
   137     ~QDeclarativeViewPrivate() { delete root; }
   135     ~QDeclarativeViewPrivate() { delete root; delete engine; }
   138     void execute();
   136     void execute();
   139     void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
   137     void itemGeometryChanged(QDeclarativeItem *item, const QRectF &newGeometry, const QRectF &oldGeometry);
   140     void initResize();
   138     void initResize();
   141     void updateSize();
   139     void updateSize();
   142     inline QSize rootObjectSize() const;
   140     inline QSize rootObjectSize() const;
   145     QDeclarativeGuard<QDeclarativeItem> declarativeItemRoot;
   143     QDeclarativeGuard<QDeclarativeItem> declarativeItemRoot;
   146     QDeclarativeGuard<QGraphicsWidget> graphicsWidgetRoot;
   144     QDeclarativeGuard<QGraphicsWidget> graphicsWidgetRoot;
   147 
   145 
   148     QUrl source;
   146     QUrl source;
   149 
   147 
   150     QDeclarativeEngine engine;
   148     QDeclarativeEngine* engine;
   151     QDeclarativeComponent *component;
   149     QDeclarativeComponent *component;
   152     QBasicTimer resizetimer;
   150     QBasicTimer resizetimer;
   153 
   151 
   154     QDeclarativeView::ResizeMode resizeMode;
   152     QDeclarativeView::ResizeMode resizeMode;
   155     QTime frameTimer;
   153     QSize initialSize;
       
   154     QElapsedTimer frameTimer;
   156 
   155 
   157     void init();
   156     void init();
   158 
   157 
   159     QGraphicsScene scene;
   158     QDeclarativeScene scene;
   160 };
   159 };
   161 
   160 
   162 void QDeclarativeViewPrivate::execute()
   161 void QDeclarativeViewPrivate::execute()
   163 {
   162 {
   164     Q_Q(QDeclarativeView);
   163     Q_Q(QDeclarativeView);
   169     if (component) {
   168     if (component) {
   170         delete component;
   169         delete component;
   171         component = 0;
   170         component = 0;
   172     }
   171     }
   173     if (!source.isEmpty()) {
   172     if (!source.isEmpty()) {
   174         component = new QDeclarativeComponent(&engine, source, q);
   173         component = new QDeclarativeComponent(engine, source, q);
   175         if (!component->isLoading()) {
   174         if (!component->isLoading()) {
   176             q->continueExecute();
   175             q->continueExecute();
   177         } else {
   176         } else {
   178             QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), q, SLOT(continueExecute()));
   177             QObject::connect(component, SIGNAL(statusChanged(QDeclarativeComponent::Status)), q, SLOT(continueExecute()));
   179         }
   178         }
   193 /*!
   192 /*!
   194     \class QDeclarativeView
   193     \class QDeclarativeView
   195   \since 4.7
   194   \since 4.7
   196     \brief The QDeclarativeView class provides a widget for displaying a Qt Declarative user interface.
   195     \brief The QDeclarativeView class provides a widget for displaying a Qt Declarative user interface.
   197 
   196 
   198     Any QGraphicsObject or QDeclarativeItem
   197     QDeclarativeItem objects can be placed on a standard QGraphicsScene and 
   199     created via QML can be placed on a standard QGraphicsScene and viewed with a standard
   198     displayed with QGraphicsView. QDeclarativeView is a QGraphicsView subclass 
   200     QGraphicsView.
   199     provided as a convenience for displaying QML files, and connecting between 
   201 
   200     QML and C++ Qt objects.
   202     QDeclarativeView is a QGraphicsView subclass provided as a convenience for displaying QML
   201 
   203     files, and connecting between QML and C++ Qt objects.
   202     QDeclarativeView provides:
   204 
       
   205     QDeclarativeView performs the following functions:
       
   206 
   203 
   207     \list
   204     \list
   208     \o Manages QDeclarativeComponent loading and object creation.
   205     \o Management of QDeclarativeComponent loading and object creation
   209     \o Initializes QGraphicsView for optimal performance with QML:
   206     \o Initialization of QGraphicsView for optimal performance with QML using these settings:
   210         \list
   207         \list
   211         \o QGraphicsView::setOptimizationFlags(QGraphicsView::DontSavePainterState);
   208         \o QGraphicsView::setOptimizationFlags(QGraphicsView::DontSavePainterState)
   212         \o QGraphicsView::setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate);
   209         \o QGraphicsView::setViewportUpdateMode(QGraphicsView::BoundingRectViewportUpdate)
   213         \o QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex);
   210         \o QGraphicsScene::setItemIndexMethod(QGraphicsScene::NoIndex)
   214         \endlist
   211         \endlist
   215     \o Initializes QGraphicsView for QML key handling:
   212     \o Initialization of QGraphicsView for QML key handling using these settings:
   216         \list
   213         \list
   217         \o QGraphicsView::viewport()->setFocusPolicy(Qt::NoFocus);
   214         \o QGraphicsView::viewport()->setFocusPolicy(Qt::NoFocus)
   218         \o QGraphicsView::setFocusPolicy(Qt::StrongFocus);
   215         \o QGraphicsView::setFocusPolicy(Qt::StrongFocus)
   219         \o QGraphicsScene::setStickyFocus(true);
   216         \o QGraphicsScene::setStickyFocus(true)
   220         \endlist
   217         \endlist
   221     \endlist
   218     \endlist
   222 
   219 
   223     Typical usage:
   220     Typical usage:
       
   221 
   224     \code
   222     \code
   225     ...
   223     QDeclarativeView *view = new QDeclarativeView;
   226     QDeclarativeView *view = new QDeclarativeView(this);
   224     view->setSource(QUrl::fromLocalFile("myqmlfile.qml"));
   227     vbox->addWidget(view);
       
   228 
       
   229     QUrl url = QUrl::fromLocalFile(fileName);
       
   230     view->setSource(url);
       
   231     view->show();
   225     view->show();
   232     \endcode
   226     \endcode
       
   227 
       
   228     Since QDeclarativeView is a QWidget-based class, it can be used to
       
   229     display QML interfaces within QWidget-based GUI applications that do not
       
   230     use the Graphics View framework.
   233 
   231 
   234     To receive errors related to loading and executing QML with QDeclarativeView,
   232     To receive errors related to loading and executing QML with QDeclarativeView,
   235     you can connect to the statusChanged() signal and monitor for QDeclarativeView::Error.
   233     you can connect to the statusChanged() signal and monitor for QDeclarativeView::Error.
   236     The errors are available via QDeclarativeView::errors().
   234     The errors are available via QDeclarativeView::errors().
       
   235 
       
   236     \sa {Integrating QML with existing Qt UI code}, {Using QML in C++ Applications}
   237 */
   237 */
   238 
   238 
   239 
   239 
   240 /*! \fn void QDeclarativeView::sceneResized(QSize size)
   240 /*! \fn void QDeclarativeView::sceneResized(QSize size)
   241   This signal is emitted when the view is resized to \a size.
   241   This signal is emitted when the view is resized to \a size.
   273 }
   273 }
   274 
   274 
   275 void QDeclarativeViewPrivate::init()
   275 void QDeclarativeViewPrivate::init()
   276 {
   276 {
   277     Q_Q(QDeclarativeView);
   277     Q_Q(QDeclarativeView);
       
   278     engine = new QDeclarativeEngine();
   278     q->setScene(&scene);
   279     q->setScene(&scene);
   279 
   280 
   280     q->setOptimizationFlags(QGraphicsView::DontSavePainterState);
   281     q->setOptimizationFlags(QGraphicsView::DontSavePainterState);
   281     q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   282     q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   282     q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   283     q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
   336 
   337 
   337 /*!
   338 /*!
   338   Returns a pointer to the QDeclarativeEngine used for instantiating
   339   Returns a pointer to the QDeclarativeEngine used for instantiating
   339   QML Components.
   340   QML Components.
   340  */
   341  */
   341 QDeclarativeEngine* QDeclarativeView::engine()
   342 QDeclarativeEngine* QDeclarativeView::engine() const
   342 {
   343 {
   343     Q_D(QDeclarativeView);
   344     Q_D(const QDeclarativeView);
   344     return &d->engine;
   345     return d->engine;
   345 }
   346 }
   346 
   347 
   347 /*!
   348 /*!
   348   This function returns the root of the context hierarchy.  Each QML
   349   This function returns the root of the context hierarchy.  Each QML
   349   component is instantiated in a QDeclarativeContext.  QDeclarativeContext's are
   350   component is instantiated in a QDeclarativeContext.  QDeclarativeContext's are
   350   essential for passing data to QML components.  In QML, contexts are
   351   essential for passing data to QML components.  In QML, contexts are
   351   arranged hierarchically and this hierarchy is managed by the
   352   arranged hierarchically and this hierarchy is managed by the
   352   QDeclarativeEngine.
   353   QDeclarativeEngine.
   353  */
   354  */
   354 QDeclarativeContext* QDeclarativeView::rootContext()
   355 QDeclarativeContext* QDeclarativeView::rootContext() const
   355 {
   356 {
   356     Q_D(QDeclarativeView);
   357     Q_D(const QDeclarativeView);
   357     return d->engine.rootContext();
   358     return d->engine->rootContext();
   358 }
   359 }
   359 
   360 
   360 /*!
   361 /*!
   361   \enum QDeclarativeView::Status
   362   \enum QDeclarativeView::Status
   362     Specifies the loading status of the QDeclarativeView.
   363     Specifies the loading status of the QDeclarativeView.
   586             resize(widget->size());
   587             resize(widget->size());
   587         }
   588         }
   588     }
   589     }
   589 
   590 
   590     if (d->root) {
   591     if (d->root) {
   591         QSize initialSize = d->rootObjectSize();
   592         d->initialSize = d->rootObjectSize();
   592         if (initialSize != size()) {
   593         if (d->initialSize != size()) {
   593             resize(initialSize);
   594             if (!(parentWidget() && parentWidget()->layout())) {
       
   595                 resize(d->initialSize);
       
   596             }
   594         }
   597         }
   595         d->initResize();
   598         d->initResize();
   596     }
   599     }
   597 }
   600 }
   598 
   601 
   608         d->updateSize();
   611         d->updateSize();
   609         d->resizetimer.stop();
   612         d->resizetimer.stop();
   610     }
   613     }
   611 }
   614 }
   612 
   615 
   613 /*! \reimp */
   616 /*! \internal */
   614 bool QDeclarativeView::eventFilter(QObject *watched, QEvent *e)
   617 bool QDeclarativeView::eventFilter(QObject *watched, QEvent *e)
   615 {
   618 {
   616     Q_D(QDeclarativeView);
   619     Q_D(QDeclarativeView);
   617     if (watched == d->root && d->resizeMode == SizeViewToRootObject) {
   620     if (watched == d->root && d->resizeMode == SizeViewToRootObject) {
   618         if (d->graphicsWidgetRoot) {
   621         if (d->graphicsWidgetRoot) {
   635     if (rootObjectSize.isEmpty()) {
   638     if (rootObjectSize.isEmpty()) {
   636         return size();
   639         return size();
   637     } else {
   640     } else {
   638         return rootObjectSize;
   641         return rootObjectSize;
   639     }
   642     }
       
   643 }
       
   644 
       
   645 /*!
       
   646   Returns the initial size of the root object
       
   647 */
       
   648 QSize QDeclarativeView::initialSize() const
       
   649 {
       
   650     Q_D(const QDeclarativeView);
       
   651     return d->initialSize;
   640 }
   652 }
   641 
   653 
   642 /*!
   654 /*!
   643   Returns the view's root \l {QGraphicsObject} {item}.
   655   Returns the view's root \l {QGraphicsObject} {item}.
   644  */
   656  */
   674     \internal
   686     \internal
   675 */
   687 */
   676 void QDeclarativeView::paintEvent(QPaintEvent *event)
   688 void QDeclarativeView::paintEvent(QPaintEvent *event)
   677 {
   689 {
   678     Q_D(QDeclarativeView);
   690     Q_D(QDeclarativeView);
       
   691 
       
   692     QDeclarativeDebugTrace::addEvent(QDeclarativeDebugTrace::FramePaint);
       
   693     QDeclarativeDebugTrace::startRange(QDeclarativeDebugTrace::Painting);
       
   694 
   679     int time = 0;
   695     int time = 0;
   680     if (frameRateDebug() || QDeclarativeViewDebugServer::isDebuggingEnabled())
   696     if (frameRateDebug()) 
   681         time = d->frameTimer.restart();
   697         time = d->frameTimer.restart();
       
   698 
   682     QGraphicsView::paintEvent(event);
   699     QGraphicsView::paintEvent(event);
   683     if (QDeclarativeViewDebugServer::isDebuggingEnabled())
   700 
   684         qfxViewDebugServer()->addTiming(d->frameTimer.elapsed(), time);
   701     QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Painting);
       
   702 
   685     if (frameRateDebug())
   703     if (frameRateDebug())
   686         qDebug() << "paintEvent:" << d->frameTimer.elapsed() << "time since last frame:" << time;
   704         qDebug() << "paintEvent:" << d->frameTimer.elapsed() << "time since last frame:" << time;
   687 }
   705 }
   688 
   706 
   689 QT_END_NAMESPACE
   707 QT_END_NAMESPACE