1 /* Copyright (C) 2017 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "precompiled.h"
19 
20 #include "Common/Tools.h"
21 #include "Common/Brushes.h"
22 #include "Common/MiscState.h"
23 #include "Common/ObjectSettings.h"
24 #include "GameInterface/Messages.h"
25 #include "ScenarioEditor/ScenarioEditor.h"
26 
27 #include <wx/clipbrd.h>
28 #include <wx/sstream.h>
29 #include <wx/version.h>
30 #include <wx/xml/xml.h>
31 
32 
33 using AtlasMessage::Position;
34 
35 class TransformPath : public StateDrivenTool<TransformPath>
36 {
37 	DECLARE_DYNAMIC_CLASS(TransformPath);
38 
39 	wxPoint m_StartPoint;
40 	AtlasMessage::sCinemaPathNode node;
41 	int axis;
42 
43 public:
TransformPath()44 	TransformPath()
45 	{
46 		SetState(&Waiting);
47 	}
48 
OnDisable()49 	void OnDisable()
50 	{
51 		POST_MESSAGE(ClearPathNodePreview, );
52 	}
53 
54 	struct sWaiting : public State
55 	{
OnMouseTransformPath::sWaiting56 		bool OnMouse(TransformPath* obj, wxMouseEvent& evt)
57 		{
58 			if (evt.LeftDown())
59 			{
60 				ScenarioEditor::GetCommandProc().FinaliseLastCommand();
61 
62 				AtlasMessage::qPickPathNode query(Position(evt.GetPosition()));
63 				query.Post();
64 
65 				obj->node = query.node;
66 				if (obj->node.index != AtlasMessage::AXIS_INVALID)
67 					SET_STATE(WaitingAxis);
68 				return true;
69 			}
70 			else
71 				return false;
72 		}
73 	}
74 	Waiting;
75 
76 	struct sWaitingAxis : public State
77 	{
OnMouseTransformPath::sWaitingAxis78 		bool OnMouse(TransformPath* obj, wxMouseEvent& evt)
79 		{
80 			if (evt.LeftDown())
81 			{
82 				AtlasMessage::qPickAxis query(obj->node, Position(evt.GetPosition()));
83 				query.Post();
84 
85 				obj->axis = query.axis;
86 				if (obj->axis != AtlasMessage::AXIS_INVALID)
87 				{
88 					obj->m_StartPoint = evt.GetPosition();
89 					SET_STATE(Dragging);
90 				}
91 				return true;
92 			}
93 			else if (evt.LeftUp())
94 			{
95 				if (obj->axis != AtlasMessage::AXIS_INVALID)
96 					return false;
97 
98 				AtlasMessage::qPickPathNode query(Position(evt.GetPosition()));
99 				query.Post();
100 
101 				obj->node = query.node;
102 				if (obj->node.index == -1)
103 					SET_STATE(Waiting);
104 				return true;
105 			}
106 			else
107 				return false;
108 		}
109 
OnKeyTransformPath::sWaitingAxis110 		bool OnKey(TransformPath* obj, wxKeyEvent& evt, KeyEventType type)
111 		{
112 			if (type != KEY_UP)
113 				return false;
114 			switch (evt.GetKeyCode())
115 			{
116 			case WXK_INSERT:
117 				POST_COMMAND(AddPathNode, (obj->node));
118 				return true;
119 			case WXK_DELETE:
120 				POST_COMMAND(DeletePathNode, (obj->node));
121 				obj->node.index = -1;
122 				return true;
123 			case WXK_ESCAPE:
124 				POST_MESSAGE(ClearPathNodePreview, );
125 				SET_STATE(Waiting);
126 				return true;
127 			default:
128 				return false;
129 			}
130 		}
131 	}
132 	WaitingAxis;
133 
134 	struct sDragging : public State
135 	{
OnMouseTransformPath::sDragging136 		bool OnMouse(TransformPath* obj, wxMouseEvent& evt)
137 		{
138 			if (evt.LeftUp())
139 			{
140 				obj->axis = AtlasMessage::AXIS_INVALID;
141 				SET_STATE(WaitingAxis);
142 				return true;
143 			}
144 			else if (evt.Dragging())
145 			{
146 				POST_COMMAND(MovePathNode, (obj->node, obj->axis, Position(obj->m_StartPoint), Position(evt.GetPosition())));
147 				obj->m_StartPoint = evt.GetPosition();
148 				return true;
149 			}
150 			else
151 				return false;
152 		}
153 
OnKeyTransformPath::sDragging154 		bool OnKey(TransformPath* obj, wxKeyEvent& evt, KeyEventType type)
155 		{
156 			if (type != KEY_UP)
157 				return false;
158 			if (evt.GetKeyCode() == WXK_ESCAPE)
159 			{
160 				POST_MESSAGE(ClearPathNodePreview, );
161 				SET_STATE(Waiting);
162 				return true;
163 			}
164 			else
165 				return false;
166 		}
167 	}
168 	Dragging;
169 };
170 
171 IMPLEMENT_DYNAMIC_CLASS(TransformPath, StateDrivenTool<TransformPath>);
172