channelprogrammeditor.h 6.04 KB
Newer Older
Leander Schulten's avatar
Leander Schulten committed
1
2
3
4
#ifndef CHANNELPROGRAMMEDITOR_H
#define CHANNELPROGRAMMEDITOR_H

#include <QFlags>
5
#include <QQuickItem>
6
#include <dmx/programmprototype.h>
Leander Schulten's avatar
Leander Schulten committed
7

8
namespace GUI {
9

Leander Schulten's avatar
Leander Schulten committed
10
11
class ChannelProgrammEditor;

12
class CurrentTimePointWrapper : public QObject {
Leander Schulten's avatar
Leander Schulten committed
13
14
15
16
    Q_OBJECT
    Q_PROPERTY(unsigned char value READ getValue WRITE setValue NOTIFY valueChanged)
    Q_PROPERTY(bool hasCurrent READ hasCurrent NOTIFY hasCurrentChanged)
    Q_PROPERTY(double time READ getTime WRITE setTime NOTIFY timeChanged)
17
18
    ChannelProgrammEditor *editor;

Leander Schulten's avatar
Leander Schulten committed
19
public:
20
    CurrentTimePointWrapper(ChannelProgrammEditor *editor);
Leander Schulten's avatar
Leander Schulten committed
21
    void setValue(unsigned char value);
22
    unsigned char getValue() const;
Leander Schulten's avatar
Leander Schulten committed
23
24
    bool hasCurrent();
    void setTime(double time);
25
    double getTime() const;
Leander Schulten's avatar
Leander Schulten committed
26
27
28
29
30
31
signals:
    void valueChanged();
    void hasCurrentChanged();
    void timeChanged();
};

32
class ChannelProgrammEditor : public QQuickItem {
Leander Schulten's avatar
Leander Schulten committed
33
    Q_OBJECT
34
    Q_PROPERTY(CurrentTimePointWrapper *currentTimePoint READ getCurrentTimePointWrapper CONSTANT)
Leander Schulten's avatar
Leander Schulten committed
35
36
    Q_PROPERTY(int clickRadius MEMBER clickRadius NOTIFY clickRadiusChanged)
    Q_PROPERTY(QColor graphColor MEMBER graphColor NOTIFY graphColorChanged)
37
38
39
40
41
42
43
    Q_PROPERTY(DMX::ChannelProgramm *channelProgramm READ getChannelProgramm WRITE setChannelProgramm NOTIFY channelProgrammChanged)
    Q_PROPERTY(double hoverSegmentX READ getHoverSegmentX NOTIFY hoverSegmentXChanged)
    Q_PROPERTY(double hoverSegmentLength READ getHoverSegmentLength NOTIFY hoverSegmentLengthChanged)
    Q_PROPERTY(double selectedSegmentX READ getSelectedSegmentX NOTIFY selectedSegmentXChanged)
    Q_PROPERTY(double selectedSegmentLength READ getSelectedSegmentLength NOTIFY selectedSegmentLengthChanged)
    Q_PROPERTY(QEasingCurve::Type selectedEasingCurve READ getSelectedEasingCurve WRITE setSelectedEasingCurve NOTIFY selectedEasingCurveChanged)
    Q_PROPERTY(double mouseX READ getMouseX NOTIFY mouseXChanged)
Leander Schulten's avatar
Leander Schulten committed
44
private:
45
    friend class CurrentTimePointWrapper;
Leander Schulten's avatar
Leander Schulten committed
46
    CurrentTimePointWrapper currentTimePointWrapper;
47
    DMX::ChannelProgramm *channelProgramm = nullptr;
48
    decltype(DMX::ChannelProgramm::timeline)::iterator currentTimePoint;
49
50
51
    decltype(DMX::ChannelProgramm::timeline)::iterator currentSegment;
    int clickRadius = 4;
    double xScale = 50.;
52
    double totalXOffset = 0;
53
54
    QColor graphColor = QColor(0, 0, 0);
    enum Modifier { X_PRESSED = 0x1, Y_PRESSED = 0x2, N_PRESSED = 0x4, D_PRESSED = 0x20 };
Leander Schulten's avatar
Leander Schulten committed
55
    QFlags<Modifier> modifier;
56
57
58
59
60
61
62
63
64
65

    double hoverSegmentX = 0;
    double hoverSegmentLength = 0;
    void updateHoverSegment();
    double selectedSegmentX = 0;
    double selectedSegmentLength = 0;
    void updateSelectedSegment();

