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 OP_NONE = 0,
59 OP_SELECT,
60 OP_DRAG_POINT,
61 OP_DRAG_POINT_X,
62 OP_DRAG_POINT_Y,
63 OP_CONTEXT_MENU,
64 OP_BOX_SELECT,
65 OP_SCALE
66};
67
68enum class ESoundSourceOp
69{
70 OP_NONE = 0,
71 OP_MOVE,
72 OP_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::OP_NONE; }
84
85private:
86 EEnvelopeEditorOp m_TrackedOp = EEnvelopeEditorOp::OP_NONE;
87
88 struct SPointData
89 {
90 bool m_Used;
91 CFixedTime m_Time;
92 std::map<int, int> m_Values;
93 };
94
95 std::map<int, SPointData> m_SavedValues;
96
97 void HandlePointDragStart();
98 void HandlePointDragEnd(bool Switch);
99};
100
101class CSoundSourceOperationTracker : public CMapObject
102{
103public:
104 explicit CSoundSourceOperationTracker(CEditorMap *pMap);
105
106 void Begin(CSoundSource *pSource, ESoundSourceOp Operation, int LayerIndex);
107 void End();
108
109private:
110 CSoundSource *m_pSource;
111 ESoundSourceOp m_TrackedOp;
112 int m_LayerIndex;
113
114 struct SData
115 {
116 CPoint m_OriginalPoint;
117 };
118 SData m_Data;
119};
120
121struct SPropTrackerHelper
122{
123 static int GetDefaultGroupIndex(CEditorMap *pMap);
124 static int GetDefaultLayerIndex(CEditorMap *pMap);
125};
126
127template<typename T, typename E>
128class CPropTracker : public CMapObject
129{
130public:
131 explicit CPropTracker(CEditorMap *pMap) :
132 CMapObject(pMap),
133 m_OriginalValue(0),
134 m_pObject(nullptr),
135 m_OriginalLayerIndex(-1),
136 m_OriginalGroupIndex(-1),
137 m_CurrentLayerIndex(-1),
138 m_CurrentGroupIndex(-1),
139 m_Tracking(false) {}
140
141 void Begin(T *pObject, E Prop, EEditState State, int GroupIndex = -1, int LayerIndex = -1)
142 {
143 if(m_Tracking || Prop == static_cast<E>(-1))
144 return;
145 m_pObject = pObject;
146
147 m_OriginalGroupIndex = GroupIndex < 0 ? SPropTrackerHelper::GetDefaultGroupIndex(pMap: Map()) : GroupIndex;
148 m_OriginalLayerIndex = LayerIndex < 0 ? SPropTrackerHelper::GetDefaultLayerIndex(pMap: Map()) : LayerIndex;
149 m_CurrentGroupIndex = m_OriginalGroupIndex;
150 m_CurrentLayerIndex = m_OriginalLayerIndex;
151
152 int Value = PropToValue(Prop);
153 if(State == EEditState::START || State == EEditState::ONE_GO)
154 {
155 m_Tracking = true;
156 m_OriginalValue = Value;
157 OnStart(Prop);
158 }
159 }
160
161 void End(E Prop, EEditState State, int GroupIndex = -1, int LayerIndex = -1)
162 {
163 if(!m_Tracking || Prop == static_cast<E>(-1))
164 return;
165
166 m_CurrentGroupIndex = GroupIndex < 0 ? SPropTrackerHelper::GetDefaultGroupIndex(pMap: Map()) : GroupIndex;
167 m_CurrentLayerIndex = LayerIndex < 0 ? SPropTrackerHelper::GetDefaultLayerIndex(pMap: Map()) : LayerIndex;
168
169 if(State == EEditState::END || State == EEditState::ONE_GO)
170 {
171 m_Tracking = false;
172 int Value = PropToValue(Prop);
173 if(EndChecker(Prop, Value))
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 EndChecker(E Prop, int Value)
183 {
184 return Value != m_OriginalValue;
185 }
186
187 int m_OriginalValue;
188 T *m_pObject;
189 int m_OriginalLayerIndex;
190 int m_OriginalGroupIndex;
191 int m_CurrentLayerIndex;
192 int m_CurrentGroupIndex;
193 bool m_Tracking;
194};
195
196class CLayerPropTracker : public CPropTracker<CLayer, ELayerProp>
197{
198public:
199 explicit CLayerPropTracker(CEditorMap *pMap) :
200 CPropTracker<CLayer, ELayerProp>(pMap) {}
201
202protected:
203 void OnEnd(ELayerProp Prop, int Value) override;
204 int PropToValue(ELayerProp Prop) override;
205};
206
207class CLayerTilesPropTracker : public CPropTracker<CLayerTiles, ETilesProp>
208{
209public:
210 explicit CLayerTilesPropTracker(CEditorMap *pMap) :
211 CPropTracker<CLayerTiles, ETilesProp>(pMap) {}
212
213protected:
214 void OnStart(ETilesProp Prop) override;
215 void OnEnd(ETilesProp Prop, int Value) override;
216 bool EndChecker(ETilesProp Prop, int Value) override;
217
218 int PropToValue(ETilesProp Prop) override;
219
220private:
221 std::map<int, std::shared_ptr<CLayer>> m_SavedLayers;
222};
223
224class CLayerTilesCommonPropTracker : public CPropTracker<CLayerTiles, ETilesCommonProp>
225{
226public:
227 explicit CLayerTilesCommonPropTracker(CEditorMap *pMap) :
228 CPropTracker<CLayerTiles, ETilesCommonProp>(pMap) {}
229
230protected:
231 void OnStart(ETilesCommonProp Prop) override;
232 void OnEnd(ETilesCommonProp Prop, int Value) override;
233 bool EndChecker(ETilesCommonProp Prop, int Value) override;
234
235 int PropToValue(ETilesCommonProp Prop) override;
236
237private:
238 std::map<std::shared_ptr<CLayerTiles>, std::map<int, std::shared_ptr<CLayer>>> m_SavedLayers;
239
240public:
241 std::vector<std::shared_ptr<CLayerTiles>> m_vpLayers;
242 std::vector<int> m_vLayerIndices;
243};
244
245class CLayerGroupPropTracker : public CPropTracker<CLayerGroup, EGroupProp>
246{
247public:
248 explicit CLayerGroupPropTracker(CEditorMap *pMap) :
249 CPropTracker<CLayerGroup, EGroupProp>(pMap) {}
250
251protected:
252 void OnEnd(EGroupProp Prop, int Value) override;
253 int PropToValue(EGroupProp Prop) override;
254};
255
256class CLayerQuadsPropTracker : public CPropTracker<CLayerQuads, ELayerQuadsProp>
257{
258public:
259 explicit CLayerQuadsPropTracker(CEditorMap *pMap) :
260 CPropTracker<CLayerQuads, ELayerQuadsProp>(pMap) {}
261
262protected:
263 void OnEnd(ELayerQuadsProp Prop, int Value) override;
264 int PropToValue(ELayerQuadsProp Prop) override;
265};
266
267class CLayerSoundsPropTracker : public CPropTracker<CLayerSounds, ELayerSoundsProp>
268{
269public:
270 explicit CLayerSoundsPropTracker(CEditorMap *pMap) :
271 CPropTracker<CLayerSounds, ELayerSoundsProp>(pMap) {}
272
273protected:
274 void OnEnd(ELayerSoundsProp Prop, int Value) override;
275 int PropToValue(ELayerSoundsProp Prop) override;
276};
277
278class CSoundSourcePropTracker : public CPropTracker<CSoundSource, ESoundProp>
279{
280public:
281 explicit CSoundSourcePropTracker(CEditorMap *pMap) :
282 CPropTracker<CSoundSource, ESoundProp>(pMap) {}
283
284protected:
285 void OnEnd(ESoundProp Prop, int Value) override;
286 int PropToValue(ESoundProp Prop) override;
287};
288
289class CSoundSourceRectShapePropTracker : public CPropTracker<CSoundSource, ERectangleShapeProp>
290{
291public:
292 explicit CSoundSourceRectShapePropTracker(CEditorMap *pMap) :
293 CPropTracker<CSoundSource, ERectangleShapeProp>(pMap) {}
294
295protected:
296 void OnEnd(ERectangleShapeProp Prop, int Value) override;
297 int PropToValue(ERectangleShapeProp Prop) override;
298};
299
300class CSoundSourceCircleShapePropTracker : public CPropTracker<CSoundSource, ECircleShapeProp>
301{
302public:
303 explicit CSoundSourceCircleShapePropTracker(CEditorMap *pMap) :
304 CPropTracker<CSoundSource, ECircleShapeProp>(pMap) {}
305
306protected:
307 void OnEnd(ECircleShapeProp Prop, int Value) override;
308 int PropToValue(ECircleShapeProp Prop) override;
309};
310
311#endif
312