]> git.sesse.net Git - nageru/blob - clip_list.h
Serialize state to disk between runs, using SQLite.
[nageru] / clip_list.h
1 #ifndef _CLIP_LIST_H
2 #define _CLIP_LIST_H 1
3
4 #include <QAbstractTableModel>
5
6 #include <stdint.h>
7
8 #include <vector>
9 #include <string>
10
11 #include "defs.h"
12 #include "state.pb.h"
13
14 struct Clip {
15         int64_t pts_in = -1, pts_out = -1;  // pts_in is inclusive, pts_out is exclusive.
16         std::string descriptions[NUM_CAMERAS];
17         unsigned stream_idx = 0;  // For the playlist only.
18 };
19
20 class DataChangedReceiver {
21 public:
22         virtual void emit_data_changed(size_t row) = 0;
23 };
24
25 // Like a smart pointer to a Clip, but emits dataChanged when it goes out of scope.
26 struct ClipProxy {
27 public:
28         ClipProxy(Clip &clip, DataChangedReceiver *clip_list, size_t row)
29                 : clip(clip), clip_list(clip_list), row(row) {}
30         ~ClipProxy() {
31                 if (clip_list != nullptr) {
32                         clip_list->emit_data_changed(row);
33                 }
34         }
35         Clip *operator->() { return &clip; }
36         Clip &operator*() { return clip; }
37
38 private:
39         Clip &clip;
40         DataChangedReceiver *clip_list;
41         size_t row;
42 };
43
44 class ClipList : public QAbstractTableModel, public DataChangedReceiver {
45         Q_OBJECT
46
47 public:
48         explicit ClipList(const ClipListProto &serialized);
49
50         enum class Column {
51                 IN,
52                 OUT,
53                 DURATION,
54                 CAMERA_1,
55                 CAMERA_2,
56                 CAMERA_3,
57                 CAMERA_4,
58                 NUM_COLUMNS
59         };
60
61         int rowCount(const QModelIndex &parent) const override;
62         int columnCount(const QModelIndex &parent) const override;
63         QVariant data(const QModelIndex &parent, int role) const override;
64         QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
65         Qt::ItemFlags flags(const QModelIndex &index) const override;
66         bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
67
68         void add_clip(const Clip &clip);
69         size_t size() const { return clips.size(); }
70         bool empty() const { return clips.empty(); }
71
72         ClipProxy mutable_clip(size_t index) { return ClipProxy(clips[index], this, index); }
73         const Clip *clip(size_t index) const { return &clips[index]; }
74
75         ClipProxy mutable_back() { return mutable_clip(size() - 1); }
76         const Clip *back() const { return clip(size() - 1); }
77
78         ClipListProto serialize() const;
79
80         void emit_data_changed(size_t row) override;
81
82 signals:
83         void any_content_changed();
84
85 private:
86         std::vector<Clip> clips;
87 };
88
89 class PlayList : public QAbstractTableModel, public DataChangedReceiver {
90         Q_OBJECT
91
92 public:
93         explicit PlayList(const ClipListProto &serialized);
94
95         enum class Column {
96                 PLAYING,
97                 IN,
98                 OUT,
99                 DURATION,
100                 CAMERA,
101                 DESCRIPTION,
102                 NUM_COLUMNS
103         };
104
105         int rowCount(const QModelIndex &parent) const override;
106         int columnCount(const QModelIndex &parent) const override;
107         QVariant data(const QModelIndex &parent, int role) const override;
108         QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
109         Qt::ItemFlags flags(const QModelIndex &index) const override;
110         bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
111
112         void add_clip(const Clip &clip);
113
114         // <last> is inclusive in all of these.
115         void duplicate_clips(size_t first, size_t last);
116         void erase_clips(size_t first, size_t last);
117         // <delta> is -1 to move upwards, +1 to move downwards.
118         void move_clips(size_t first, size_t last, int delta);
119
120         size_t size() const { return clips.size(); }
121         bool empty() const { return clips.empty(); }
122
123         ClipProxy mutable_clip(size_t index) { return ClipProxy(clips[index], this, index); }
124         const Clip *clip(size_t index) const { return &clips[index]; }
125
126         ClipProxy mutable_back() { return mutable_clip(size() - 1); }
127         const Clip *back() const { return clip(size() - 1); }
128
129         void set_currently_playing(int index, double progress);  // -1 = none.
130         int get_currently_playing() const { return currently_playing_index; }
131
132         ClipListProto serialize() const;
133
134         void emit_data_changed(size_t row) override;
135
136 signals:
137         void any_content_changed();
138
139 private:
140         std::vector<Clip> clips;
141         int currently_playing_index = -1;
142         double play_progress = 0.0;
143 };
144
145 #endif  // !defined (_CLIP_LIST_H)