1 module D2DGame.Window.WindowEvent;
2 
3 import D2D;
4 
5 import std.math : abs;
6 
7 /// Event structure on Window Events.
8 struct WindowEvent
9 {
10 	/// Types that can occur when WindowEvents are fired.
11 	enum Type
12 	{
13 		Undefined,
14 		/// Occurs when X button is clicked.
15 		Close,
16 		/// Occurs when window got resized.
17 		Resized,
18 		/// Occurs when window got moved.
19 		Moved,
20 		/// Occurs when window lost focus.
21 		LostFocus,
22 		/// Occurs when window gained focus again.
23 		GainedFocus,
24 		/// Occurs when `window.show` got called.
25 		Shown,
26 		/// Occurs when `window.hide` got called.
27 		Hidden,
28 		/// Occurs when the window minimizes.
29 		Minimized,
30 		/// Occurs when the window maximizes.
31 		Maximized,
32 		/// Occurs when the window restores from minimized/maximized state.
33 		Restored,
34 		/// Occurs when the user typed some text on the keyboard for text fields.
35 		TextEntered,
36 		/// Occurs when the user presses a key on the keyboard. Will fire repeatedly when held down.
37 		KeyPressed,
38 		/// Occurs when the user releases a key on the keyboard.
39 		KeyReleased,
40 		/// Occurs when the user scrolled.
41 		MouseWheelMoved,
42 		/// Occurs when the user pressed a mouse button.
43 		MouseButtonPressed,
44 		/// Occurs when the user released a mouse button.
45 		MouseButtonReleased,
46 		/// Occurs when the user moved the mouse.
47 		MouseMoved,
48 		/// Occurs when the mouse hovers over the window.
49 		MouseEntered,
50 		/// Occurs when the mouse no longer hovers over the window
51 		MouseLeft,
52 		/// Occurs when a button on a controller got pressed.
53 		ControllerButtonPressed,
54 		/// Occurs when a button on a controller got released.
55 		ControllerButtonReleased,
56 		/// Occurs when an axis on a controller got moved.
57 		ControllerAxis,
58 		/// Occurs when a controller connected.
59 		ControllerConnected,
60 		/// Occurs when a controller disconnected.
61 		ControllerDisconnected,
62 		/// Occurs when window is closing.
63 		Quit
64 	}
65 
66 	Type   type;
67 
68 	/// x/width in events.
69 	int	   x;
70 	/// y/height in events.
71 	int	   y;
72 	/// Relative mouse coordinates in Mouse events.
73 	int	   xrel, yrel;
74 	/// Mouse button in Mouse events.
75 	int	   mousebutton;
76 	/// Key in Controller and Keyboard events.
77 	int	   key;
78 	/// Controller id in Controller* event.
79 	int	   controllerID;
80 	/// Axis id in ControllerAxis event.
81 	int	   axis;
82 	/// Axis value in ControllerAxis event.
83 	short  axisValue;
84 	/// Text contained in TextEntered event.
85 	string text;
86 
87 	/// Function for converting a SDL event to a WindowEvent
88 	void   fromSDL(const ref SDL_Event event)
89 	{
90 		switch (event.type)
91 		{
92 		case SDL_WINDOWEVENT:
93 			switch (event.window.event)
94 			{
95 			case SDL_WINDOWEVENT_SHOWN:
96 				type = Type.Shown;
97 				break;
98 			case SDL_WINDOWEVENT_HIDDEN:
99 				type = Type.Hidden;
100 				break;
101 			case SDL_WINDOWEVENT_MOVED:
102 				type = Type.Moved;
103 				x	 = event.window.data1;
104 				y	 = event.window.data2;
105 				break;
106 			case SDL_WINDOWEVENT_RESIZED:
107 				type = Type.Resized;
108 				x	 = event.window.data1;
109 				y	 = event.window.data2;
110 				break;
111 			case SDL_WINDOWEVENT_MINIMIZED:
112 				type = Type.Minimized;
113 				break;
114 			case SDL_WINDOWEVENT_MAXIMIZED:
115 				type = Type.Maximized;
116 				break;
117 			case SDL_WINDOWEVENT_RESTORED:
118 				type = Type.Restored;
119 				break;
120 			case SDL_WINDOWEVENT_ENTER:
121 				type = Type.MouseEntered;
122 				break;
123 			case SDL_WINDOWEVENT_LEAVE:
124 				type = Type.MouseLeft;
125 				break;
126 			case SDL_WINDOWEVENT_FOCUS_GAINED:
127 				type = Type.GainedFocus;
128 				break;
129 			case SDL_WINDOWEVENT_FOCUS_LOST:
130 				type = Type.LostFocus;
131 				break;
132 			case SDL_WINDOWEVENT_CLOSE:
133 				type = Type.Close;
134 				break;
135 			default:
136 				type = Type.Undefined;
137 				break;
138 			}
139 			break;
140 		case SDL_KEYDOWN:
141 			type = Type.KeyPressed;
142 			key	 = event.key.keysym.sym;
143 			break;
144 		case SDL_KEYUP:
145 			type = Type.KeyReleased;
146 			key	 = event.key.keysym.sym;
147 			break;
148 		case SDL_MOUSEWHEEL:
149 			type = Type.MouseWheelMoved;
150 			x	 = event.wheel.x;
151 			y	 = event.wheel.y;
152 			break;
153 		case SDL_MOUSEMOTION:
154 			type = Type.MouseMoved;
155 			x	 = event.motion.x;
156 			y	 = event.motion.y;
157 			xrel = event.motion.xrel;
158 			yrel = event.motion.yrel;
159 			break;
160 		case SDL_MOUSEBUTTONDOWN:
161 			type		= Type.MouseButtonPressed;
162 			x			= event.button.x;
163 			y			= event.button.y;
164 			mousebutton = event.button.button;
165 			break;
166 		case SDL_MOUSEBUTTONUP:
167 			type		= Type.MouseButtonReleased;
168 			x			= event.button.x;
169 			y			= event.button.y;
170 			mousebutton = event.button.button;
171 			break;
172 		case SDL_CONTROLLERDEVICEADDED:
173 			type		 = Type.ControllerConnected;
174 			controllerID = event.cdevice.which;
175 			SDL_GameControllerOpen(controllerID);
176 			break;
177 		case SDL_CONTROLLERDEVICEREMOVED:
178 			type		 = Type.ControllerDisconnected;
179 			controllerID = event.cdevice.which;
180 			break;
181 		case SDL_CONTROLLERBUTTONDOWN:
182 			type		 = Type.ControllerButtonPressed;
183 			controllerID = event.cbutton.which;
184 			key			 = event.cbutton.button;
185 			break;
186 		case SDL_CONTROLLERBUTTONUP:
187 			type		 = Type.ControllerButtonReleased;
188 			controllerID = event.cbutton.which;
189 			key			 = event.cbutton.button;
190 			break;
191 		case SDL_CONTROLLERAXISMOTION:
192 			type = Type.ControllerAxis;
193 			short value = event.caxis.value;
194 			if (value < -32767)
195 				value = -32767;
196 			if ((event.caxis.axis == 0 || event.caxis.axis == 1) && abs(value) < 7849)
197 			{
198 				value = 0;
199 			}
200 			if ((event.caxis.axis == 2 || event.caxis.axis == 3) && abs(value) < 8689)
201 			{
202 				value = 0;
203 			}
204 			if ((event.caxis.axis == 4 || event.caxis.axis == 5) && abs(value) < 30)
205 			{
206 				value = 0;
207 			}
208 			axis	  = event.caxis.axis;
209 			axisValue = value;
210 			break;
211 		case SDL_TEXTINPUT:
212 			type = Type.TextEntered;
213 			text = cast(string) fromStringz(event.text.text.ptr);
214 			break;
215 		case SDL_QUIT:
216 			type = Type.Quit;
217 			break;
218 		default:
219 			type = Type.Undefined;
220 			break;
221 		}
222 	}
223 }
224 
225 ///
226 unittest
227 {
228 	SDL_Event	source;
229 	WindowEvent event;
230 	source.type			  = SDL_KEYDOWN;
231 	source.key.keysym.sym = 42;
232 	event.fromSDL(source);
233 
234 	assert(event.type == WindowEvent.Type.KeyPressed);
235 	assert(event.key == 42);
236 }
237 
238 ///
239 alias Event = WindowEvent;