    static constexpr auto INVALID_POS = QPointF(std::numeric_limits<qreal>::lowest(), std::numeric_limits<qreal>::lowest());
    QPointF lastMousePosition = INVALID_POS;
Leander Schulten's avatar
Leander Schulten committed
66
    ulong mousePressTimestamp;
67
    decltype(DMX::ChannelProgramm::timeline)::iterator getTimePointForPosition(int x, int y);
68
69
70
71
72
73
74
75
76
    /**
     * @brief mapToVisualX maps from values/mouse Position to the visual Position of the graph
     * eg: mouse/value = 100
     * xScale = 2
     * totalXOffset = 100
     * result = x*xScale+totalXOffset = 300
     * @param x the x coordinate
     * @return x * xScale + totalXOffset
     */
77
    double mapToVisualX(double x) const { return x * xScale + totalXOffset; }
78
79
80
81
82
83
84
85
86
    /**
     * @brief mapFromVisualX maps from the visual Position of the graph to real values
     * @param xthe x coordinate
     * eg: visual value = 300
     * xScale = 2
     * totalXOffset = 100
     * result = (x-totalXOffset)*(1/xScale) = 100
     * @return
     */
87
88
89
    double mapFromVisualX(double x) const { return (x - totalXOffset) * (1 / xScale); }
    int getScaledY(int y) const { return 255 - int(y / height() * 255); }

Leander Schulten's avatar
Leander Schulten committed
90
91
public:
    ChannelProgrammEditor();
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
    void setChannelProgramm(DMX::ChannelProgramm *p);
    DMX::ChannelProgramm *getChannelProgramm() const { return channelProgramm; }
    bool haveCurrentTimePoint() const { return channelProgramm ? (currentTimePoint != channelProgramm->timeline.cend()) : false; }
    DMX::TimePoint *getCurrentTimePoint();
    CurrentTimePointWrapper *getCurrentTimePointWrapper() { return &currentTimePointWrapper; }
    Q_INVOKABLE QEasingCurve *getCurveForPoint(int x);
    double getHoverSegmentX() const { return hoverSegmentX; }
    double getHoverSegmentLength() const { return hoverSegmentLength; }
    double getSelectedSegmentX() const { return selectedSegmentX; }
    double getSelectedSegmentLength() const { return selectedSegmentLength; }
    QEasingCurve::Type getSelectedEasingCurve() const { return channelProgramm && currentSegment != channelProgramm->timeline.end() ? currentSegment->easingCurveToNextPoint.type() : static_cast<QEasingCurve::Type>(-1); }
    void setSelectedEasingCurve(QEasingCurve::Type type);
    double getMouseX() const { return lastMousePosition.x(); }
    Q_INVOKABLE double getTimeForVisualX(double x) const { return mapFromVisualX(x); }
    Q_INVOKABLE int getValueForVisualX(double x) const { return channelProgramm ? channelProgramm->getValueForTime(std::max(0., mapFromVisualX(x))) : -1; }

Leander Schulten's avatar
Leander Schulten committed
108
protected:
109
110
111
112
113
114
115
116
117
118
    virtual QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override;
    virtual void mouseMoveEvent(QMouseEvent *event) override;
    virtual void mousePressEvent(QMouseEvent *event) override;
    virtual void mouseReleaseEvent(QMouseEvent *event) override;
    virtual void hoverEnterEvent(QHoverEvent *e) override;
    virtual void hoverMoveEvent(QHoverEvent *e) override;
    virtual void hoverLeaveEvent(QHoverEvent *e) override;
    virtual void keyPressEvent(QKeyEvent *event) override;
    virtual void keyReleaseEvent(QKeyEvent *event) override;
    virtual void wheelEvent(QWheelEvent *event) override;
Leander Schulten's avatar
Leander Schulten committed
119
120
121
122
signals:
    void clickRadiusChanged();
    void graphColorChanged();
    void channelProgrammChanged();
Leander Schulten's avatar
Leander Schulten committed
123
124
    void click(int x, int y);
    void rightClick(int x, int y);
125
126
127
128
129
130
    void hoverSegmentXChanged();
    void hoverSegmentLengthChanged();
    void selectedSegmentXChanged();
    void selectedSegmentLengthChanged();
    void selectedEasingCurveChanged();
    void mouseXChanged();
Leander Schulten's avatar
Leander Schulten committed
131
132
};

133
134
} // namespace GUI

Leander Schulten's avatar
Leander Schulten committed
135
#endif // CHANNELPROGRAMMEDITOR_H