Skip to content

File DataTransition.hpp

File List > QAccelPlot > src > QAccelPlot > transitions > DataTransition.hpp

Go to the documentation of this file

//
// SPDX-FileCopyrightText: 2026 Michal Grabarczyk
// SPDX-License-Identifier: GPL-3.0-only WITH Universal-FOSS-exception-1.0
//
// This file is also available under a separate commercial license.
// See COMMERCIAL-LICENSING.md for contact information.
//
#pragma once

#include <QEasingCurve>
#include <QList>
#include <QObject>
#include <QtQml/qqmlregistration.h>

#include <vector>

QT_FORWARD_DECLARE_CLASS(QAbstractAnimation)

namespace QAccelPlot {

class DataTransition : public QObject {
    Q_OBJECT
    QML_ANONYMOUS

    Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
    Q_PROPERTY(QEasingCurve easing READ easing WRITE setEasing NOTIFY easingChanged)
    Q_PROPERTY(bool enabled READ enabled WRITE setEnabled NOTIFY enabledChanged)
    Q_PROPERTY(bool running READ running NOTIFY runningChanged)

public:
    struct Dataset {
        std::vector<double> values;
        int count{0};
        int stride{2};
    };

    class Run {
    public:
        Run() = default;
        ~Run();

        Run(const Run&) = delete;
        Run& operator=(const Run&) = delete;

        bool active() const;
        bool pending() const;
        const std::vector<double>& targetData() const;
        int targetPointCount() const;

        bool finish(std::vector<double>& outData, int& outPointCount);
        void cancel();

    private:
        friend class DataTransition;

        void detach();

        DataTransition* transition_{nullptr};
        bool pending_{false};
        Dataset from_;
        Dataset to_;
        int startTime_{0};
    };

    explicit DataTransition(QObject* parent = nullptr);
    ~DataTransition() override;

    int duration() const;
    void setDuration(int duration);

    QEasingCurve easing() const;
    void setEasing(const QEasingCurve& easing);

    bool enabled() const;
    void setEnabled(bool enabled);

    bool running() const;

    void start(Run& run, const std::vector<double>& currentData, int currentPointCount, std::vector<double>&& newData, int newPointCount, int stride = 2);

    void cancel();

    bool advance(Run& run, std::vector<double>& outData, int& outPointCount);

signals:
    void durationChanged();
    void easingChanged();
    void enabledChanged();
    void runningChanged();

protected:
    virtual void interpolate(double easedProgress, const Dataset& from, const Dataset& to, Dataset& out) = 0;

private:
    void removeRun(Run* run);
    void setRunning(bool running);

    int duration_{300};
    QEasingCurve easing_{QEasingCurve(QEasingCurve::Linear)};
    bool enabled_{true};
    bool running_{false};
    QList<Run*> runs_;
    QAbstractAnimation* clock_;
};

} // namespace QAccelPlot