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