1#ifndef GAME_EDITOR_EDITOR_TRACKERS_H
2#define GAME_EDITOR_EDITOR_TRACKERS_H
3
4#include <game/editor/mapitems.h>
5#include <game/editor/mapitems/layer_quads.h>
6#include <game/mapitems.h>
7
8#include <map>
9#include <memory>
10#include <vector>
11
12class CEditor;
13class CLayerTiles;
14class CLayerGroup;
15class CLayerSounds;
16struct CSoundSource;
17
18class CQuadEditTracker
19{
20public:
21 CQuadEditTracker();
22 ~CQuadEditTracker();
23
24 void BeginQuadTrack(const std::shared_ptr<CLayerQuads> &pLayer, const std::vector<int> &vSelectedQuads, int GroupIndex = -1, int LayerIndex = -1);
25 void EndQuadTrack();
26
27 void BeginQuadPropTrack(const std::shared_ptr<CLayerQuads> &pLayer, const std::vector<int> &vSelectedQuads, EQuadProp Prop, int GroupIndex = -1, int LayerIndex = -1);
28 void EndQuadPropTrack(EQuadProp Prop);
29
30 void BeginQuadPointPropTrack(const std::shared_ptr<CLayerQuads> &pLayer, const std::vector<int> &vSelectedQuads, int SelectedQuadPoints, int GroupIndex = -1, int LayerIndex = -1);
31 void AddQuadPointPropTrack(EQuadPointProp Prop);
32 void EndQuadPointPropTrack(EQuadPointProp Prop);
33 void EndQuadPointPropTrackAll();
34
35 CEditor *m_pEditor;
36
37private:
38 std::vector<int> m_vSelectedQuads;
39 int m_SelectedQuadPoints;
40 std::map<int, std::vector<CPoint>> m_InitalPoints;
41
42 bool m_Tracking = false;
43 std::shared_ptr<CLayerQuads> m_pLayer;
44
45 EQuadProp m_TrackedProp;
46 std::vector<EQuadPointProp> m_vTrackedProps;
47 std::map<int, int> m_PreviousValues;
48 std::map<int, std::vector<std::map<EQuadPointProp, int>>> m_PreviousValuesPoint;
49 int m_LayerIndex;
50 int m_GroupIndex;
51};
52
53enum class EEnvelopeEditorOp
54{
55 OP_NONE = 0,
56 OP_SELECT,
57 OP_DRAG_POINT,
58 OP_DRAG_POINT_X,
59 OP_DRAG_POINT_Y,
60 OP_CONTEXT_MENU,
61 OP_BOX_SELECT,
62 OP_SCALE
63};
64
65enum class ESoundSourceOp
66{
67 OP_NONE = 0,
68 OP_MOVE,
69 OP_CONTEXT_MENU,
70};
71
72class CEnvelopeEditorOperationTracker
73{
74public:
75 CEnvelopeEditorOperationTracker() = default;
76
77 void Begin(EEnvelopeEditorOp Operation);
78 void Stop(bool Switch = true);
79 inline void Reset() { m_TrackedOp = EEnvelopeEditorOp::OP_NONE; }
80
81 CEditor *m_pEditor;
82
83private:
84 EEnvelopeEditorOp m_TrackedOp = EEnvelopeEditorOp::OP_NONE;
85
86 struct SPointData
87 {
88 bool m_Used;
89 int m_Time;
90 std::map<int, int> m_Values;
91 };
92
93 std::map<int, SPointData> m_SavedValues;
94
95 void HandlePointDragStart();
96 void HandlePointDragEnd(bool Switch);
97};
98
99class CSoundSourceOperationTracker
100{
101public:
102 CSoundSourceOperationTracker(CEditor *pEditor);
103
104 void Begin(CSoundSource *pSource, ESoundSourceOp Operation, int LayerIndex);
105 void End();
106
107private:
108 CEditor *m_pEditor;
109 CSoundSource *m_pSource;
110 ESoundSourceOp m_TrackedOp;
111 int m_LayerIndex;
112
113 struct SData
114 {
115 CPoint m_OriginalPoint;
116 };
117 SData m_Data;
118
119 enum EState
120 {
121 STATE_BEGIN,
122 STATE_EDITING,
123 STATE_END
124 };
125 void HandlePointMove(EState State);
126};
127
128struct SPropTrackerHelper
129{
130 static int GetDefaultGroupIndex(CEditor *pEditor);
131 static int GetDefaultLayerIndex(CEditor *pEditor);
132};
133
134template<typename T, typename E>
135class CPropTracker
136{
137public:
138 CPropTracker(CEditor *pEditor) :
139 m_pEditor(pEditor), m_OriginalValue(0), m_pObject(nullptr), m_OriginalLayerIndex(-1), m_OriginalGroupIndex(-1), m_CurrentLayerIndex(-1), m_CurrentGroupIndex(-1), m_Tracking(false) {}
140 CEditor *m_pEditor;
141
142 void Begin(T *pObject, E Prop, EEditState State, int GroupIndex = -1, int LayerIndex = -1)
143 {
144 if(m_Tracking || Prop == static_cast<E>(-1))
145 return;
146 m_pObject = pObject;
147
148 m_OriginalGroupIndex = GroupIndex < 0 ? SPropTrackerHelper::GetDefaultGroupIndex(pEditor: m_pEditor) : GroupIndex;
149 m_OriginalLayerIndex = LayerIndex < 0 ? SPropTrackerHelper::GetDefaultLayerIndex(pEditor: m_pEditor) : LayerIndex;
150 m_CurrentGroupIndex = m_OriginalGroupIndex;
151 m_CurrentLayerIndex = m_OriginalLayerIndex;
152
153 int Value = PropToValue(Prop);
154 if(StartChecker(Prop, State, Value))
155 {
156 m_Tracking = true;
157 m_OriginalValue = Value;
158 OnStart(Prop);
159 }
160 }
161
162 void End(E Prop, EEditState State, int GroupIndex = -1, int LayerIndex = -1)
163 {
164 if(!m_Tracking || Prop == static_cast<E>(-1))
165 return;
166
167 m_CurrentGroupIndex = GroupIndex < 0 ? SPropTrackerHelper::GetDefaultGroupIndex(pEditor: m_pEditor) : GroupIndex;
168 m_CurrentLayerIndex = LayerIndex < 0 ? SPropTrackerHelper::GetDefaultLayerIndex(pEditor: m_pEditor) : LayerIndex;
169
170 int Value = PropToValue(Prop);
171 if(EndChecker(Prop, State, Value))
172 {
173 m_Tracking = false;
174 OnEnd(Prop, Value);
175 }
176 }
177
178protected:
179 virtual void OnStart(E Prop) {}
180 virtual void OnEnd(E Prop, int Value) {}
181 virtual int PropToValue(E Prop) { return 0; }
182 virtual bool StartChecker(E Prop, EEditState State, int Value)
183 {
184 return State == EEditState::START || State == EEditState::ONE_GO;
185 }
186 virtual bool EndChecker(E Prop, EEditState State, int Value)
187 {
188 return (State == EEditState::END || State == EEditState::ONE_GO) && (Value != m_OriginalValue);
189 }
190
191 int m_OriginalValue;
192 T *m_pObject;
193 int m_OriginalLayerIndex;
194 int m_OriginalGroupIndex;
195 int m_CurrentLayerIndex;
196 int m_CurrentGroupIndex;
197 bool m_Tracking;
198};
199
200class CLayerPropTracker : public CPropTracker<CLayer, ELayerProp>
201{
202public:
203 CLayerPropTracker(CEditor *pEditor) :
204 CPropTracker<CLayer, ELayerProp>(pEditor){};
205
206protected:
207 void OnEnd(ELayerProp Prop, int Value) override;
208 int PropToValue(ELayerProp Prop) override;
209};
210
211class CLayerTilesPropTracker : public CPropTracker<CLayerTiles, ETilesProp>
212{
213public:
214 CLayerTilesPropTracker(CEditor *pEditor) :
215 CPropTracker<CLayerTiles, ETilesProp>(pEditor){};
216
217protected:
218 void OnStart(ETilesProp Prop) override;
219 void OnEnd(ETilesProp Prop, int Value) override;
220 bool EndChecker(ETilesProp Prop, EEditState State, int Value) override;
221
222 int PropToValue(ETilesProp Prop) override;
223
224private:
225 std::map<int, std::shared_ptr<CLayer>> m_SavedLayers;
226};
227
228class CLayerTilesCommonPropTracker : public CPropTracker<CLayerTiles, ETilesCommonProp>
229{
230public:
231 CLayerTilesCommonPropTracker(CEditor *pEditor) :
232 CPropTracker<CLayerTiles, ETilesCommonProp>(pEditor){};
233
234protected:
235 void OnStart(ETilesCommonProp Prop) override;
236 void OnEnd(ETilesCommonProp Prop, int Value) override;
237 bool EndChecker(ETilesCommonProp Prop, EEditState State, int Value) override;
238
239 int PropToValue(ETilesCommonProp Prop) override;
240
241private:
242 std::map<std::shared_ptr<CLayerTiles>, std::map<int, std::shared_ptr<CLayer>>> m_SavedLayers;
243
244public:
245 std::vector<std::shared_ptr<CLayerTiles>> m_vpLayers;
246 std::vector<int> m_vLayerIndices;
247};
248
249class CLayerGroupPropTracker : public CPropTracker<CLayerGroup, EGroupProp>
250{
251public:
252 CLayerGroupPropTracker(CEditor *pEditor) :
253 CPropTracker<CLayerGroup, EGroupProp>(pEditor){};
254
255protected:
256 void OnEnd(EGroupProp Prop, int Value) override;
257 int PropToValue(EGroupProp Prop) override;
258};
259
260class CLayerQuadsPropTracker : public CPropTracker<CLayerQuads, ELayerQuadsProp>
261{
262public:
263 CLayerQuadsPropTracker(CEditor *pEditor) :
264 CPropTracker<CLayerQuads, ELayerQuadsProp>(pEditor){};
265
266protected:
267 void OnEnd(ELayerQuadsProp Prop, int Value) override;
268 int PropToValue(ELayerQuadsProp Prop) override;
269};
270
271class CLayerSoundsPropTracker : public CPropTracker<CLayerSounds, ELayerSoundsProp>
272{
273public:
274 CLayerSoundsPropTracker(CEditor *pEditor) :
275 CPropTracker<CLayerSounds, ELayerSoundsProp>(pEditor){};
276
277protected:
278 void OnEnd(ELayerSoundsProp Prop, int Value) override;
279 int PropToValue(ELayerSoundsProp Prop) override;
280};
281
282class CSoundSourcePropTracker : public CPropTracker<CSoundSource, ESoundProp>
283{
284public:
285 CSoundSourcePropTracker(CEditor *pEditor) :
286 CPropTracker<CSoundSource, ESoundProp>(pEditor) {}
287
288protected:
289 void OnEnd(ESoundProp Prop, int Value) override;
290 int PropToValue(ESoundProp Prop) override;
291};
292
293class CSoundSourceRectShapePropTracker : public CPropTracker<CSoundSource, ERectangleShapeProp>
294{
295public:
296 CSoundSourceRectShapePropTracker(CEditor *pEditor) :
297 CPropTracker<CSoundSource, ERectangleShapeProp>(pEditor) {}
298
299protected:
300 void OnEnd(ERectangleShapeProp Prop, int Value) override;
301 int PropToValue(ERectangleShapeProp Prop) override;
302};
303
304class CSoundSourceCircleShapePropTracker : public CPropTracker<CSoundSource, ECircleShapeProp>
305{
306public:
307 CSoundSourceCircleShapePropTracker(CEditor *pEditor) :
308 CPropTracker<CSoundSource, ECircleShapeProp>(pEditor) {}
309
310protected:
311 void OnEnd(ECircleShapeProp Prop, int Value) override;
312 int PropToValue(ECircleShapeProp Prop) override;
313};
314
315#endif
316