/**************************************************************************** ** ** Copyright (C) 2018 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** ** This file is part of Qt 3D Studio. ** ** $QT_BEGIN_LICENSE:GPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 3 or (at your option) any later version ** approved by the KDE Free Qt Foundation. The licenses are as published by ** the Free Software Foundation and appearing in the file LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #ifndef Q3DSABSTRACTSLIDEPLAYER_P_H #define Q3DSABSTRACTSLIDEPLAYER_P_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include "q3dsuippresentation_p.h" QT_BEGIN_NAMESPACE class Q3DSSlideDeck; namespace Q3DSSlideUtils { Q3DSV_PRIVATE_EXPORT bool useDragonWings(); Q3DSV_PRIVATE_EXPORT void getStartAndEndTime(Q3DSSlide *slide, qint32 *start, qint32 *end); }; class Q3DSV_PRIVATE_EXPORT Q3DSAbstractSlidePlayer : public QObject { Q_OBJECT Q_PROPERTY(Q3DSSlideDeck *slideDeck READ slideDeck WRITE setSlideDeck NOTIFY slideDeckChanged) Q_PROPERTY(float duration READ duration NOTIFY durationChanged) Q_PROPERTY(float position READ position NOTIFY positionChanged) public: Q3DSAbstractSlidePlayer(QObject *parent = nullptr) : QObject(parent) {} enum class PlayerState { Idle, Ready, Stopped, Playing, Paused }; Q_ENUM(PlayerState) enum class PlayerMode { Viewer, Editor }; Q_ENUM(PlayerMode) enum class PlayerType { Scene, Component }; Q_ENUM(PlayerType) virtual Q3DSSlideDeck *slideDeck() const = 0; virtual void advanceFrame(float dt) = 0; virtual void sceneReady() = 0; virtual float duration() const = 0; virtual float position() const = 0; virtual PlayerState state() const = 0; virtual void setMode(PlayerMode mode) = 0; virtual PlayerMode mode() const = 0; virtual void objectAboutToBeAddedToScene(Q3DSGraphObject *obj) = 0; virtual void objectAboutToBeRemovedFromScene(Q3DSGraphObject *obj) = 0; virtual void objectAddedToSlide(Q3DSGraphObject *obj, Q3DSSlide *slide) = 0; virtual void objectRemovedFromSlide(Q3DSGraphObject *obj, Q3DSSlide *slide) = 0; virtual float playbackRate() const = 0; public Q_SLOTS: virtual void play() = 0; virtual void stop() = 0; virtual void pause() = 0; virtual void seek(float) = 0; virtual void setSlideDeck(Q3DSSlideDeck *slideDeck) = 0; virtual void setPlaybackRate(float rate) = 0; virtual void nextSlide() = 0; virtual void previousSlide() = 0; virtual void precedingSlide() = 0; virtual void reload() = 0; Q_SIGNALS: void slideDeckChanged(Q3DSSlideDeck *slideDeck); void durationChanged(float duration); void positionChanged(float position); void stateChanged(PlayerState state); void slideChanged(Q3DSSlide *); }; class Q3DSV_PRIVATE_EXPORT Q3DSSlideDeck { public: Q3DSSlideDeck(Q3DSSlide *masterSlide, Q3DSSlide *parent = nullptr) : m_masterSlide(masterSlide) , m_parent(parent) { Q_ASSERT(masterSlide); Q_ASSERT_X(!masterSlide->parent(), Q_FUNC_INFO, "Slide is not a master slide!"); if (!masterSlide->firstChild()) { qWarning("No slides?"); return; } m_index = 0; } int slideCount() const { return m_masterSlide->childCount(); } bool isEmpty() const { return (slideCount() == 0); } Q3DSSlide *currentSlide() const { if (!m_masterSlide) return nullptr; if (isEmpty()) return nullptr; Q_ASSERT(m_index < slideCount()); return static_cast(m_masterSlide->childAtIndex(m_index)); } Q3DSSlide *previousSlide() const { if (!m_masterSlide) return nullptr; if (isEmpty()) return nullptr; if (m_previouslyActiveIndex < 0) return nullptr; Q_ASSERT(m_previouslyActiveIndex < slideCount()); return static_cast(m_masterSlide->childAtIndex(m_previouslyActiveIndex)); } Q3DSSlide *slideAtIndex(int index) const { const int count = slideCount(); if (index < 0 || index > count - 1) return nullptr; return static_cast(m_masterSlide->childAtIndex(index)); } void setCurrentSlide(int index) { Q_ASSERT(m_masterSlide); const int count = m_masterSlide->childCount(); if ((index < 0) || (index > count - 1)) { qWarning("Invalid index!"); return; } if (index == m_index) return; if (count < 1) return; if (m_player) m_player->pause(); m_previouslyActiveIndex = m_index; m_index = index; if (m_player) m_player->reload(); } Q3DSSlide *setCurrentIndex(int index) { Q_ASSERT(m_masterSlide); const int count = m_masterSlide->childCount(); if ((index < 0) || (index > count - 1)) { qWarning("Invalid index!"); return nullptr; } if (index != m_index) { m_previouslyActiveIndex = m_index; m_index = index; } return static_cast(m_masterSlide->childAtIndex(m_index)); } Q3DSSlide *goToNextSlide(bool wrap = false) { if (!m_masterSlide) return nullptr; if (isEmpty() || m_index == -1) return nullptr; if (m_index < slideCount() - 1) { m_previouslyActiveIndex = m_index; return static_cast(m_masterSlide->childAtIndex(++m_index)); } else if (wrap && m_index == slideCount() - 1) { m_previouslyActiveIndex = m_index; m_index = 0; return static_cast(m_masterSlide->childAtIndex(m_index)); } else { return nullptr; } } Q3DSSlide *gotToPreviousSlide(bool wrap = false) { if (!m_masterSlide) return nullptr; if (isEmpty() || m_index == -1) return nullptr; if ((m_index > 0) && (m_index < slideCount())) { m_previouslyActiveIndex = m_index; return static_cast(m_masterSlide->childAtIndex(--m_index)); } else if (wrap && m_index == 0) { m_previouslyActiveIndex = m_index; m_index = slideCount() - 1; return static_cast(m_masterSlide->childAtIndex(m_index)); } else { return nullptr; } } Q3DSSlide *precedingSlide() { // This is effectively a go-back-in-history with a 1 level history, // i.e. go to the slide that was current before the current one - but // going "back" from there would bring us back to what is current now. if (m_previouslyActiveIndex == -1) return nullptr; return setCurrentIndex(m_previouslyActiveIndex); } int indexOfSlide(Q3DSSlide *slide) { Q_ASSERT(m_masterSlide); Q3DSSlide *ns = static_cast(m_masterSlide->firstChild()); int index = 0; bool found = false; while (ns) { if (ns == slide) { found = true; break; } ns = static_cast(ns->nextSibling()); ++index; } return found ? index : -1; } int indexOfSlide(const QByteArray &slideId) { Q_ASSERT(m_masterSlide); Q3DSSlide *ns = static_cast(m_masterSlide->firstChild()); int index = 0; bool found = false; while (ns) { if (ns->id() == slideId) { found = true; break; } ns = static_cast(ns->nextSibling()); ++index; } return found ? index : -1; } Q3DSSlide *parentSlide() const { return m_parent; } Q3DSSlide *masterSlide() const { return m_masterSlide; } void bind(Q3DSAbstractSlidePlayer *player) { if (player == m_player) return; if (m_player) m_player->setSlideDeck(nullptr); m_player = player; } private: Q3DSAbstractSlidePlayer *m_player = nullptr; Q3DSSlide *m_masterSlide = nullptr; Q3DSSlide *m_parent = nullptr; int m_index = -1; int m_previouslyActiveIndex = -1; }; QT_END_NAMESPACE #endif // Q3DSABSTRACTSLIDEPLAYER_P_H