1 /**
2 *	Cursors and windows.
3 */
4 module glfw3d.Window;
5 
6 import glfw3d.glfw3;
7 import glfw3d.Main;
8 import glfw3d.Monitor;
9 import std.string : fromStringz;
10 
11 /**
12 *	Utility structs. No documentation needed, isn't it?
13 */
14 struct WindowPosition {
15 	int x, y;
16 }
17 /// ditto
18 struct WindowSize {
19 	int width, height;
20 }
21 /// ditto
22 struct FrameSize {
23 	int left, top, right, bottom;
24 }
25 /// ditto
26 struct CursorPosition {
27 	double x, y;
28 }
29 
30 /**
31 *	Wrapper around GLFWcursor struct
32 */
33 class Cursor {
34 	private GLFWcursor* cursor;
35 
36 	/**
37 	*	It can be used to direct access to glfw3 functions.
38 	*	Returns: pointer to GLFWcursor
39 	*/
40 	GLFWcursor* ptr() {
41 		return this.cursor;
42 	}
43 
44 	/**
45 	*	Destroys cursor
46 	*/
47 	~this() {
48 		this.destroy();
49 	}
50 
51 	/**
52 	*	Creates basic arrow cursor
53 	*/
54 	this() {
55 		this(GLFW_ARROW_CURSOR);
56 	}
57 
58 	/**
59 	*	Creates cursor with standard shape.
60 	*	See_Also:
61 	*		$(LINK http://www.glfw.org/docs/latest/group__shapes.html)
62 	*/
63 	this(int shape) {
64 		this.cursor = glfwCreateStandardCursor(shape);
65 	}
66 
67 	/**
68 	*	Creates cursor with non-standard shape.
69 	*/
70 	this(const(GLFWimage)* img, int xhot, int yhot) {
71 		this.cursor = glfwCreateCursor(img, xhot, yhot);
72 	}
73 
74 	/**
75 	*	Destroys current cursor
76 	*/
77 	void destroy() {
78 		glfwDestroyCursor(this.cursor);
79 	}
80 }
81 
82 /**
83 *	Wrapper around GLFWwindow struct.
84 */
85 class Window {
86 	private GLFWwindow* window;
87 
88 	/**
89 	*	It can be used to direct access to glfw3 functions.
90 	*	Returns: pointer to GLFWwindow
91 	*/
92 	GLFWwindow* ptr() {
93 		return this.window;
94 	}
95 
96 	/**
97 	*	Destroys window
98 	*/
99 	~this() {
100 		this.destroy();
101 	}
102 
103 	/**
104 	*	Creates window
105 	*	Params:
106 	*		width = Width of new window
107 	*		height = Height of new window
108 	*		title = Title of new window
109 	*		mon = Make window full-screen on this monitor
110 	*		share = Share context with this window
111 	*/
112 	this(int width,
113 		int height,
114 		string title) {
115 			this(width,
116 				height,
117 				title,
118 				cast(GLFWmonitor*) null,
119 				cast(GLFWwindow*) null);
120 	}
121 	/// ditto
122 	this(int width,
123 		int height,
124 		string title,
125 		glfw3d.Monitor.Monitor mon) {
126 			this(width, height, title, mon.ptr, null);
127 	}
128 	/// ditto
129 	this(int width,
130 		int height,
131 		string title,
132 		glfw3d.Window.Window share) {
133 			this(width, height, title, null, share.ptr);
134 	}
135 	/// ditto
136 	this(int width,
137 		int height,
138 		string title,
139 		glfw3d.Monitor.Monitor mon,
140 		glfw3d.Window.Window share) {
141 			this(width, height, title, mon.ptr, share.ptr);
142 	}
143 	/// ditto
144 	this(int width,
145 		int height,
146 		string title, 
147 		GLFWmonitor* mon,
148 		GLFWwindow* share) {
149 			this.window = glfwCreateWindow(width,
150 				height,
151 				cast(const(char)*) title,
152 				mon,
153 				share);
154 			if(!this.window)
155 				throw new glfw3dException("Window or OpenGL context creation failed");
156 	}
157 
158 	/**
159 	*	Destroys window
160 	*/
161 	void destroy() {
162 		glfwDestroyWindow(this.window);
163 	}
164 
165 	/**
166 	*	Example:
167 	*	---
168 	*	auto w = new Window(640, 480, "Test");
169 	*	while(!w.shouldClose()) {
170 	*		// Main app loop
171 	*	}
172 	*	---
173 	*/
174 	int shouldClose() {
175 		return glfwWindowShouldClose(this.window);
176 	}
177 
178 	/**
179 	*	Sets shouldClose
180 	*/
181 	void setShouldClose(int v) {
182 		glfwSetWindowShouldClose(this.window, v);
183 	}
184 
185 	/**
186 	*	Sets window title
187 	*/
188 	void setTitle(string t) {
189 		glfwSetWindowTitle(this.window, cast(const(char)*) t);
190 	}
191 
192 	/**
193 	*	Sets window icon
194 	*/
195 	void setIcon(int count, const(GLFWimage)* img) {
196 		glfwSetWindowIcon(this.window, count, img);
197 	}
198 
199 	/**
200 	*	Returns: position of current window
201 	*/
202 	WindowPosition getPosition() {
203 		int x, y;
204 		glfwGetWindowPos(this.window, &x, &y);
205 		return WindowPosition(x, y);
206 	}
207 
208 	/**
209 	*	Sets position of window
210 	*/
211 	void setPosition(WindowPosition w) {
212 		this.setPosition(w.x, w.y);
213 	}
214 	/// ditto
215 	void setPosition(int x, int y) {
216 		glfwSetWindowPos(this.window, x, y);
217 	}
218 
219 	/**
220 	*	Returns: size of current window
221 	*/
222 	WindowSize getSize() {
223 		int w, h;
224 		glfwGetWindowSize(this.window, &w, &h);
225 		return WindowSize(w, h);
226 	}
227 
228 	/**
229 	*	Sets size of window
230 	*/
231 	void setSize(WindowSize w) {
232 		this.setSize(w.width, w.height);
233 	}
234 	/// ditto
235 	void setSize(int width, int height) {
236 		glfwSetWindowSize(this.window, width, height);
237 	}
238 
239 	/**
240 	*	Sets size limits of window
241 	*/
242 	void setSizeLimits(int minWidth,
243 		int minHeight,
244 		int maxWidth,
245 		int maxHeight) {
246 			glfwSetWindowSizeLimits(
247 				this.window,
248 				minWidth,
249 				minHeight,
250 				maxWidth,
251 				maxHeight
252 			);
253 	}
254 
255 	/**
256 	*	Example:
257 	*	---
258 	*	w.setAspectRatio(16, 9); // Window now always 16:9
259 	*	w.setAspectRatio(4, 3); // Window is 4:3
260 	*	---
261 	*/
262 	void setAspectRatio(int number, int denom) {
263 		glfwSetWindowAspectRatio(this.window, number, denom);
264 	}
265 
266 	/**
267 	*	Returns: size of framebuffer
268 	*/
269 	WindowSize getFramebufferSize() {
270 		int w, h;
271 		glfwGetFramebufferSize(this.window, &w, &h);
272 		return WindowSize(w, h);
273 	}
274 
275 	/**
276 	*	Returns: size, in screen coordinates, of each edge of the frame of the current window.
277 	*/
278 	FrameSize getFrameSize() {
279 		int l, t, r, b;
280 		glfwGetWindowFrameSize(this.window, &l, &t, &r, &b);
281 		return FrameSize(l, t, r, b);
282 	}
283 
284 	/**
285 	*	Minimizes(Iconifiezes) current window.
286 	*/
287 	void iconify() {
288 		glfwIconifyWindow(this.window);
289 	}
290 
291 	/**
292 	*	Restores iconified window.
293 	*/
294 	void restore() {
295 		glfwRestoreWindow(this.window);
296 	}
297 
298 	/**
299 	*	Maximizes window.
300 	*/
301 	void maximize() {
302 		glfwMaximizeWindow(this.window);
303 	}
304 
305 	/**
306 	*	Shows window.
307 	*/
308 	void show() {
309 		glfwShowWindow(this.window);
310 	}
311 
312 	/**
313 	*	Hides window.
314 	*/
315 	void hide() {
316 		glfwHideWindow(this.window);
317 	}
318 
319 	/**
320 	*	Gives input focus to window.
321 	*/
322 	void focus() {
323 		glfwFocusWindow(this.window);
324 	}
325 
326 	/**
327 	*	Returns: Monitor for fullscreen windows, or NULL for non-fullscreen windows.
328 	*/
329 	glfw3d.Monitor.Monitor getMonitor() {
330 		return new glfw3d.Monitor.Monitor(
331 			glfwGetWindowMonitor(this.window)
332 		);
333 	}
334 
335 	/**
336 	*	Makes window fullscreen on specified monitor.
337 	*/
338 	void setMonitor(glfw3d.Monitor.Monitor m,
339 		WindowPosition pos,
340 		WindowSize size,
341 		int refreshRate) {
342 			glfwSetWindowMonitor(
343 				this.window,
344 				m.ptr,
345 				pos.x,
346 				pos.y,
347 				size.width,
348 				size.height,
349 				refreshRate
350 			);
351 	}
352 
353 	/**
354 	*	Returns: Value of attribute $U(a)
355 	*/
356 	int getAttrib(int a) {
357 		return glfwGetWindowAttrib(this.window, a);
358 	}
359 
360 	/**
361 	*	Sets user pointer for the window.
362 	*/
363 	void setUserPointer(void* pointer) {
364 		glfwSetWindowUserPointer(this.window, pointer);
365 	}
366 
367 	/**
368 	*	Returns: user pointer of the window.
369 	*/
370 	void* getUserPointer() {
371 		return glfwGetWindowUserPointer(this.window);
372 	}
373 
374 	/**
375 	*	Swaps front and back buffer.
376 	*/
377 	void swapBuffers() {
378 		glfwSwapBuffers(this.window);
379 	}
380 
381 	/**
382 	*	Returns: current input mode
383 	*/
384 	int getInputMode(int mode) {
385 		return glfwGetInputMode(this.window, mode);
386 	}
387 
388 	/**
389 	*	Sets input mode.
390 	*/
391 	void setInputMode(int mode, int value) {
392 		return glfwSetInputMode(this.window, mode, value);
393 	}
394 
395 	/**
396 	*	Returns: last reported state of $U(key)
397 	*/
398 	int getKey(int key) {
399 		return glfwGetKey(this.window, key);
400 	}
401 
402 	/**
403 	*	Returns: last reported state of $U(button)
404 	*/
405 	int getMouseButton(int button) {
406 		return glfwGetMouseButton(this.window, button);
407 	}
408 
409 	/**
410 	*	Returns: position of the cursor
411 	*/
412 	CursorPosition getCursorPosition() {
413 		double x, y;
414 		glfwGetCursorPos(this.window, &x, &y);
415 		return CursorPosition(x, y);
416 	}
417 
418 	/**
419 	*	Sets cursor position.
420 	*/
421 	void setCursorPosition(CursorPosition c) {
422 		this.setCursorPosition(c.x, c.y);
423 	}
424 	/// ditto
425 	void setCursorPosition(double x, double y) {
426 		glfwSetCursorPos(this.window, x, y);
427 	}
428 
429 	/**
430 	*	Sets cursor.
431 	*/
432 	void setCursor(Cursor c) {
433 		this.setCursor(c.ptr());
434 	}
435 	/// ditto
436 	void setCursor(GLFWcursor* c) {
437 		glfwSetCursor(this.window, c);
438 	}
439 
440 	/**
441 	*	Sets clipboard text.
442 	*/
443 	void setClipboard(string s) {
444 		glfwSetClipboardString(this.window, cast(const(char)*) s);
445 	}
446 
447 	/**
448 	*	Returns: clipboard text
449 	*/
450 	string getClipboard() {
451 		return glfwGetClipboardString(this.window).fromStringz.idup;
452 	}
453 
454 	/**
455 	*	After creation of context this makes context current.
456 	*/
457 	void makeContextCurrent() {
458 		glfwMakeContextCurrent(this.window);
459 	}
460 
461 	/**
462 	*	Callbacks. More information in GLFW3 documentation.
463 	*/
464 	GLFWwindowposfun setPositionCallback(GLFWwindowposfun cb) {
465 		return glfwSetWindowPosCallback(this.window, cb);
466 	}
467 	/// ditto
468 	GLFWwindowsizefun setSizeCallback(GLFWwindowsizefun cb) {
469 		return glfwSetWindowSizeCallback(this.window, cb);
470 	}
471 	/// ditto
472 	GLFWwindowclosefun setCloseCallback(GLFWwindowclosefun cb) {
473 		return glfwSetWindowCloseCallback(this.window, cb);
474 	}
475 	/// ditto
476 	GLFWwindowrefreshfun setRefreshCallback(GLFWwindowrefreshfun cb) {
477 		return glfwSetWindowRefreshCallback(this.window, cb);
478 	}
479 	/// ditto
480 	GLFWwindowfocusfun setFocusCallback(GLFWwindowfocusfun cb) {
481 		return glfwSetWindowFocusCallback(this.window, cb);
482 	}
483 	/// ditto
484 	GLFWwindowiconifyfun setIconifyCallback(GLFWwindowiconifyfun cb) {
485 		return glfwSetWindowIconifyCallback(this.window, cb);
486 	}
487 	/// ditto
488 	GLFWframebuffersizefun setFramebufferSizeCallback(
489 		GLFWframebuffersizefun cb
490 	) {
491 		return glfwSetFramebufferSizeCallback(this.window, cb);
492 	}
493 	/// ditto
494 	GLFWkeyfun setKeyCallback(GLFWkeyfun cb) {
495 		return glfwSetKeyCallback(this.window, cb);
496 	}
497 	/// ditto
498 	GLFWcharfun setCharCallback(GLFWcharfun cb) {
499 		return glfwSetCharCallback(this.window, cb);
500 	}
501 	/// ditto
502 	GLFWcharmodsfun setCharModsCallback(GLFWcharmodsfun cb) {
503 		return glfwSetCharModsCallback(this.window, cb);
504 	}
505 	/// ditto
506 	GLFWmousebuttonfun setMouseButtonCallback(GLFWmousebuttonfun cb) {
507 		return glfwSetMouseButtonCallback(this.window, cb);
508 	}
509 	/// ditto
510 	GLFWcursorposfun setCursorPosCallback(GLFWcursorposfun cb) {
511 		return glfwSetCursorPosCallback(this.window, cb);
512 	}
513 	/// ditto
514 	GLFWcursorenterfun setCursorEnterCallback(GLFWcursorenterfun cb) {
515 		return glfwSetCursorEnterCallback(this.window, cb);
516 	}
517 	/// ditto
518 	GLFWscrollfun setScrollCallback(GLFWscrollfun cb) {
519 		return glfwSetScrollCallback(this.window, cb);
520 	}
521 	/// ditto
522 	GLFWdropfun setDropCallback(GLFWdropfun cb) {
523 		return glfwSetDropCallback(this.window, cb);
524 	}
525 }
526