diff options
author | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-06-15 12:35:14 +1000 |
---|---|---|
committer | Aaron Kennedy <aaron.kennedy@nokia.com> | 2011-06-15 12:35:14 +1000 |
commit | ee67e60cad8f9da67d8e8f11aeaf6efb11de89e9 (patch) | |
tree | df1a5c0dad7ef4ffbcfe4946c36811d148e635a1 /src | |
parent | cf9e9d07b980f6ba3c68cd1fd69adf1cfef59bdb (diff) | |
parent | 7b22f02961a97c0fa07127ea3ff26b8435a617b8 (diff) |
Merge branch 'qtquick2' of scm.dev.nokia.troll.no:qt/qtdeclarative-staging into v8
Diffstat (limited to 'src')
-rw-r--r-- | src/declarative/debugger/qjsdebuggeragent.cpp | 13 | ||||
-rw-r--r-- | src/declarative/debugger/qjsdebuggeragent_p.h | 2 | ||||
-rw-r--r-- | src/declarative/debugger/qjsdebugservice.cpp | 10 | ||||
-rw-r--r-- | src/declarative/debugger/qpacketprotocol.cpp | 2 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativetextinput.cpp | 54 | ||||
-rw-r--r-- | src/declarative/graphicsitems/qdeclarativetextinput_p.h | 5 | ||||
-rw-r--r-- | src/declarative/items/qsgcanvas.cpp | 74 | ||||
-rw-r--r-- | src/declarative/items/qsgcanvas.h | 3 | ||||
-rw-r--r-- | src/declarative/items/qsgcanvas_p.h | 2 | ||||
-rw-r--r-- | src/declarative/particles/qsgitemparticle.cpp | 78 | ||||
-rw-r--r-- | src/declarative/particles/qsgitemparticle_p.h | 23 | ||||
-rw-r--r-- | src/declarative/particles/qsgmodelparticle.cpp | 20 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticleemitter.cpp | 7 | ||||
-rw-r--r-- | src/declarative/particles/qsgparticleemitter_p.h | 1 |
14 files changed, 207 insertions, 87 deletions
diff --git a/src/declarative/debugger/qjsdebuggeragent.cpp b/src/declarative/debugger/qjsdebuggeragent.cpp index 9c92f27736..3169f91b59 100644 --- a/src/declarative/debugger/qjsdebuggeragent.cpp +++ b/src/declarative/debugger/qjsdebuggeragent.cpp @@ -56,7 +56,7 @@ class QJSDebuggerAgentPrivate { public: QJSDebuggerAgentPrivate(QJSDebuggerAgent *q) - : q(q), state(NoState) + : q(q), state(NoState), isInitialized(false) {} void continueExec(); @@ -79,6 +79,7 @@ public: QHash<QString, JSAgentBreakpointData> fileNameToBreakpoints; QStringList watchExpressions; QSet<qint64> knownObjectIds; + bool isInitialized; }; namespace { @@ -252,6 +253,14 @@ QJSDebuggerAgent::~QJSDebuggerAgent() delete d; } +/*! + Indicates whether the agent got the list of breakpoints. + */ +bool QJSDebuggerAgent::isInitialized() const +{ + return d->isInitialized; +} + void QJSDebuggerAgent::setBreakpoints(const JSAgentBreakpoints &breakpoints) { d->breakpoints = breakpoints; @@ -259,6 +268,8 @@ void QJSDebuggerAgent::setBreakpoints(const JSAgentBreakpoints &breakpoints) d->fileNameToBreakpoints.clear(); foreach (const JSAgentBreakpointData &bp, breakpoints) d->fileNameToBreakpoints.insertMulti(fileName(QString::fromUtf8(bp.fileUrl)), bp); + + d->isInitialized = true; } void QJSDebuggerAgent::setWatchExpressions(const QStringList &watchExpressions) diff --git a/src/declarative/debugger/qjsdebuggeragent_p.h b/src/declarative/debugger/qjsdebuggeragent_p.h index 5aa3c9ccbc..309588eb2f 100644 --- a/src/declarative/debugger/qjsdebuggeragent_p.h +++ b/src/declarative/debugger/qjsdebuggeragent_p.h @@ -145,6 +145,8 @@ public: QJSDebuggerAgent(QDeclarativeEngine *engine, QObject *parent = 0); ~QJSDebuggerAgent(); + bool isInitialized() const; + void setBreakpoints(const JSAgentBreakpoints &); void setWatchExpressions(const QStringList &); diff --git a/src/declarative/debugger/qjsdebugservice.cpp b/src/declarative/debugger/qjsdebugservice.cpp index 4ce2c906bc..ad84f656f7 100644 --- a/src/declarative/debugger/qjsdebugservice.cpp +++ b/src/declarative/debugger/qjsdebugservice.cpp @@ -71,6 +71,16 @@ void QJSDebugService::addEngine(QDeclarativeEngine *engine) Q_ASSERT(!m_engines.contains(engine)); m_engines.append(engine); + + if (status() == Enabled && !m_engines.isEmpty() && !m_agent) { + m_agent = new QJSDebuggerAgent(engine, engine); + connect(m_agent, SIGNAL(stopped(bool,QString)), + this, SLOT(executionStopped(bool,QString))); + + while (!m_agent->isInitialized()) { + waitForMessage(); + } + } } void QJSDebugService::removeEngine(QDeclarativeEngine *engine) diff --git a/src/declarative/debugger/qpacketprotocol.cpp b/src/declarative/debugger/qpacketprotocol.cpp index a40a9ab8a6..9caaa79011 100644 --- a/src/declarative/debugger/qpacketprotocol.cpp +++ b/src/declarative/debugger/qpacketprotocol.cpp @@ -198,6 +198,8 @@ public Q_SLOTS: packets.append(inProgress); inProgressSize = -1; inProgress.clear(); + + waitingForPacket = false; emit readyRead(); } else return; diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp index 98ec2050e9..b456d07c02 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp +++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp @@ -236,11 +236,11 @@ void QDeclarativeTextInput::setFont(const QFont &font) if (oldFont != d->font) { d->control->setFont(d->font); + updateSize(); + updateCursorRectangle(); if(d->cursorItem){ d->cursorItem->setHeight(QFontMetrics(d->font).height()); - moveCursor(); } - updateSize(); } emit fontChanged(d->sourceFont); } @@ -359,8 +359,7 @@ void QDeclarativeTextInput::setHAlign(HAlignment align) bool forceAlign = d->hAlignImplicit && d->effectiveLayoutMirror; d->hAlignImplicit = false; if (d->setHAlign(align, forceAlign) && isComponentComplete()) { - updateRect(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } } @@ -369,8 +368,7 @@ void QDeclarativeTextInput::resetHAlign() Q_D(QDeclarativeTextInput); d->hAlignImplicit = true; if (d->determineHorizontalAlignment() && isComponentComplete()) { - updateRect(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } } @@ -423,8 +421,7 @@ void QDeclarativeTextInputPrivate::mirrorChange() Q_Q(QDeclarativeTextInput); if (q->isComponentComplete()) { if (!hAlignImplicit && (hAlign == QDeclarativeTextInput::AlignRight || hAlign == QDeclarativeTextInput::AlignLeft)) { - q->updateRect(); - updateHorizontalScroll(); + q->updateCursorRectangle(); emit q->effectiveHorizontalAlignmentChanged(); } } @@ -683,7 +680,7 @@ void QDeclarativeTextInput::setAutoScroll(bool b) d->autoScroll = b; //We need to repaint so that the scrolling is taking into account. updateSize(true); - d->updateHorizontalScroll(); + updateCursorRectangle(); emit autoScrollChanged(d->autoScroll); } @@ -947,10 +944,6 @@ void QDeclarativeTextInput::setCursorDelegate(QDeclarativeComponent* c) d->cursorComponent = c; if(!c){ //note that the components are owned by something else - disconnect(d->control, SIGNAL(cursorPositionChanged(int,int)), - this, SLOT(moveCursor())); - disconnect(d->control, SIGNAL(updateMicroFocus()), - this, SLOT(moveCursor())); delete d->cursorItem; }else{ d->startCreatingCursor(); @@ -962,10 +955,6 @@ void QDeclarativeTextInput::setCursorDelegate(QDeclarativeComponent* c) void QDeclarativeTextInputPrivate::startCreatingCursor() { Q_Q(QDeclarativeTextInput); - q->connect(control, SIGNAL(cursorPositionChanged(int,int)), - q, SLOT(moveCursor()), Qt::UniqueConnection); - q->connect(control, SIGNAL(updateMicroFocus()), - q, SLOT(moveCursor()), Qt::UniqueConnection); if(cursorComponent->isReady()){ q->createCursor(); }else if(cursorComponent->isLoading()){ @@ -1001,15 +990,6 @@ void QDeclarativeTextInput::createCursor() d->cursorItem->setHeight(d->control->height()-1); // -1 to counter QLineControl's +1 which is not consistent with Text. } -void QDeclarativeTextInput::moveCursor() -{ - Q_D(QDeclarativeTextInput); - if(!d->cursorItem) - return; - d->updateHorizontalScroll(); - d->cursorItem->setX(d->control->cursorToX() - d->hscroll); -} - /*! \qmlmethod rect TextInput::positionToRectangle(int pos) @@ -1118,8 +1098,6 @@ void QDeclarativeTextInput::inputMethodEvent(QInputMethodEvent *ev) ev->ignore(); } else { d->control->processInputMethodEvent(ev); - updateSize(); - d->updateHorizontalScroll(); } } if (!ev->isAccepted()) @@ -1297,7 +1275,7 @@ void QDeclarativeTextInput::geometryChanged(const QRectF &newGeometry, Q_D(QDeclarativeTextInput); if (newGeometry.width() != oldGeometry.width()) { updateSize(); - d->updateHorizontalScroll(); + updateCursorRectangle(); } QDeclarativePaintedItem::geometryChanged(newGeometry, oldGeometry); } @@ -1643,7 +1621,6 @@ void QDeclarativeTextInput::moveCursorSelection(int position) { Q_D(QDeclarativeTextInput); d->control->moveCursor(position, true); - d->updateHorizontalScroll(); } /*! @@ -1901,7 +1878,7 @@ void QDeclarativeTextInputPrivate::init() canPaste = !control->isReadOnly() && QApplication::clipboard()->text().length() != 0; #endif // QT_NO_CLIPBOARD q->connect(control, SIGNAL(updateMicroFocus()), - q, SLOT(updateMicroFocus())); + q, SLOT(updateCursorRectangle())); q->connect(control, SIGNAL(displayTextChanged(QString)), q, SLOT(updateRect())); q->updateSize(); @@ -1917,9 +1894,7 @@ void QDeclarativeTextInputPrivate::init() void QDeclarativeTextInput::cursorPosChanged() { Q_D(QDeclarativeTextInput); - d->updateHorizontalScroll(); - updateRect();//TODO: Only update rect between pos's - updateMicroFocus(); + updateCursorRectangle(); emit cursorPositionChanged(); d->control->resetCursorBlinkTimer(); @@ -1935,6 +1910,17 @@ void QDeclarativeTextInput::cursorPosChanged() } } +void QDeclarativeTextInput::updateCursorRectangle() +{ + Q_D(QDeclarativeTextInput); + d->updateHorizontalScroll(); + updateRect();//TODO: Only update rect between pos's + updateMicroFocus(); + emit cursorRectangleChanged(); + if (d->cursorItem) + d->cursorItem->setX(d->control->cursorToX() - d->hscroll); +} + void QDeclarativeTextInput::selectionChanged() { Q_D(QDeclarativeTextInput); diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h index aaf8859150..8b7fff9cfb 100644 --- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h +++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h @@ -75,7 +75,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInput : public QDeclarativeImplicitSizeP Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly NOTIFY readOnlyChanged) Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible NOTIFY cursorVisibleChanged) Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged) - Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorPositionChanged) + Q_PROPERTY(QRect cursorRectangle READ cursorRectangle NOTIFY cursorRectangleChanged) Q_PROPERTY(QDeclarativeComponent *cursorDelegate READ cursorDelegate WRITE setCursorDelegate NOTIFY cursorDelegateChanged) Q_PROPERTY(int selectionStart READ selectionStart NOTIFY selectionStartChanged) Q_PROPERTY(int selectionEnd READ selectionEnd NOTIFY selectionEndChanged) @@ -221,6 +221,7 @@ public: Q_SIGNALS: void textChanged(); void cursorPositionChanged(); + void cursorRectangleChanged(); void selectionStartChanged(); void selectionEndChanged(); void selectedTextChanged(); @@ -279,8 +280,8 @@ private Q_SLOTS: void q_textChanged(); void selectionChanged(); void createCursor(); - void moveCursor(); void cursorPosChanged(); + void updateCursorRectangle(); void updateRect(const QRect &r = QRect()); void q_canPasteChanged(); diff --git a/src/declarative/items/qsgcanvas.cpp b/src/declarative/items/qsgcanvas.cpp index 3a88fbb790..fee58b87a8 100644 --- a/src/declarative/items/qsgcanvas.cpp +++ b/src/declarative/items/qsgcanvas.cpp @@ -174,7 +174,7 @@ void QSGCanvas::paintEvent(QPaintEvent *) int lastFrame = frameTimer.restart(); #endif - if (d->animationDriver->isRunning()) + if (d->animationDriver && d->animationDriver->isRunning()) d->animationDriver->advance(); #ifdef FRAME_TIMING @@ -222,10 +222,10 @@ void QSGCanvas::paintEvent(QPaintEvent *) QDeclarativeDebugTrace::endRange(QDeclarativeDebugTrace::Painting); - if (d->animationDriver->isRunning()) + if (d->animationDriver && d->animationDriver->isRunning()) update(); } else { - if (isUpdatesEnabled()) { + if (updatesEnabled()) { d->thread->paint(); setUpdatesEnabled(false); } @@ -252,12 +252,14 @@ void QSGCanvas::showEvent(QShowEvent *e) if (!d->contextFailed) { if (d->threadedRendering) { - if (!d->animationDriver) { - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), d->thread, SLOT(animationStarted()), Qt::DirectConnection); - connect(d->animationDriver, SIGNAL(stopped()), d->thread, SLOT(animationStopped()), Qt::DirectConnection); + if (d->vsyncAnimations) { + if (!d->animationDriver) { + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), d->thread, SLOT(animationStarted()), Qt::DirectConnection); + connect(d->animationDriver, SIGNAL(stopped()), d->thread, SLOT(animationStopped()), Qt::DirectConnection); + } + d->animationDriver->install(); } - d->animationDriver->install(); d->thread->startRenderThread(); setUpdatesEnabled(true); } else { @@ -265,11 +267,14 @@ void QSGCanvas::showEvent(QShowEvent *e) if (!d->context || !d->context->isReady()) { d->initializeSceneGraph(); - d->animationDriver = d->context->createAnimationDriver(this); - connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); + if (d->vsyncAnimations) { + d->animationDriver = d->context->createAnimationDriver(this); + connect(d->animationDriver, SIGNAL(started()), this, SLOT(update())); + } } - d->animationDriver->install(); + if (d->animationDriver) + d->animationDriver->install(); } } } @@ -283,12 +288,52 @@ void QSGCanvas::hideEvent(QHideEvent *e) d->thread->stopRenderThread(); } - d->animationDriver->uninstall(); + if (d->animationDriver) + d->animationDriver->uninstall(); } QGLWidget::hideEvent(e); } + + +/*! + Sets weither this canvas should use vsync driven animations. + + This option can only be set on one single QSGCanvas, and that it's + vsync signal will then be used to drive all animations in the + process. + + This feature is primarily useful for single QSGCanvas, QML-only + applications. + + \warning Enabling vsync on multiple QSGCanvas instances has + undefined behavior. + */ +void QSGCanvas::setVSyncAnimations(bool enabled) +{ + Q_D(QSGCanvas); + if (isVisible()) { + qWarning("QSGCanvas::setVSyncAnimations: Cannot be changed when widget is shown"); + return; + } + d->vsyncAnimations = enabled; +} + + + +/*! + Returns true if this canvas should use vsync driven animations; + otherwise returns false. + */ +bool QSGCanvas::vsyncAnimations() const +{ + Q_D(const QSGCanvas); + return d->vsyncAnimations; +} + + + void QSGCanvas::focusOutEvent(QFocusEvent *event) { Q_D(QSGCanvas); @@ -384,6 +429,7 @@ QSGCanvasPrivate::QSGCanvasPrivate() , threadedRendering(false) , animationRunning(false) , renderThreadAwakened(false) + , vsyncAnimations(false) , thread(0) , animationDriver(0) { @@ -958,7 +1004,7 @@ bool QSGCanvas::event(QEvent *e) d->thread->syncAlreadyHappened = false; - if (d->animationRunning) { + if (d->animationRunning && d->animationDriver) { #ifdef THREAD_DEBUG qDebug("GUI: Advancing animations...\n"); #endif @@ -2053,7 +2099,7 @@ void QSGCanvasRenderThread::run() // but we don't want to lock an extra time. wake(); - if (!d->animationRunning && !isExternalUpdatePending) { + if (!d->animationRunning && !isExternalUpdatePending && !shouldExit) { #ifdef THREAD_DEBUG printf(" RenderThread: nothing to do, going to sleep...\n"); #endif diff --git a/src/declarative/items/qsgcanvas.h b/src/declarative/items/qsgcanvas.h index d0d0c79d5e..8913e41b86 100644 --- a/src/declarative/items/qsgcanvas.h +++ b/src/declarative/items/qsgcanvas.h @@ -75,6 +75,9 @@ public: QSGEngine *sceneGraphEngine() const; + void setVSyncAnimations(bool enabled); + bool vsyncAnimations() const; + QImage grabFrameBuffer(); Q_SIGNALS: diff --git a/src/declarative/items/qsgcanvas_p.h b/src/declarative/items/qsgcanvas_p.h index 9b2683cc38..7f7182ee52 100644 --- a/src/declarative/items/qsgcanvas_p.h +++ b/src/declarative/items/qsgcanvas_p.h @@ -160,6 +160,8 @@ public: uint animationRunning: 1; uint renderThreadAwakened : 1; + uint vsyncAnimations : 1; + QSGCanvasRenderThread *thread; QSize widgetSize; QSize viewportSize; diff --git a/src/declarative/particles/qsgitemparticle.cpp b/src/declarative/particles/qsgitemparticle.cpp index 819c823155..42f0062148 100644 --- a/src/declarative/particles/qsgitemparticle.cpp +++ b/src/declarative/particles/qsgitemparticle.cpp @@ -42,14 +42,22 @@ #include "qsgitemparticle_p.h" #include <QtDeclarative/private/qsgvisualitemmodel_p.h> #include <qsgnode.h> +#include <QTimer> +#include <QDeclarativeComponent> #include <QDebug> QT_BEGIN_NAMESPACE QSGItemParticle::QSGItemParticle(QSGItem *parent) : - QSGParticlePainter(parent), m_fade(true) + QSGParticlePainter(parent), m_fade(true), m_delegate(0) { setFlag(QSGItem::ItemHasContents); + QTimer* manageDelegates = new QTimer(this);//TODO: don't leak + connect(manageDelegates, SIGNAL(timeout()), + this, SLOT(tick())); + manageDelegates->setInterval(16); + manageDelegates->setSingleShot(false); + manageDelegates->start(); } @@ -79,33 +87,54 @@ void QSGItemParticle::give(QSGItem *item) void QSGItemParticle::load(QSGParticleData* d) { - if(m_pendingItems.isEmpty()) - return; int pos = particleTypeIndex(d); - if(m_items[pos]){ - if(m_stasis.contains(m_items[pos])) - qWarning() << "Current model particles prefers overwrite:false"; - //remove old item from the particle that is dying to make room for this one - m_items[pos]->setOpacity(0.); + m_data[pos] = d; + m_loadables << pos; +} + +void QSGItemParticle::tick() +{ + foreach(QSGItem* item, m_deletables){ + if(m_fade) + item->setOpacity(0.); QSGItemParticleAttached* mpa; - if((mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[pos], false)))) + if((mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(item)))) mpa->detach();//reparent as well? - m_items[pos] = 0; - m_data[pos] = 0; + //TODO: Delete iff we created it m_activeCount--; } - m_items[pos] = m_pendingItems.front(); - m_pendingItems.pop_front(); - m_items[pos]->setX(d->curX() - m_items[pos]->width()/2); - m_items[pos]->setY(d->curY() - m_items[pos]->height()/2); - QSGItemParticleAttached* mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[pos])); - if(mpa){ - mpa->m_mp = this; - mpa->attach(); + m_deletables.clear(); + + foreach(int pos, m_loadables){ + if(m_stasis.contains(m_items[pos])) + qWarning() << "Current model particles prefers overwrite:false"; + //remove old item from the particle that is dying to make room for this one + if(m_items[pos]){ + m_deletables << m_items[pos]; + m_activeCount--; + } + m_items[pos] = 0; + if(!m_pendingItems.isEmpty()){ + m_items[pos] = m_pendingItems.front(); + m_pendingItems.pop_front(); + }else if(m_delegate){ + m_items[pos] = qobject_cast<QSGItem*>(m_delegate->create(qmlContext(this))); + } + if(m_items[pos]){ + m_items[pos]->setX(m_data[pos]->curX() - m_items[pos]->width()/2);//TODO: adjust for system? + m_items[pos]->setY(m_data[pos]->curY() - m_items[pos]->height()/2); + QSGItemParticleAttached* mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[pos])); + if(mpa){ + mpa->m_mp = this; + mpa->attach(); + } + m_items[pos]->setParentItem(this); + if(m_fade) + m_items[pos]->setOpacity(0.); + m_activeCount++; + } } - m_items[pos]->setParentItem(this); - m_data[pos] = d; - m_activeCount++; + m_loadables.clear(); } void QSGItemParticle::reload(QSGParticleData* d) @@ -173,10 +202,7 @@ void QSGItemParticle::prepareNextFrame() continue; } if(t >= 1.0){//Usually happens from load - item->setOpacity(0.); - QSGItemParticleAttached* mpa; - if((mpa = qobject_cast<QSGItemParticleAttached*>(qmlAttachedPropertiesObject<QSGItemParticle>(m_items[i])))) - mpa->detach();//reparent as well? + m_deletables << item; m_items[i] = 0; m_data[i] = 0; m_activeCount--; diff --git a/src/declarative/particles/qsgitemparticle_p.h b/src/declarative/particles/qsgitemparticle_p.h index fa3516b631..3b7db519de 100644 --- a/src/declarative/particles/qsgitemparticle_p.h +++ b/src/declarative/particles/qsgitemparticle_p.h @@ -55,8 +55,8 @@ class QSGItemParticleAttached; class QSGItemParticle : public QSGParticlePainter { Q_OBJECT - Q_PROPERTY(bool fade READ fade WRITE setFade NOTIFY fadeChanged) + Q_PROPERTY(QDeclarativeComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged) public: explicit QSGItemParticle(QSGItem *parent = 0); @@ -69,9 +69,16 @@ public: virtual int count(); static QSGItemParticleAttached *qmlAttachedProperties(QObject *object); + QDeclarativeComponent* delegate() const + { + return m_delegate; + } + signals: void fadeChanged(); + void delegateChanged(QDeclarativeComponent* arg); + public slots: //TODO: Add a follow mode, where moving the delegate causes the logical particle to go with it? void freeze(QSGItem* item); @@ -80,11 +87,22 @@ public slots: void give(QSGItem* item);//give from modelparticle void setFade(bool arg){if(arg == m_fade) return; m_fade = arg; emit fadeChanged();} + void setDelegate(QDeclarativeComponent* arg) + { + if (m_delegate != arg) { + m_delegate = arg; + emit delegateChanged(arg); + } + } + protected: virtual void reset(); void prepareNextFrame(); +private slots: + void tick(); private: - QList<QPointer<QSGItem> > m_deletables; + QList<QSGItem* > m_deletables; + QList< int > m_loadables; int m_particleCount; bool m_fade; @@ -96,6 +114,7 @@ private: QSet<QSGItem*> m_stasis; qreal m_lastT; int m_activeCount; + QDeclarativeComponent* m_delegate; }; class QSGItemParticleAttached : public QObject diff --git a/src/declarative/particles/qsgmodelparticle.cpp b/src/declarative/particles/qsgmodelparticle.cpp index 704b9a298c..f87c0d31b9 100644 --- a/src/declarative/particles/qsgmodelparticle.cpp +++ b/src/declarative/particles/qsgmodelparticle.cpp @@ -178,18 +178,22 @@ void QSGModelParticle::processPending() item->setOpacity(0.); m_model->release(item); } + m_deletables.clear(); foreach(int pos, m_requests){ - m_items[pos] = m_model->item(m_available.first()); - m_idx[pos] = m_available.first(); - m_available.pop_front(); - QSGModelParticleAttached* mpa = qobject_cast<QSGModelParticleAttached*>(qmlAttachedPropertiesObject<QSGModelParticle>(m_items[pos])); - if(mpa){ - mpa->m_mp = this; - mpa->attach(); + if(!m_available.isEmpty()){ + m_items[pos] = m_model->item(m_available.first()); + m_idx[pos] = m_available.first(); + m_available.pop_front(); + QSGModelParticleAttached* mpa = qobject_cast<QSGModelParticleAttached*>(qmlAttachedPropertiesObject<QSGModelParticle>(m_items[pos])); + if(mpa){ + mpa->m_mp = this; + mpa->attach(); + } + m_items[pos]->setParentItem(this); } - m_items[pos]->setParentItem(this); } + m_requests.clear(); } void QSGModelParticle::reload(QSGParticleData* d) diff --git a/src/declarative/particles/qsgparticleemitter.cpp b/src/declarative/particles/qsgparticleemitter.cpp index 20f3c6bb4b..143338f798 100644 --- a/src/declarative/particles/qsgparticleemitter.cpp +++ b/src/declarative/particles/qsgparticleemitter.cpp @@ -121,6 +121,13 @@ void QSGParticleEmitter::burst(int num) m_burstQueue << qMakePair(num, QPointF(x(), y())); } +void QSGParticleEmitter::burst(int num, qreal x, qreal y) +{ + if(!particleCount()) + qWarning() << "burst called on an emitter with a particle count of zero"; + m_burstQueue << qMakePair(num, QPointF(x, y)); +} + void QSGParticleEmitter::setMaxParticleCount(int arg) { if (m_maxParticleCount != arg) { diff --git a/src/declarative/particles/qsgparticleemitter_p.h b/src/declarative/particles/qsgparticleemitter_p.h index 9fafd9d43d..65aca0c83e 100644 --- a/src/declarative/particles/qsgparticleemitter_p.h +++ b/src/declarative/particles/qsgparticleemitter_p.h @@ -142,6 +142,7 @@ signals: public slots: void pulse(qreal seconds); void burst(int num); + void burst(int num, qreal x, qreal y); void setEmitting(bool arg); |