1 /*
2 DSFML - The Simple and Fast Multimedia Library for D
3 
4 Copyright (c) 2013 - 2015 Jeremy DeHaan (dehaan.jeremiah@gmail.com)
5 
6 This software is provided 'as-is', without any express or implied warranty.
7 In no event will the authors be held liable for any damages arising from the use of this software.
8 
9 Permission is granted to anyone to use this software for any purpose, including commercial applications,
10 and to alter it and redistribute it freely, subject to the following restrictions:
11 
12 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software.
13 If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
14 
15 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
16 
17 3. This notice may not be removed or altered from any source distribution
18 */
19 
20 module dsfml.graphics.view;
21 
22 import dsfml.graphics.rect;
23 import dsfml.system.vector2;
24 
25 /++
26  + 2D camera that defines what region is shown on screen
27  + 
28  + View defines a camera in the 2D scene.
29  + 
30  + This is a very powerful concept: you can scroll, rotate or zoom the entire scene without altering the way that your drawable objects are drawn.
31  + 
32  + A view is composed of a source rectangle, which defines what part of the 2D scene is shown, and a target viewport, which defines where the contents of the source rectangle will be displayed on the render target (window or texture).
33  + 
34  + The viewport allows to map the scene to a custom part of the render target, and can be used for split-screen or for displaying a minimap, for example. If the source rectangle has not the same size as the viewport, its contents will be stretched to fit in.
35  + 
36  + To apply a view, you have to assign it to the render target. Then, every objects drawn in this render target will be affected by the view until you use another view.
37  + 
38  + Authors: Laurent Gomila, Jeremy DeHaan
39  + See_Also: http://www.sfml-dev.org/documentation/2.0/classsf_1_1View.php#details
40  +/
41 
42 class View
43 {
44 	package sfView* sfPtr;
45 	
46 	this()
47 	{
48 		// Constructor code
49 		sfPtr = sfView_create();
50 	}
51 
52 	this(FloatRect rectangle)
53 	{
54 		
55 		sfPtr = sfView_createFromRect(rectangle.left,rectangle.top, rectangle.width, rectangle.height);
56 	}
57 	
58 	package this(sfView* sfview)
59 	{
60 		sfPtr = sfView_copy(sfview);
61 	}
62 
63 	~this()
64 	{
65 		import dsfml.system.config;
66 		mixin(destructorOutput);
67 		sfView_destroy(sfPtr);
68 	}
69 
70 	/// The center of the view.
71 	@property
72 	{
73 		Vector2f center(Vector2f newCenter)
74 		{
75 			sfView_setCenter(sfPtr, newCenter.x, newCenter.y);
76 			return newCenter;
77 		}
78 		
79 		Vector2f center() const
80 		{
81 			Vector2f temp;
82 			sfView_getCenter(sfPtr, &temp.x, &temp.y);
83 			return temp;
84 		}	
85 	}
86 
87 	/// The orientation of the view, in degrees. The default rotation is 0 degrees.
88 	@property
89 	{
90 		float rotation(float newRotation)
91 		{
92 			sfView_setRotation(sfPtr, newRotation);
93 			return newRotation;
94 		}
95 		float rotation() const
96 		{
97 			return sfView_getRotation(sfPtr);
98 			
99 		}
100 	}
101 
102 	/// The size of the view. The default size is (1, 1).
103 	@property
104 	{
105 		Vector2f size(Vector2f newSize)
106 		{
107 			sfView_setSize(sfPtr, newSize.x, newSize.y);
108 			return newSize;
109 		}
110 		
111 		Vector2f size() const
112 		{
113 			Vector2f temp;
114 			sfView_getSize(sfPtr, &temp.x, &temp.y);
115 			return temp;
116 		}
117 	}
118 
119 	/**
120 	 * The target viewpoirt.
121 	 * 
122 	 * The viewport is the rectangle into which the contents of the view are displayed, expressed as a factor (between 0 and 1) of the size of the RenderTarget to which the view is applied. For example, a view which takes the left side of the target would be defined with View.setViewport(FloatRect(0, 0, 0.5, 1)). By default, a view has a viewport which covers the entire target.
123 	 */
124 	@property
125 	{
126 		FloatRect viewport(FloatRect newTarget)
127 		{
128 			sfView_setViewport(sfPtr, newTarget.left, newTarget.top, newTarget.width, newTarget.height);
129 			return newTarget;
130 		}
131 		FloatRect viewport() const
132 		{
133 			FloatRect temp;
134 			sfView_getViewport(sfPtr, &temp.left, &temp.top, &temp.width, &temp.height);
135 			return temp;
136 		}
137 	}
138 
139 	/**
140 	 * Performs a deep copy of the view.
141 	 * 
142 	 * Returns: Duplicated view.
143 	 */
144 	@property
145 	View dup() const
146 	{
147 		return new View(sfView_copy(sfPtr));
148 	}
149 
150 	/**
151 	 * Move the view relatively to its current position.
152 	 * 
153 	 * Params:
154 	 * 		offset	= Move offset
155 	 */
156 	void move(Vector2f offset)
157 	{
158 		sfView_move(sfPtr, offset.x, offset.y);
159 	}
160 
161 	/**
162 	 * Reset the view to the given rectangle.
163 	 * 
164 	 * Note that this function resets the rotation angle to 0.
165 	 * 
166 	 * Params:
167 	 * 		rectangle	= Rectangle defining the zone to display.
168 	 */
169 	void reset(FloatRect rectangle)
170 	{
171 		sfView_reset(sfPtr, rectangle.left,rectangle.top, rectangle.width, rectangle.height);
172 	}
173 
174 	/**
175 	 * Resize the view rectangle relatively to its current size.
176 	 * 
177 	 * Resizing the view simulates a zoom, as the zone displayed on screen grows or shrinks. factor is a multiplier:
178 	 * - 1 keeps the size unchanged.
179 	 * - > 1 makes the view bigger (objects appear smaller).
180 	 * - < 1 makes the view smaller (objects appear bigger).
181 	 * 
182 	 * Params:
183 	 * 		factor	= Zoom factor to apply.
184 	 */
185 	void zoom(float factor)
186 	{
187 		sfView_zoom(sfPtr, factor);
188 	}
189 }
190 
191 unittest
192 {
193 	version(DSFML_Unittest_Graphics)
194 	{
195 		import std.stdio;
196 
197 		import dsfml.graphics.rendertexture;
198 
199 		writeln("Unit test for View");
200 
201 		//the portion of the screen the view is displaying is at position (0,0) with a width of 100 and a height of 100
202 		auto view = new View(FloatRect(0,0,100,100));
203 
204 		//the portion of the screen the view is displaying is at position (0,0) and takes up the remaining size of the screen.(expressed as a ratio)
205 		view.viewport = FloatRect(0,0,1,1);
206 
207 		auto renderTexture = new RenderTexture();
208 		
209 		renderTexture.create(1000,1000);
210 
211 		renderTexture.clear();
212 
213 		//set the view of the renderTexture
214 		renderTexture.view = view;
215 
216 		//draw some things using this view
217 
218 		//get it ready for rendering
219 		renderTexture.display();
220 
221 
222 
223 
224 
225 		writeln();
226 	}
227 }
228 
229 
230 package extern(C) struct sfView;
231 
232 private extern(C):
233 
234 //Create a default view
235 sfView* sfView_create();
236 
237 //Construct a view from a rectangle
238 sfView* sfView_createFromRect(float left, float top, float width, float height);
239 
240 
241 //Copy an existing view
242 sfView* sfView_copy(const sfView* view);
243 
244 
245 //Destroy an existing view
246 void sfView_destroy(sfView* view);
247 
248 
249 //Set the center of a view
250 void sfView_setCenter(sfView* view, float centerX, float centerY);
251 
252 
253 //Set the size of a view
254 void sfView_setSize(sfView* view, float sizeX, float sizeY);
255 
256 
257 //Set the orientation of a view
258 void sfView_setRotation(sfView* view, float angle);
259 
260 
261 //Set the target viewport of a view
262 void sfView_setViewport(sfView* view, float left, float top, float width, float height);
263 
264 
265 //Reset a view to the given rectangle
266 void sfView_reset(sfView* view, float left, float top, float width, float height);
267 
268 
269 //Get the center of a view
270 void sfView_getCenter(const sfView* view, float* x, float* y);
271 
272 
273 //Get the size of a view
274 void sfView_getSize(const sfView* view, float* x, float* y);
275 
276 
277 //Get the current orientation of a view
278 float sfView_getRotation(const sfView* view);
279 
280 
281 //Get the target viewport rectangle of a view
282 void sfView_getViewport(const sfView* view, float* left, float* top, float* width, float* height);
283 
284 //Move a view relatively to its current position
285 void sfView_move(sfView* view, float offsetX, float offsetY);
286 
287 
288 //Rotate a view relatively to its current orientation
289 void sfView_rotate(sfView* view, float angle);
290 
291 
292 //Resize a view rectangle relatively to its current size
293 void sfView_zoom(sfView* view, float factor);