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