├── .gitignore
├── .travis.yml
├── LICENSE
├── README.md
├── docs
├── CrystGLFW.html
├── CrystGLFW
│ ├── Error.html
│ ├── Error
│ │ ├── APIUnavailable.html
│ │ ├── Any.html
│ │ ├── FormatUnavailable.html
│ │ ├── InvalidEnum.html
│ │ ├── InvalidValue.html
│ │ ├── JoystickNotConnected.html
│ │ ├── KeyNotPrintable.html
│ │ ├── NoCurrentContext.html
│ │ ├── NoWindowContext.html
│ │ ├── NotFullScreen.html
│ │ ├── NotInitialized.html
│ │ ├── OutOfMemory.html
│ │ ├── PlatformError.html
│ │ └── VersionUnavailable.html
│ ├── ErrorCallback.html
│ ├── Event.html
│ ├── Event
│ │ ├── Any.html
│ │ ├── JoystickToggleConnection.html
│ │ ├── Modifiers.html
│ │ ├── MonitorToggleConnection.html
│ │ ├── WindowChar.html
│ │ ├── WindowClose.html
│ │ ├── WindowCursorCrossThreshold.html
│ │ ├── WindowCursorMove.html
│ │ ├── WindowFileDrop.html
│ │ ├── WindowFramebufferResize.html
│ │ ├── WindowKey.html
│ │ ├── WindowMouseButton.html
│ │ ├── WindowMove.html
│ │ ├── WindowRefresh.html
│ │ ├── WindowResize.html
│ │ ├── WindowScroll.html
│ │ ├── WindowToggleFocus.html
│ │ └── WindowToggleIconification.html
│ ├── Joystick.html
│ ├── Joystick
│ │ ├── JoystickCallback.html
│ │ └── ToggleConnectionCallback.html
│ ├── Key.html
│ ├── Monitor.html
│ ├── Monitor
│ │ ├── GammaRamp.html
│ │ ├── MonitorCallback.html
│ │ ├── ToggleConnectionCallback.html
│ │ └── VideoMode.html
│ ├── MouseButton.html
│ ├── Window.html
│ └── Window
│ │ ├── CharCallback.html
│ │ ├── CloseCallback.html
│ │ ├── Cursor.html
│ │ ├── CursorCrossThresholdCallback.html
│ │ ├── CursorMoveCallback.html
│ │ ├── FileDropCallback.html
│ │ ├── FramebufferResizeCallback.html
│ │ ├── Image.html
│ │ ├── KeyCallback.html
│ │ ├── MouseButtonCallback.html
│ │ ├── MoveCallback.html
│ │ ├── RefreshCallback.html
│ │ ├── ResizeCallback.html
│ │ ├── ScrollCallback.html
│ │ ├── ToggleFocusCallback.html
│ │ ├── ToggleIconificationCallback.html
│ │ └── WindowCallback.html
├── css
│ └── style.css
├── index.html
└── js
│ └── doc.js
├── shard.yml
├── spec
├── CrystGLFW_spec.cr
└── spec_helper.cr
└── src
├── crystglfw.cr
└── crystglfw
├── action.cr
├── client_api.cr
├── connection_status.cr
├── context_api.cr
├── context_robustness.cr
├── error.cr
├── events
├── any.cr
├── event.cr
├── joystick_toggle_connection.cr
├── modifiers.cr
├── monitor_toggle_connection.cr
├── window_char.cr
├── window_close.cr
├── window_cursor_cross_threshold.cr
├── window_cursor_move.cr
├── window_file_drop.cr
├── window_framebuffer_resize.cr
├── window_key.cr
├── window_mouse_button.cr
├── window_move.cr
├── window_refresh.cr
├── window_resize.cr
├── window_scroll.cr
├── window_toggle_focus.cr
└── window_toggle_iconification.cr
├── joystick.cr
├── key.cr
├── monitors
├── gamma_ramp.cr
├── monitor.cr
└── video_mode.cr
├── mouse_button.cr
├── opengl_profile.cr
├── release_behavior.cr
├── sticky.cr
├── version.cr
└── windows
├── cursor.cr
├── hint_label.cr
├── image.cr
├── state.cr
└── window.cr
/.gitignore:
--------------------------------------------------------------------------------
1 | /doc/
2 | /lib/
3 | /bin/
4 | /.shards/
5 |
6 | # Libraries don't need dependency lock
7 | # Dependencies will be locked in application that uses them
8 | /shard.lock
9 |
10 | .DS_Store
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: crystal
2 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2017 Caleb Uriah Harrison
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in
13 | all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | THE SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CrystGLFW
2 |
3 | An object-oriented API for GLFW in Crystal.
4 |
5 | [GLFW](https://glfw.org) is a razor-thin, cross-platform library for spinning up OpenGL contexts via windows as well as
6 | receiving user input and platform events. CrystGLFW provides an object-oriented API for the full GLFW specification, including
7 | window creation, working with multiple monitors, keyboard and joystick/controller input, idiomatic callbacks, and more.
8 |
9 | The flexibility and portability of GLFW meets the speed and ease-of-use of Crystal. What a time to be alive!
10 |
11 | CrystGLFW uses [LibGLFW](https://github.com/calebuharrison/LibGLFW) behind the scenes.
12 |
13 | [Read the guides!](https://calebuharrison.gitbooks.io/crystglfw-guide/content/)
14 |
15 | ## Installation
16 |
17 | First, you'll want to make sure you've got GLFW3:
18 |
19 | ```sh
20 | brew install glfw3
21 | ```
22 |
23 | Add this to your application's `shard.yml`:
24 |
25 | ```yaml
26 | dependencies:
27 | crystglfw:
28 | github: calebuharrison/CrystGLFW
29 | branch: master
30 | ```
31 |
32 | Install your dependencies:
33 |
34 | ```sh
35 | shards install
36 | ```
37 |
38 | ## Quick Start
39 |
40 | ```crystal
41 | require "crystglfw"
42 | include CrystGLFW
43 |
44 | # Initialize GLFW
45 | CrystGLFW.run do
46 | # Create a new window.
47 | window = Window.new(title: "My First Window")
48 |
49 | # Configure the window to print its dimensions each time it is resized.
50 | window.on_resize do |event|
51 | puts "Window resized to #{event.size}"
52 | end
53 |
54 | # Make this window's OpenGL context the current drawing context.
55 | window.make_context_current
56 |
57 | # Listen for callbacks and draw the window until it has been marked for closing.
58 | until window.should_close?
59 | CrystGLFW.wait_events
60 | window.swap_buffers
61 | end
62 |
63 | # Destroy the window.
64 | window.destroy
65 |
66 | # Shut down and clean up GLFW.
67 | end
68 | ```
69 |
70 | CrystGLFW has much more to offer - check out the [guides](https://calebuharrison.gitbooks.io/crystglfw-guide/content/)!
71 |
72 | ## Contributing
73 |
74 | 1. Fork it ( https://github.com/calebuharrison/CrystGLFW/fork )
75 | 2. Create your feature branch (git checkout -b my-new-feature)
76 | 3. Commit your changes (git commit -am 'Add some feature')
77 | 4. Push to the branch (git push origin my-new-feature)
78 | 5. Create a new Pull Request
79 |
80 | ## Contributors
81 |
82 | - [calebuharrison](https://github.com/calebuharrison) Caleb Uriah Harrison - creator, maintainer
--------------------------------------------------------------------------------
/docs/CrystGLFW/ErrorCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::ErrorCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::ErrorCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
Int32 -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/CrystGLFW/Window/CharCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::Window::CharCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::Window::CharCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
CrystGLFW::Event::WindowChar -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw/windows/window.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/CrystGLFW/Window/CloseCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::Window::CloseCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::Window::CloseCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
CrystGLFW::Event::WindowClose -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw/windows/window.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/CrystGLFW/Window/KeyCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::Window::KeyCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::Window::KeyCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
CrystGLFW::Event::WindowKey -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw/windows/window.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/CrystGLFW/Window/MoveCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::Window::MoveCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::Window::MoveCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
CrystGLFW::Event::WindowMove -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw/windows/window.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/CrystGLFW/Window/RefreshCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::Window::RefreshCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::Window::RefreshCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
CrystGLFW::Event::WindowRefresh -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw/windows/window.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/CrystGLFW/Window/ResizeCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::Window::ResizeCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::Window::ResizeCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
CrystGLFW::Event::WindowResize -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw/windows/window.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/CrystGLFW/Window/ScrollCallback.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | CrystGLFW::Window::ScrollCallback - github.com/calebuharrison/CrystGLFW
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
20 |
21 |
22 |
23 | -
24 | CrystGLFW
25 |
26 |
27 |
28 | -
29 | Error
30 |
31 |
104 |
105 |
106 |
107 |
108 | -
109 | ErrorCallback
110 |
111 |
112 |
113 | -
114 | Event
115 |
116 |
209 |
210 |
211 |
212 |
213 | -
214 | Joystick
215 |
216 |
229 |
230 |
231 |
232 |
233 | -
234 | Key
235 |
236 |
237 |
238 | -
239 | Monitor
240 |
241 |
264 |
265 |
266 |
267 |
268 | -
269 | MouseButton
270 |
271 |
272 |
273 | -
274 | Window
275 |
276 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 | alias CrystGLFW::Window::ScrollCallback
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
Alias Definition
391 |
CrystGLFW::Event::WindowScroll -> Nil
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
Defined in:
405 |
406 |
407 |
crystglfw/windows/window.cr
408 |
409 |
410 |
411 |
412 |
413 |
414 |
415 |
416 |
417 |
418 |
419 |
420 |
421 |
422 |
423 |
424 |
425 |
426 |
427 |
428 |
429 |
430 |
431 |
432 |
433 |
434 |
435 |
436 |
437 |
438 |
439 |
440 |
--------------------------------------------------------------------------------
/docs/css/style.css:
--------------------------------------------------------------------------------
1 | html, body {
2 | position: relative;
3 | margin: 0;
4 | padding: 0;
5 | width: 100%;
6 | height: 100%;
7 | overflow: hidden;
8 | }
9 |
10 | body {
11 | font-family: "Avenir", "Tahoma", "Lucida Sans", "Lucida Grande", Verdana, Arial, sans-serif;
12 | color: #333;
13 | }
14 |
15 | a {
16 | color: #263F6C;
17 | }
18 |
19 | a:visited {
20 | color: #112750;
21 | }
22 |
23 | h1, h2, h3, h4, h5, h6 {
24 | margin: 35px 0 25px;
25 | color: #444444;
26 | }
27 |
28 | h1.type-name {
29 | color: #47266E;
30 | margin: 20px 0 30px;
31 | background-color: #F8F8F8;
32 | padding: 10px 12px;
33 | border: 1px solid #EBEBEB;
34 | border-radius: 2px;
35 | }
36 |
37 | h2 {
38 | border-bottom: 1px solid #E6E6E6;
39 | padding-bottom: 5px;
40 | }
41 |
42 | #types-list, #main-content {
43 | position: absolute;
44 | top: 0;
45 | bottom: 0;
46 | overflow: auto;
47 | }
48 |
49 | #types-list {
50 | left: 0;
51 | width: 20%;
52 | background-color: #2E1052;
53 | padding: 0 0 30px;
54 | box-shadow: inset -3px 0 4px rgba(0,0,0,.35);
55 | }
56 |
57 | #types-list #search-box {
58 | padding: 8px 9px;
59 | }
60 |
61 | #types-list input {
62 | display: block;
63 | box-sizing: border-box;
64 | margin: 0;
65 | padding: 5px;
66 | font: inherit;
67 | font-family: inherit;
68 | line-height: 1.2;
69 | width: 100%;
70 | border: 0;
71 | outline: 0;
72 | border-radius: 2px;
73 | box-shadow: 0px 3px 5px rgba(0,0,0,.25);
74 | transition: box-shadow .12s;
75 | }
76 |
77 | #types-list input:focus {
78 | box-shadow: 0px 5px 6px rgba(0,0,0,.5);
79 | }
80 |
81 | #types-list input::-webkit-input-placeholder { /* Chrome/Opera/Safari */
82 | color: #C8C8C8;
83 | font-size: 14px;
84 | text-indent: 2px;
85 | }
86 |
87 | #types-list input::-moz-placeholder { /* Firefox 19+ */
88 | color: #C8C8C8;
89 | font-size: 14px;
90 | text-indent: 2px;
91 | }
92 |
93 | #types-list input:-ms-input-placeholder { /* IE 10+ */
94 | color: #C8C8C8;
95 | font-size: 14px;
96 | text-indent: 2px;
97 | }
98 |
99 | #types-list input:-moz-placeholder { /* Firefox 18- */
100 | color: #C8C8C8;
101 | font-size: 14px;
102 | text-indent: 2px;
103 | }
104 |
105 | #types-list ul {
106 | margin: 0;
107 | padding: 0;
108 | list-style: none outside;
109 | }
110 |
111 | #types-list li {
112 | display: block;
113 | position: relative;
114 | }
115 |
116 | #types-list li.hide {
117 | display: none;
118 | }
119 |
120 | #types-list a {
121 | display: block;
122 | padding: 5px 15px 5px 30px;
123 | text-decoration: none;
124 | color: #F8F4FD;
125 | transition: color .14s;
126 | }
127 |
128 | #types-list a:focus {
129 | outline: 1px solid #D1B7F1;
130 | }
131 |
132 | #types-list .current > a,
133 | #types-list a:hover {
134 | color: #866BA6;
135 | }
136 |
137 | #types-list li ul {
138 | overflow: hidden;
139 | height: 0;
140 | max-height: 0;
141 | transition: 1s ease-in-out;
142 | }
143 |
144 |
145 | #types-list li.parent {
146 | padding-left: 30px;
147 | }
148 |
149 | #types-list li.parent::before {
150 | box-sizing: border-box;
151 | content: "▼";
152 | display: block;
153 | width: 30px;
154 | height: 30px;
155 | position: absolute;
156 | top: 0;
157 | left: 0;
158 | text-align: center;
159 | color: white;
160 | font-size: 8px;
161 | line-height: 30px;
162 | transform: rotateZ(-90deg);
163 | cursor: pointer;
164 | transition: .2s linear;
165 | }
166 |
167 |
168 | #types-list li.parent > a {
169 | padding-left: 0;
170 | }
171 |
172 | #types-list li.parent.open::before {
173 | transform: rotateZ(0);
174 | }
175 |
176 | #types-list li.open > ul {
177 | height: auto;
178 | max-height: 1000em;
179 | }
180 |
181 | #main-content {
182 | padding: 0 30px 30px 30px;
183 | left: 20%;
184 | right: 0;
185 | }
186 |
187 | .kind {
188 | font-size: 60%;
189 | color: #866BA6;
190 | }
191 |
192 | .superclass-hierarchy {
193 | margin: -15px 0 30px 0;
194 | padding: 0;
195 | list-style: none outside;
196 | font-size: 80%;
197 | }
198 |
199 | .superclass-hierarchy .superclass {
200 | display: inline-block;
201 | margin: 0 7px 0 0;
202 | padding: 0;
203 | }
204 |
205 | .superclass-hierarchy .superclass + .superclass::before {
206 | content: "<";
207 | margin-right: 7px;
208 | }
209 |
210 | .other-types-list li {
211 | display: inline-block;
212 | }
213 |
214 | .other-types-list,
215 | .list-summary {
216 | margin: 0 0 30px 0;
217 | padding: 0;
218 | list-style: none outside;
219 | }
220 |
221 | .entry-const {
222 | font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
223 | }
224 |
225 | .entry-summary {
226 | padding-bottom: 4px;
227 | }
228 |
229 | .superclass-hierarchy .superclass a,
230 | .other-type a,
231 | .entry-summary .signature {
232 | padding: 4px 8px;
233 | margin-bottom: 4px;
234 | display: inline-block;
235 | background-color: #f8f8f8;
236 | color: #47266E;
237 | border: 1px solid #f0f0f0;
238 | text-decoration: none;
239 | border-radius: 3px;
240 | font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
241 | transition: background .15s, border-color .15s;
242 | }
243 |
244 | .superclass-hierarchy .superclass a:hover,
245 | .other-type a:hover,
246 | .entry-summary .signature:hover {
247 | background: #D5CAE3;
248 | border-color: #624288;
249 | }
250 |
251 | .entry-summary .summary {
252 | padding-left: 32px;
253 | }
254 |
255 | .entry-summary .summary p {
256 | margin: 12px 0 16px;
257 | }
258 |
259 | .entry-summary a {
260 | text-decoration: none;
261 | }
262 |
263 | .entry-detail {
264 | padding: 30px 0;
265 | }
266 |
267 | .entry-detail .signature {
268 | position: relative;
269 | padding: 5px 15px;
270 | margin-bottom: 10px;
271 | display: block;
272 | border-radius: 5px;
273 | background-color: #f8f8f8;
274 | color: #47266E;
275 | border: 1px solid #f0f0f0;
276 | font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
277 | transition: .2s ease-in-out;
278 | }
279 |
280 | .entry-detail:target .signature {
281 | background-color: #D5CAE3;
282 | border: 1px solid #624288;
283 | }
284 |
285 | .entry-detail .signature .method-permalink {
286 | position: absolute;
287 | top: 0;
288 | left: -35px;
289 | padding: 5px 15px;
290 | text-decoration: none;
291 | font-weight: bold;
292 | color: #624288;
293 | opacity: .4;
294 | transition: opacity .2s;
295 | }
296 |
297 | .entry-detail .signature .method-permalink:hover {
298 | opacity: 1;
299 | }
300 |
301 | .entry-detail:target .signature .method-permalink {
302 | opacity: 1;
303 | }
304 |
305 | .methods-inherited {
306 | padding-right: 10%;
307 | line-height: 1.5em;
308 | }
309 |
310 | .methods-inherited h3 {
311 | margin-bottom: 4px;
312 | }
313 |
314 | .methods-inherited a {
315 | display: inline-block;
316 | text-decoration: none;
317 | color: #47266E;
318 | }
319 |
320 | .methods-inherited a:hover {
321 | text-decoration: underline;
322 | color: #6C518B;
323 | }
324 |
325 | .methods-inherited .tooltip>span {
326 | background: #D5CAE3;
327 | padding: 4px 8px;
328 | border-radius: 3px;
329 | margin: -4px -8px;
330 | }
331 |
332 | .methods-inherited .tooltip * {
333 | color: #47266E;
334 | }
335 |
336 | pre {
337 | padding: 10px 20px;
338 | margin-top: 4px;
339 | border-radius: 3px;
340 | line-height: 1.45;
341 | overflow: auto;
342 | color: #333;
343 | background: #fdfdfd;
344 | font-size: 14px;
345 | border: 1px solid #eee;
346 | }
347 |
348 | code {
349 | font-family: Consolas, 'Courier New', Courier, Monaco, monospace;
350 | }
351 |
352 | span.flag {
353 | padding: 2px 4px 1px;
354 | border-radius: 3px;
355 | margin-right: 3px;
356 | font-size: 11px;
357 | border: 1px solid transparent;
358 | }
359 |
360 | span.flag.orange {
361 | background-color: #EE8737;
362 | color: #FCEBDD;
363 | border-color: #EB7317;
364 | }
365 |
366 | span.flag.yellow {
367 | background-color: #E4B91C;
368 | color: #FCF8E8;
369 | border-color: #B69115;
370 | }
371 |
372 | span.flag.green {
373 | background-color: #469C14;
374 | color: #E2F9D3;
375 | border-color: #34700E;
376 | }
377 |
378 | span.flag.red {
379 | background-color: #BF1919;
380 | color: #F9ECEC;
381 | border-color: #822C2C;
382 | }
383 |
384 | span.flag.purple {
385 | background-color: #2E1052;
386 | color: #ECE1F9;
387 | border-color: #1F0B37;
388 | }
389 |
390 | .tooltip>span {
391 | position: absolute;
392 | opacity: 0;
393 | display: none;
394 | pointer-events: none;
395 | }
396 |
397 | .tooltip:hover>span {
398 | display: inline-block;
399 | opacity: 1;
400 | }
401 |
402 | .c {
403 | color: #969896;
404 | }
405 |
406 | .n {
407 | color: #0086b3;
408 | }
409 |
410 | .t {
411 | color: #0086b3;
412 | }
413 |
414 | .s {
415 | color: #183691;
416 | }
417 |
418 | .i {
419 | color: #7f5030;
420 | }
421 |
422 | .k {
423 | color: #a71d5d;
424 | }
425 |
426 | .o {
427 | color: #a71d5d;
428 | }
429 |
430 | .m {
431 | color: #795da3;
432 | }
433 |
--------------------------------------------------------------------------------
/docs/js/doc.js:
--------------------------------------------------------------------------------
1 | document.addEventListener('DOMContentLoaded', function() {
2 | var sessionStorage;
3 | try {
4 | sessionStorage = window.sessionStorage;
5 | } catch (e) { }
6 | if(!sessionStorage) {
7 | sessionStorage = {
8 | setItem: function() {},
9 | getItem: function() {},
10 | removeItem: function() {}
11 | };
12 | }
13 |
14 | var repositoryName = document.getElementById('repository-name').getAttribute('content');
15 | var typesList = document.getElementById('types-list');
16 | var searchInput = document.getElementById('search-input');
17 | var parents = document.querySelectorAll('#types-list li.parent');
18 |
19 | for(var i = 0; i < parents.length; i++) {
20 | var _parent = parents[i];
21 | _parent.addEventListener('click', function(e) {
22 | e.stopPropagation();
23 |
24 | if(e.target.tagName.toLowerCase() == 'li') {
25 | if(e.target.className.match(/open/)) {
26 | sessionStorage.removeItem(e.target.getAttribute('data-id'));
27 | e.target.className = e.target.className.replace(/ +open/g, '');
28 | } else {
29 | sessionStorage.setItem(e.target.getAttribute('data-id'), '1');
30 | if(e.target.className.indexOf('open') == -1) {
31 | e.target.className += ' open';
32 | }
33 | }
34 | }
35 | });
36 |
37 | if(sessionStorage.getItem(_parent.getAttribute('data-id')) == '1') {
38 | _parent.className += ' open';
39 | }
40 | };
41 |
42 | var childMatch = function(type, regexp){
43 | var types = type.querySelectorAll("ul li");
44 | for (var j = 0; j < types.length; j ++) {
45 | var t = types[j];
46 | if(regexp.exec(t.getAttribute('data-name'))){ return true; };
47 | };
48 | return false;
49 | };
50 |
51 | var searchTimeout;
52 | var performSearch = function() {
53 | clearTimeout(searchTimeout);
54 | searchTimeout = setTimeout(function() {
55 | var text = searchInput.value;
56 | var types = document.querySelectorAll('#types-list li');
57 | var words = text.toLowerCase().split(/\s+/).filter(function(word) {
58 | return word.length > 0;
59 | });
60 | var regexp = new RegExp(words.join('|'));
61 |
62 | for(var i = 0; i < types.length; i++) {
63 | var type = types[i];
64 | if(words.length == 0 || regexp.exec(type.getAttribute('data-name')) || childMatch(type, regexp)) {
65 | type.className = type.className.replace(/ +hide/g, '');
66 | var is_parent = new RegExp("parent").exec(type.className);
67 | var is_not_opened = !(new RegExp("open").exec(type.className));
68 | if(childMatch(type,regexp) && is_parent && is_not_opened){
69 | type.className += " open";
70 | };
71 | } else {
72 | if(type.className.indexOf('hide') == -1) {
73 | type.className += ' hide';
74 | };
75 | };
76 | if(words.length == 0){
77 | type.className = type.className.replace(/ +open/g, '');
78 | };
79 | }
80 | }, 200);
81 | };
82 | if (searchInput.value.length > 0) {
83 | performSearch();
84 | }
85 | searchInput.addEventListener('keyup', performSearch);
86 | searchInput.addEventListener('input', performSearch);
87 |
88 | typesList.onscroll = function() {
89 | var y = typesList.scrollTop;
90 | sessionStorage.setItem(repositoryName + '::types-list:scrollTop', y);
91 | };
92 |
93 | var initialY = parseInt(sessionStorage.getItem(repositoryName + '::types-list:scrollTop') + "", 10);
94 | if(initialY > 0) {
95 | typesList.scrollTop = initialY;
96 | }
97 |
98 | var scrollToEntryFromLocationHash = function() {
99 | var hash = window.location.hash;
100 | if (hash) {
101 | var targetAnchor = unescape(hash.substr(1));
102 | var targetEl = document.querySelectorAll('.entry-detail[id="' + targetAnchor + '"]');
103 |
104 | if (targetEl && targetEl.length > 0) {
105 | targetEl[0].offsetParent.scrollTop = targetEl[0].offsetTop;
106 | }
107 | }
108 | };
109 | window.addEventListener("hashchange", scrollToEntryFromLocationHash, false);
110 | scrollToEntryFromLocationHash();
111 | });
112 |
--------------------------------------------------------------------------------
/shard.yml:
--------------------------------------------------------------------------------
1 | name: crystglfw
2 | version: 0.3.0
3 |
4 | authors:
5 | - Caleb Uriah Harrison
6 |
7 | dependencies:
8 | lib_glfw:
9 | github: calebuharrison/LibGLFW
10 | branch: master
11 |
12 | crystal: 1.0.0
13 |
14 | license: MIT
15 |
--------------------------------------------------------------------------------
/spec/CrystGLFW_spec.cr:
--------------------------------------------------------------------------------
1 | require "./spec_helper"
2 |
3 | describe CrystGLFW do
4 |
5 | describe "#version" do
6 | it "returns a NamedTuple(major: Int32, minor: Int32, rev: Int32)" do
7 | CrystGLFW.version.should be_a(NamedTuple(major: Int32, minor: Int32, rev: Int32))
8 | end
9 |
10 | it "can be called outside of a run block" do
11 | CrystGLFW.version.should be_a(NamedTuple(major: Int32, minor: Int32, rev: Int32))
12 | end
13 | end
14 |
15 | describe "#version_string" do
16 | it "returns a String" do
17 | CrystGLFW.version_string.should be_a(String)
18 | end
19 |
20 | it "can be called outside of a run block" do
21 | CrystGLFW.version_string.should be_a(String)
22 | end
23 | end
24 |
25 | describe "#time" do
26 | context "when GLFW is initialized" do
27 | it "returns a Float64" do
28 | CrystGLFW.run do
29 | CrystGLFW.time.should be_a(Float64)
30 | end
31 | end
32 | end
33 | context "when GLFW is not initialized" do
34 | it "raises an exception" do
35 | expect_raises(Exception) do
36 | CrystGLFW.time
37 | end
38 | end
39 | end
40 | end
41 |
42 | end
43 |
--------------------------------------------------------------------------------
/spec/spec_helper.cr:
--------------------------------------------------------------------------------
1 | require "spec"
2 | require "../src/CrystGLFW"
3 |
--------------------------------------------------------------------------------
/src/crystglfw.cr:
--------------------------------------------------------------------------------
1 | require "./crystglfw/**"
2 | require "lib_glfw"
3 |
4 | module CrystGLFW
5 | extend self
6 |
7 | DONT_CARE = LibGLFW::DONT_CARE
8 |
9 | alias ErrorCallback = Proc(Int32, Nil)
10 |
11 | @@error_callback = ErrorCallback.new do |error_code|
12 | Error.new(error_code).raise
13 | end
14 |
15 | # Sets the error callback that is called when an error occurs in LibGLFW.
16 | #
17 | # When an error occurs in LibGLFW, an error code is yielded to the block
18 | # defined by this method. The error code identifies the type of error that
19 | # occurred and can be validated by checking it against the constants defined
20 | # in CrystGLFW:
21 | #
22 | # ```
23 | # CrystGLFW.on_error do |error_code|
24 | # case error_code
25 | # when CrystGLFW[:not_initialized]
26 | # puts "CrystGLFW has not been initialized."
27 | # when CrystGLFW[:invalid_enum]
28 | # puts "An invalid enum was passed to CrystGLFW."
29 | # else
30 | # puts "An error occurred"
31 | # end
32 | # end
33 | # ```
34 | #
35 | # NOTE: This method may be called outside a `#run` block definition without
36 | # triggering an error.
37 | # NOTE: Defining custom behavior will bypass the `Error` module entirely. It
38 | # is recommended that this method not be used.
39 | def self.on_error(&callback : ErrorCallback)
40 | @@error_callback = callback
41 | end
42 |
43 | # Sets up GLFW to execute the block and terminates GLFW afterwards.
44 | #
45 | # ```
46 | # include CrystGLFW
47 | #
48 | # CrystGLFW.run do
49 | # window = Window.new(title: "My Window")
50 | # until window.should_close?
51 | # window.wait_events
52 | # window.swap_buffers
53 | # end
54 | # end
55 | # ```
56 | #
57 | # With few exceptions, all CrystGLFW methods must be called within the block
58 | # passed to this method. This method initializes the underlying GLFW library
59 | # for use and cleans up the library after the block has returned.
60 | def self.run(&block)
61 | LibGLFW.init
62 | yield
63 | LibGLFW.terminate
64 | end
65 |
66 | # Returns the major, minor, and revision version numbers of GLFW.
67 | #
68 | # ```
69 | # CrystGLFW.version # => {major: 3, minor: 2, rev: 1}
70 | # ```
71 | #
72 | # NOTE: This method may be called outside a `#run` block definition without
73 | # triggering an error.
74 | def self.version : NamedTuple(major: Int32, minor: Int32, rev: Int32)
75 | LibGLFW.get_version(out major, out minor, out rev)
76 | { major: major, minor: minor, rev: rev }
77 | end
78 |
79 | # Returns the compile-time generated version string of GLFW.
80 | #
81 | # ```
82 | # CrystGLFW.version_string # => "3.2.1 Cocoa NSGL chdir menubar retina dynamic"
83 | # ```
84 | #
85 | # NOTE: This method may be called outside a `#run` block definition without
86 | # triggering an error.
87 | def self.version_string : String
88 | String.new(LibGLFW.get_version_string)
89 | end
90 |
91 | # Returns the current value, in seconds, of the GLFW timer.
92 | #
93 | # ```
94 | # CrystGLFW.time # => 0.13899576
95 | # ```
96 | #
97 | # NOTE: This method must be called inside a `#run` block definition.
98 | def self.time : Float64
99 | LibGLFW.get_time
100 | end
101 |
102 | # Sets the GLFW timer to a new time, in seconds.
103 | #
104 | # This method accepts the following arguments:
105 | # - *t*, the new time.
106 | #
107 | # ```
108 | # CrystGLFW.set_time 1.0
109 | # CrystGLFW.time # => 1.0
110 | # ```
111 | #
112 | # NOTE: This method must be called inside a `#run` block definition.
113 | def self.set_time(t : Number)
114 | LibGLFW.set_time t
115 | end
116 |
117 | # Alternate syntax for `#set_time`.
118 | #
119 | # This method accepts the following arguments:
120 | # - *t*, the new time.
121 | #
122 | # ```
123 | # CrystGLFW.time = 1.0
124 | # CrystGLFW.time # => 1.0
125 | # ```
126 | #
127 | # NOTE: This method must be called from within a `#run` block definition.
128 | def self.time=(t : Number)
129 | self.set_time t
130 | end
131 |
132 | # Returns the current value of the raw timer, measured in 1 / `#timer_frequency` seconds.
133 | #
134 | # ```
135 | # CrystGLFW.timer_value # => 754_104_002_009_408
136 | # ```
137 | #
138 | # NOTE: This method must be called inside a `#run` block definition.
139 | def self.timer_value : UInt64
140 | LibGLFW.get_timer_value
141 | end
142 |
143 | # Returns the frequency, in Hz, of the raw timer.
144 | #
145 | # ```
146 | # CrystGLFW.timer_frequency # => 1_000_000_000
147 | # ```
148 | #
149 | # NOTE: This method must be called inside a `#run` block definition.
150 | def self.timer_frequency : UInt64
151 | LibGLFW.get_timer_frequency
152 | end
153 |
154 | # Processes all events in the event queue and then returns immediately.
155 | #
156 | # ```
157 | # include CrystGLFW
158 | #
159 | # CrystGLFW.run do
160 | # window = Window.new
161 | # until window.should_close?
162 | # CrystGLFW.poll_events # Process all events, even if queue is empty.
163 | # window.swap_buffers
164 | # end
165 | # end
166 | # ```
167 | #
168 | # NOTE: This method must be called inside a `#run` block definition.
169 | # NOTE: This method must not be called from within a callback.
170 | def self.poll_events
171 | LibGLFW.poll_events
172 | end
173 |
174 | # Puts the calling thread to sleep until at least one event is queued.
175 | #
176 | # ```
177 | # include CrystGLFW
178 | #
179 | # CrystGLFW.run do
180 | # window = Window.new
181 | # until window.should_close?
182 | # CrystGLFW.wait_events # Wait for events to queue, then process them.
183 | # window.swap_buffers
184 | # end
185 | # end
186 | #
187 | # NOTE: This method must be called inside a `#run` block definition.
188 | # NOTE: This method must not be called from within a callback.
189 | def self.wait_events
190 | LibGLFW.wait_events
191 | end
192 |
193 | # Puts the calling thread to sleep until at least one event is queued or the specified timeout is reached.
194 | #
195 | # ```
196 | # include CrystGLFW
197 | #
198 | # CrystGLFW.run do
199 | # window = Window.new
200 | # until window.should_close?
201 | # CrystGLFW.wait_events(1.5)
202 | # window.swap_buffers
203 | # end
204 | # end
205 | #
206 | # This method accepts the following arguments:
207 | # - *timeout*, the maximum amount of time, in seconds, to wait.
208 | #
209 | # NOTE: This method must be called inside a `#run` block definition.
210 | # NOTE: This method must not be called from within a callback.
211 | def self.wait_events(timeout : Number)
212 | LibGLFW.wait_events_timeout(timeout)
213 | end
214 |
215 | # Posts an empty event to the event queue, forcing `#wait_events` to return.
216 | #
217 | # ```
218 | # CrystGLFW.post_empty_event
219 | # ```
220 | #
221 | # NOTE: This method must be called inside a `#run` block definition.
222 | def self.post_empty_event
223 | LibGLFW.post_empty_event
224 | end
225 |
226 | # Sets the immutable error callback shim.
227 | private def self.set_error_callback
228 | callback = LibGLFW::Errorfun.new do |error_code, description|
229 | @@error_callback.call error_code
230 | end
231 | LibGLFW.set_error_callback callback
232 | end
233 |
234 | set_error_callback
235 | end
--------------------------------------------------------------------------------
/src/crystglfw/action.cr:
--------------------------------------------------------------------------------
1 | require "lib_glfw"
2 |
3 | module CrystGLFW
4 | enum Action
5 | Press = LibGLFW::PRESS
6 | Release = LibGLFW::RELEASE
7 | Repeat = LibGLFW::REPEAT
8 | end
9 | end
--------------------------------------------------------------------------------
/src/crystglfw/client_api.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum ClientAPI
3 | OpenGL = LibGLFW::OPENGL_API
4 | OpenGLES = LibGLFW::OPENGL_ES_API
5 | None = LibGLFW::NO_API
6 | end
7 | end
--------------------------------------------------------------------------------
/src/crystglfw/connection_status.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum ConnectionStatus
3 | Connected = LibGLFW::CONNECTED
4 | Disconnected = LibGLFW::DISCONNECTED
5 | end
6 | end
--------------------------------------------------------------------------------
/src/crystglfw/context_api.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum ContextAPI
3 | Native = LibGLFW::NATIVE_CONTEXT_API
4 | EGL = LibGLFW::EGL_CONTEXT_API
5 | end
6 | end
--------------------------------------------------------------------------------
/src/crystglfw/context_robustness.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum ContextRobustness
3 | None = LibGLFW::NO_ROBUSTNESS
4 | NoResetNotification = LibGLFW::NO_RESET_NOTIFICATION
5 | LoseContextOnReset = LibGLFW::LOSE_CONTEXT_ON_RESET
6 | end
7 | end
--------------------------------------------------------------------------------
/src/crystglfw/error.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum Error
3 | NotInitialized = LibGLFW::NOT_INITIALIZED
4 | NoCurrentContext = LibGLFW::NO_CURRENT_CONTEXT
5 | InvalidEnum = LibGLFW::INVALID_ENUM
6 | InvalidValue = LibGLFW::INVALID_VALUE
7 | OutOfMemory = LibGLFW::OUT_OF_MEMORY
8 | APIUnavailable = LibGLFW::API_UNAVAILABLE
9 | VersionUnavailable = LibGLFW::VERSION_UNAVAILABLE
10 | PlatformError = LibGLFW::PLATFORM_ERROR
11 | FormatUnavailable = LibGLFW::FORMAT_UNAVAILABLE
12 | NoWindowContext = LibGLFW::NO_WINDOW_CONTEXT
13 | NotFullScreen
14 | KeyNotPrintable
15 | JoystickNotConnected
16 |
17 | def raise
18 | raise "CrystGLFW Error: " + self.to_s
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/src/crystglfw/events/any.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Event::Any is the abstract superclass of the different CrystGLFW events.
4 | abstract struct Any
5 | end
6 | end
7 | end
8 |
--------------------------------------------------------------------------------
/src/crystglfw/events/event.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | # The Event module encapsulates the handful of GLFW callback events and provides an interface for them.
3 | module Event
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/src/crystglfw/events/joystick_toggle_connection.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a joystick is either connected or disconnected from the system.
4 | struct JoystickToggleConnection < Any
5 | getter joystick : Joystick
6 |
7 | # :nodoc:
8 | def initialize(joystick : Joystick, connection_status : ConnectionStatus)
9 | @joystick = joystick
10 | @connection_status = connection_status
11 | end
12 |
13 | def connected?
14 | @connection_status.connected?
15 | end
16 | end
17 | end
18 | end
--------------------------------------------------------------------------------
/src/crystglfw/events/modifiers.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # The Modifiers module encapsulates the instance variables and interfaces for Events that support modifier keys.
4 | module Modifiers
5 | @mod_shift : Bool = false
6 | @mod_control : Bool = false
7 | @mod_alt : Bool = false
8 | @mod_super : Bool = false
9 |
10 | private def set_modifiers(modifiers : Int32)
11 | @mod_shift = modifiers.bit(0) == 1
12 | @mod_control = modifiers.bit(1) == 1
13 | @mod_alt = modifiers.bit(2) == 1
14 | @mod_super = modifiers.bit(3) == 1
15 | end
16 |
17 | # Returns true if the shift key was held down as a modifier. False otherwise.
18 | #
19 | # ```
20 | # window.on_key do |key_event|
21 | # puts "The shift key was held down as a modifier." if key_event.shift?
22 | # end
23 | # ```
24 | def shift?
25 | @mod_shift
26 | end
27 |
28 | # Returns true if the control key was held down as a modifier. False otherwise.
29 | #
30 | # ```
31 | # window.on_key do |key_event|
32 | # puts "The control key was held down as a modifier." if key_event.control?
33 | # end
34 | # ```
35 | def control?
36 | @mod_control
37 | end
38 |
39 | # Returns true if the alt key was held down as a modifier. False otherwise.
40 | #
41 | # ```
42 | # window.on_key do |key_event|
43 | # puts "The alt key was held down as a modifier." if key_event.alt?
44 | # end
45 | # ```
46 | def alt?
47 | @mod_alt
48 | end
49 |
50 | # Returns true if the super key was held down as a modifier. False otherwise.
51 | #
52 | # ```
53 | # window.on_key do |key_event|
54 | # puts "The super key was held down as a modifier." if key_event.super?
55 | # end
56 | # ```
57 | def super?
58 | @mod_super
59 | end
60 | end
61 | end
62 | end
63 |
--------------------------------------------------------------------------------
/src/crystglfw/events/monitor_toggle_connection.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a monitor is either connected or disconnected from the system.
4 | struct MonitorToggleConnection < Any
5 | getter monitor : Monitor
6 |
7 | # :nodoc:
8 | def initialize(@monitor : Monitor, @connection_status : ConnectionStatus)
9 | end
10 |
11 | def connected?
12 | @connection_status.connected?
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_char.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # A WindowCharEvent represents a user-input unicode character along with the modifier keys that were held during its input.
4 | #
5 | # ```
6 | # window = CrystGLFW::Window.new
7 | # window.on_char do |char_event|
8 | # puts char_event.char if char_event.shift? # Prints the char if the shift key is held down.
9 | # end
10 | # ```
11 | #
12 | # WindowCharEvents are generated by `Window#on_char` and are not intended to be
13 | # created in any other context. As such, CharEvents should be used when
14 | # generated by the callback, but should never be created.
15 | struct WindowChar < Any
16 | include Modifiers
17 |
18 | getter window : Window
19 | getter char : Char
20 |
21 | # :nodoc:
22 | def initialize(window : Window, char : Char, modifiers : Int32)
23 | @window = window
24 | @char = char
25 | set_modifiers modifiers
26 | end
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_close.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window is closed.
4 | struct WindowClose < Any
5 | getter window : Window
6 |
7 | # :nodoc:
8 | def initialize(window : Window)
9 | @window = window
10 | end
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_cursor_cross_threshold.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window's cursor crosses the threshold of the window.
4 | struct WindowCursorCrossThreshold < Any
5 | getter window : Window
6 | getter cursor : Window::Cursor
7 |
8 | # :nodoc:
9 | def initialize(@window : Window, @cursor : Window::Cursor, @entered : Bool)
10 | end
11 |
12 | def entered?
13 | @entered
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_cursor_move.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window's cursor is moved to a new location.
4 | struct WindowCursorMove < Any
5 | getter window : Window
6 | getter cursor : Window::Cursor
7 |
8 | # :nodoc:
9 | def initialize(@window : Window, @cursor : Window::Cursor, @x : Float64, @y : Float64)
10 | end
11 |
12 | def position : NamedTuple(x: Float64, y: Float64)
13 | { x: @x, y: @y }
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_file_drop.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein one or more files are drag-and-dropped onto the window.
4 | struct WindowFileDrop < Any
5 | getter window : Window
6 | getter paths : Array(String)
7 |
8 | # :nodoc:
9 | def initialize(window : Window, paths : Array(String))
10 | @window = window
11 | @paths = paths
12 | end
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_framebuffer_resize.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window's framebuffer is resized.
4 | struct WindowFramebufferResize < Any
5 | getter window : CrystGLFW::Window
6 |
7 | # :nodoc:
8 | def initialize(@window : Window, @width : Int32, @height : Int32)
9 | end
10 |
11 | def size : NamedTuple(width: Int32, height: Int32)
12 | { width: @width, height: @height }
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_key.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # A WindowKeyEvent is generated by the `Window#on_key` callback and contains a `Key` along with
4 | # an interface to determine what action occurred with the key.
5 | struct WindowKey < Any
6 | include Modifiers
7 |
8 | getter window : Window
9 | getter key : Key
10 | getter action : Action
11 |
12 | # :nodoc:
13 | def initialize(window : Window, key : Key, action : Action, modifiers : Int32)
14 | @window = window
15 | @key = key
16 | @action = action
17 | set_modifiers modifiers
18 | end
19 |
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_mouse_button.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # A WindowMouseButtonEvent is generated by the `Window#on_mouse_button` callback and contains a `MouseButton` along with
4 | # an interface to determine what action occurred with the key.
5 | struct WindowMouseButton < Any
6 | include Modifiers
7 |
8 | getter window : Window
9 | getter mouse_button : MouseButton
10 | getter action : Action
11 |
12 | # :nodoc:
13 | def initialize(window : Window, mouse_button : MouseButton, action : Action, modifiers : Int32)
14 | @window = window
15 | @mouse_button = mouse_button
16 | @action = action
17 | set_modifiers modifiers
18 | end
19 |
20 | end
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_move.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window is moved to a new location.
4 | struct WindowMove < Any
5 | getter window : Window
6 |
7 | # :nodoc:
8 | def initialize(@window : Window, @x : Int32, @y : Int32)
9 | end
10 |
11 | def position : NamedTuple(x: Int32, y: Int32)
12 | { x: @x, y: @y }
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_refresh.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window is refreshed.
4 | struct WindowRefresh < Any
5 | getter window : Window
6 |
7 | # :nodoc:
8 | def initialize(window : Window)
9 | @window = window
10 | end
11 | end
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_resize.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window is resized.
4 | struct WindowResize < Any
5 | getter window : Window
6 |
7 | # :nodoc:
8 | def initialize(@window : Window, @width : Int32, @height : Int32)
9 | end
10 |
11 | def size : NamedTuple(width: Int32, height: Int32)
12 | { width: @width, height: @height }
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_scroll.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window receives scroll input.
4 | struct WindowScroll < Any
5 | getter window : Window
6 |
7 | # :nodoc:
8 | def initialize(@window : Window, @x : Float64, @y : Float64)
9 | end
10 |
11 | def offset : NamedTuple(x: Float64, y: Float64)
12 | { x: @x, y: @y }
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_toggle_focus.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window's focus is toggled on or off.
4 | struct WindowToggleFocus < Any
5 | getter window : Window
6 |
7 | # :nodoc:
8 | def initialize(@window : Window, @focused : Bool)
9 | end
10 |
11 | def focused?
12 | @focused
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/events/window_toggle_iconification.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | module Event
3 | # Represents an event wherein a window's iconification is toggled on or off.
4 | struct WindowToggleIconification < Any
5 | getter window : Window
6 |
7 | # :nodoc:
8 | def initialize(@window : Window, @iconified : Bool)
9 | end
10 |
11 | def iconified?
12 | @iconified
13 | end
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/joystick.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 |
3 | enum Joystick
4 | One = LibGLFW::JOYSTICK_1
5 | Two = LibGLFW::JOYSTICK_2
6 | Three = LibGLFW::JOYSTICK_3
7 | Four = LibGLFW::JOYSTICK_4
8 | Five = LibGLFW::JOYSTICK_5
9 | Six = LibGLFW::JOYSTICK_6
10 | Seven = LibGLFW::JOYSTICK_7
11 | Eight = LibGLFW::JOYSTICK_8
12 | Nine = LibGLFW::JOYSTICK_9
13 | Ten = LibGLFW::JOYSTICK_10
14 | Eleven = LibGLFW::JOYSTICK_11
15 | Twelve = LibGLFW::JOYSTICK_12
16 | Thirteen = LibGLFW::JOYSTICK_13
17 | Fourteen = LibGLFW::JOYSTICK_14
18 | Fifteen = LibGLFW::JOYSTICK_15
19 | Sixteen = LibGLFW::JOYSTICK_16
20 | Last = LibGLFW::JOYSTICK_LAST
21 |
22 | def self.on_toggle_connection(&callback : Proc(Event::JoystickToggleConnection, Nil))
23 | @@callback = callback
24 | end
25 |
26 | protected def self.set_joystick_callback
27 | callback = LibGLFW::Joystickfun.new do |code, connection_code|
28 | joystick = Joystick.new(code)
29 | connection_status = ConnectionStatus.new(connection_code)
30 | event = Event::JoystickToggleConnection.new(joystick, connection_status)
31 | @@callback.try &.call(event)
32 | end
33 | end
34 |
35 | def name : String
36 | candidate = LibGLFW.get_joystick_name(@code)
37 | if candidate.null?
38 | Error::JoystickNotConnected.raise
39 | else
40 | String.new(candidate)
41 | end
42 | end
43 |
44 | def connected? : Bool
45 | LibGLFW.joystick_present(self) == 1
46 | end
47 |
48 | def buttons : Array(Bool)
49 | btns = LibGLFW.get_joystick_buttons(self, out count)
50 | Slice.new(btns, count).map { |b| Action.new(b).press? }
51 | end
52 |
53 | def axes : Slice(Float32)
54 | ptr = LibGLFW.get_joystick_axes(self, out count)
55 | Slice.new(ptr, count)
56 | end
57 |
58 | end
59 |
60 | Joystick.set_joystick_callback
61 | end
62 |
--------------------------------------------------------------------------------
/src/crystglfw/key.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum Key
3 | Unknown = LibGLFW::KEY_UNKNOWN
4 | Space = LibGLFW::KEY_SPACE
5 | Apostrophe = LibGLFW::KEY_APOSTROPHE
6 | Comma = LibGLFW::KEY_COMMA
7 | Minus = LibGLFW::KEY_MINUS
8 | Period = LibGLFW::KEY_PERIOD
9 | Slash = LibGLFW::KEY_SLASH
10 | Zero = LibGLFW::KEY_0
11 | One = LibGLFW::KEY_1
12 | Two = LibGLFW::KEY_2
13 | Three = LibGLFW::KEY_3
14 | Four = LibGLFW::KEY_4
15 | Five = LibGLFW::KEY_5
16 | Six = LibGLFW::KEY_6
17 | Seven = LibGLFW::KEY_7
18 | Eight = LibGLFW::KEY_8
19 | Nine = LibGLFW::KEY_9
20 | Semicolon = LibGLFW::KEY_SEMICOLON
21 | Equal = LibGLFW::KEY_EQUAL
22 | A = LibGLFW::KEY_A
23 | B = LibGLFW::KEY_B
24 | C = LibGLFW::KEY_C
25 | D = LibGLFW::KEY_D
26 | E = LibGLFW::KEY_E
27 | F = LibGLFW::KEY_F
28 | G = LibGLFW::KEY_G
29 | H = LibGLFW::KEY_H
30 | I = LibGLFW::KEY_I
31 | J = LibGLFW::KEY_J
32 | K = LibGLFW::KEY_K
33 | L = LibGLFW::KEY_L
34 | M = LibGLFW::KEY_M
35 | N = LibGLFW::KEY_N
36 | O = LibGLFW::KEY_O
37 | P = LibGLFW::KEY_P
38 | Q = LibGLFW::KEY_Q
39 | R = LibGLFW::KEY_R
40 | S = LibGLFW::KEY_S
41 | T = LibGLFW::KEY_T
42 | U = LibGLFW::KEY_U
43 | V = LibGLFW::KEY_V
44 | W = LibGLFW::KEY_W
45 | X = LibGLFW::KEY_X
46 | Y = LibGLFW::KEY_Y
47 | Z = LibGLFW::KEY_Z
48 | LeftBracket = LibGLFW::KEY_LEFT_BRACKET
49 | Backslash = LibGLFW::KEY_BACKSLASH
50 | RightBracket = LibGLFW::KEY_RIGHT_BRACKET
51 | GraveAccent = LibGLFW::KEY_GRAVE_ACCENT
52 | World1 = LibGLFW::KEY_WORLD_1
53 | World2 = LibGLFW::KEY_WORLD_2
54 | Escape = LibGLFW::KEY_ESCAPE
55 | Enter = LibGLFW::KEY_ENTER
56 | Tab = LibGLFW::KEY_TAB
57 | Backspace = LibGLFW::KEY_BACKSPACE
58 | Insert = LibGLFW::KEY_INSERT
59 | Delete = LibGLFW::KEY_DELETE
60 | Right = LibGLFW::KEY_RIGHT
61 | Left = LibGLFW::KEY_LEFT
62 | Down = LibGLFW::KEY_DOWN
63 | Up = LibGLFW::KEY_UP
64 | PageUp = LibGLFW::KEY_PAGE_UP
65 | PageDown = LibGLFW::KEY_PAGE_DOWN
66 | Home = LibGLFW::KEY_HOME
67 | End = LibGLFW::KEY_END
68 | CapsLock = LibGLFW::KEY_CAPS_LOCK
69 | ScrollLock = LibGLFW::KEY_SCROLL_LOCK
70 | NumLock = LibGLFW::KEY_NUM_LOCK
71 | PrintScreen = LibGLFW::KEY_PRINT_SCREEN
72 | Pause = LibGLFW::KEY_PAUSE
73 | F1 = LibGLFW::KEY_F1
74 | F2 = LibGLFW::KEY_F2
75 | F3 = LibGLFW::KEY_F3
76 | F4 = LibGLFW::KEY_F4
77 | F5 = LibGLFW::KEY_F5
78 | F6 = LibGLFW::KEY_F6
79 | F7 = LibGLFW::KEY_F7
80 | F8 = LibGLFW::KEY_F8
81 | F9 = LibGLFW::KEY_F9
82 | F10 = LibGLFW::KEY_F10
83 | F11 = LibGLFW::KEY_F11
84 | F12 = LibGLFW::KEY_F12
85 | F13 = LibGLFW::KEY_F13
86 | F14 = LibGLFW::KEY_F14
87 | F15 = LibGLFW::KEY_F15
88 | F16 = LibGLFW::KEY_F16
89 | F17 = LibGLFW::KEY_F17
90 | F18 = LibGLFW::KEY_F18
91 | F19 = LibGLFW::KEY_F19
92 | F20 = LibGLFW::KEY_F20
93 | F21 = LibGLFW::KEY_F21
94 | F22 = LibGLFW::KEY_F22
95 | F23 = LibGLFW::KEY_F23
96 | F24 = LibGLFW::KEY_F24
97 | F25 = LibGLFW::KEY_F25
98 | KP0 = LibGLFW::KEY_KP_0
99 | KP1 = LibGLFW::KEY_KP_1
100 | KP2 = LibGLFW::KEY_KP_2
101 | KP3 = LibGLFW::KEY_KP_3
102 | KP4 = LibGLFW::KEY_KP_4
103 | KP5 = LibGLFW::KEY_KP_5
104 | KP6 = LibGLFW::KEY_KP_6
105 | KP7 = LibGLFW::KEY_KP_7
106 | KP8 = LibGLFW::KEY_KP_8
107 | KP9 = LibGLFW::KEY_KP_9
108 | KPDecimal = LibGLFW::KEY_KP_DECIMAL
109 | KPDivide = LibGLFW::KEY_KP_DIVIDE
110 | KPMultiply = LibGLFW::KEY_KP_MULTIPLY
111 | KPSubtract = LibGLFW::KEY_KP_SUBTRACT
112 | KPAdd = LibGLFW::KEY_KP_ADD
113 | KPEnter = LibGLFW::KEY_KP_ENTER
114 | KPEqual = LibGLFW::KEY_KP_EQUAL
115 | LeftShift = LibGLFW::KEY_LEFT_SHIFT
116 | LeftControl = LibGLFW::KEY_LEFT_CONTROL
117 | LeftAlt = LibGLFW::KEY_LEFT_ALT
118 | LeftSuper = LibGLFW::KEY_LEFT_SUPER
119 | RightShift = LibGLFW::KEY_RIGHT_SHIFT
120 | RightControl = LibGLFW::KEY_RIGHT_CONTROL
121 | RightAlt = LibGLFW::KEY_RIGHT_ALT
122 | RightSuper = LibGLFW::KEY_RIGHT_SUPER
123 | Menu = LibGLFW::KEY_MENU
124 | Last = LibGLFW::KEY_LAST
125 | ModShift = LibGLFW::MOD_SHIFT
126 | ModAlt = LibGLFW::MOD_ALT
127 | ModControl = LibGLFW::MOD_CONTROL
128 | ModSuper = LibGLFW::MOD_SUPER
129 |
130 | @@printable_keys = [
131 | Apostrophe, Comma, Minus, Period, Slash, Semicolon, Equal,
132 | LeftBracket, RightBracket, Backslash, World1, World2,
133 | Zero, One, Two, Three, Four, Five, Six, Seven, Eight, Nine,
134 | A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T,
135 | U, V, W, X, Y, Z, KP0, KP1, KP2, KP3, KP4, KP5, KP6, KP7,
136 | KP8, KP9, KPDecimal, KPDivide, KPMultiply, KPSubtract, KPAdd,
137 | KPEqual
138 | ]
139 |
140 | @@scancodes = Hash(Key, Int32).new
141 |
142 | def self.from(code : Int32, scancode : Int32) : Key
143 | Key.new(code).tap { |k| @@scancodes[k] = scancode }
144 | end
145 |
146 | def name : String
147 | return "invalid-key" unless scancode = @@scancodes[self]?
148 | candidate = LibGLFW.get_key_name(self.value, scancode)
149 | if candidate.null?
150 | Error::KeyNotPrintable.raise
151 | else
152 | String.new(candidate)
153 | end
154 | end
155 |
156 | def printable? : Bool
157 | @@printable_keys.includes? self
158 | end
159 | end
160 | end
161 |
--------------------------------------------------------------------------------
/src/crystglfw/monitors/gamma_ramp.cr:
--------------------------------------------------------------------------------
1 | require "lib_glfw"
2 |
3 | module CrystGLFW
4 | struct Monitor
5 | # A GammaRamp object wraps an underlying GLFW Gammaramp and exposes its attributes.
6 | struct GammaRamp
7 | # :nodoc:
8 | def initialize(handle : Pointer(LibGLFW::Gammaramp))
9 | @handle = handle
10 | end
11 |
12 | # Returns a slice of values that describes the response of the red channel.
13 | #
14 | # ```
15 | # monitor = Monitor.primary
16 | # gamma_ramp = monitor.gamma_ramp
17 | # gamma_ramp.red
18 | # ```
19 | def red : Slice(UInt16)
20 | Slice.new(gamma_ramp.red, size)
21 | end
22 |
23 | # Returns an array of values that describes the resposne of the green channel.
24 | #
25 | # ```
26 | # monitor = Monitor.primary
27 | # gamma_ramp = monitor.gamma_ramp
28 | # gamma_ramp.green
29 | # ```
30 | def green : Slice(UInt16)
31 | Slice.new(gamma_ramp.green, size)
32 | end
33 |
34 | # Returns an array of values that describes the response of the blue channel.
35 | #
36 | # ```
37 | # monitor = Monitor.primary
38 | # gamma_ramp = monitor.gamma_ramp
39 | # gamma_ramp.blue
40 | # ```
41 | def blue : Slice(UInt16)
42 | Slice.new(gamma_ramp.blue, size)
43 | end
44 |
45 | # Returns the number of elements in each color array.
46 | #
47 | # ```
48 | # monitor = Monitor.primary
49 | # gamma_ramp = monitor.gamma_ramp
50 | # gamma_ramp.size
51 | # ```
52 | def size : UInt32
53 | gamma_ramp.size
54 | end
55 |
56 | # :nodoc:
57 | def ==(other : GammaRamp)
58 | @handle == other.to_unsafe
59 | end
60 |
61 | # :nodoc:
62 | def to_unsafe
63 | @handle
64 | end
65 |
66 | # Dereferences the underlying Gammaramp pointer.
67 | private def gamma_ramp
68 | @handle.value
69 | end
70 | end
71 | end
72 | end
73 |
--------------------------------------------------------------------------------
/src/crystglfw/monitors/monitor.cr:
--------------------------------------------------------------------------------
1 | require "lib_glfw"
2 |
3 | module CrystGLFW
4 | # A Monitor represents a physical monitor connected to the system.
5 | struct Monitor
6 | alias ToggleConnectionCallback = Proc(Event::MonitorToggleConnection, Nil)
7 | alias MonitorCallback = ToggleConnectionCallback | Nil
8 |
9 | @@monitor_callback : MonitorCallback
10 |
11 | # Sets the immutable monitor connection callback shim.
12 | private def self.set_toggle_connection_callback
13 | callback = LibGLFW::Monitorfun.new do |handle, connection_code|
14 | monitor = new(handle)
15 | connection_status = ConnectionStatus.new(connection_code)
16 | event = Event::MonitorToggleConnection.new(monitor, connection_status)
17 | @@monitor_callback.try &.call(event)
18 | end
19 | LibGLFW.set_monitor_callback callback
20 | end
21 |
22 | # Defines the behavior that gets triggered when a monitor is either connected or disconnected.
23 | #
24 | # ```
25 | # monitor = CrystGLFW::Monitor.primary
26 | # monitor.on_toggle_connection do |event|
27 | # if event.connected?
28 | # puts "Welcome back, #{event.monitor.name}!"
29 | # else
30 | # puts "Farewell, #{event.monitor.name}."
31 | # end
32 | # end
33 | # ```
34 | def self.on_toggle_connection(&callback : ToggleConnectionCallback)
35 | @@monitor_callback = callback
36 | end
37 |
38 | # Returns all monitors currently connected to the system as an Array.
39 | #
40 | # ```
41 | # monitors = CrystGLFW::Monitor.all
42 | # monitors.each { |m| puts m.name } # Prints out the name of each connected monitor.
43 | # ```
44 | #
45 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
46 | def self.all : Array(Monitor)
47 | handles = LibGLFW.get_monitors(out count)
48 | count.times.map { |i| Monitor.new(handles[i]) }
49 | end
50 |
51 | # Returns the primary monitor, which is inferred by GLFW as the window that includes the task bar.
52 | #
53 | # ```
54 | # monitor = CrystGLFW::Monitor.primary
55 | # puts "Monitor #{monitor.name} is the primary monitor."
56 | # ```
57 | #
58 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
59 | def self.primary : Monitor
60 | new(LibGLFW.get_primary_monitor)
61 | end
62 |
63 | private def initialize(handle : Pointer(LibGLFW::Monitor))
64 | @handle = handle
65 | end
66 |
67 | # Returns the position of the upper-left corner of the monitor in screen coordinates relative to the virtual screen.
68 | #
69 | # ```
70 | # # Retrieve all monitors.
71 | # monitors = CrystGLFW::Monitors.all
72 | #
73 | # # Find the monitor that is furthest to the left.
74 | # leftmost_monitor = monitors.min_by { |monitor| monitor.position[:x] }
75 | # ```
76 | #
77 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
78 | def position : NamedTuple(x: Int32, y: Int32)
79 | LibGLFW.get_monitor_pos(@handle, out x, out y)
80 | { x: x, y: y }
81 | end
82 |
83 | # Returns the physical size of the monitor in millimeters.
84 | #
85 | # ```
86 | # # Retrieve the primary monitor.
87 | # monitor = CrystGLFW::Monitor.primary
88 | #
89 | # # Calculate the area of the monitor using its physical size.
90 | # monitor_area = monitor.physical_size[:width] * monitor.physical_size[:height]
91 | #
92 | # # Print the area of the monitor in millimeters.
93 | # puts "The area of the monitor is #{monitor_area} millimeters squared."
94 | # ```
95 | #
96 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
97 | def physical_size : NamedTuple(width: Int32, height: Int32)
98 | LibGLFW.get_monitor_physical_size(@handle, out width, out height)
99 | { width: width, height: height }
100 | end
101 |
102 | # Returns the monitor's name, as set by the manufacturer.
103 | #
104 | # ```
105 | # # Retrieve the primary monitor.
106 | # monitor = CrystGLFW::Monitor.primary
107 | #
108 | # # Print out the name of the monitor.
109 | # puts "The name of the primary monitor is #{monitor.name}"
110 | # ```
111 | #
112 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
113 | def name : String
114 | String.new LibGLFW.get_monitor_name(@handle)
115 | end
116 |
117 | # Returns the monitor's supported video modes.
118 | #
119 | # TODO: Add an example here.
120 | #
121 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
122 | def video_modes : Array(VideoMode)
123 | vid_modes = LibGLFW.get_video_modes(@handle, out count)
124 | count.times.map { |i| VideoMode.new(vid_modes + i) }
125 | end
126 |
127 | # Returns the monitor's current video mode.
128 | #
129 | # ```
130 | # # Retrieve the primary monitor.
131 | # monitor = CrystGLFW::Monitor.primary
132 | #
133 | # current_video_mode = monitor.video_mode
134 | # ```
135 | #
136 | # TODO: Improve this example with something useful.
137 | #
138 | # NOTE: This method must be called inside a `CrystGLFW#run` block definition.
139 | def video_mode : VideoMode
140 | VideoMode.new LibGLFW.get_video_mode(@handle)
141 | end
142 |
143 | # Generates a gamma ramp from the given exponent and sets it as the monitor's gamma ramp.
144 | #
145 | # This method accepts the following arguments:
146 | # - *gamma*, the exponent used to generate the new gamma ramp.
147 | #
148 | # NOTE: This method must be called inside a `CrystGLFW#run` block definition.
149 | def set_gamma(gamma : Number)
150 | LibGLFW.set_gamma @handle, gamma
151 | end
152 |
153 | # Alternate syntax for `#set_gamma`.
154 | #
155 | # This method accepts the following arguments:
156 | # - *gamma*, the exponent used to generate the new gamma ramp.
157 | #
158 | # NOTE: This method must be called inside a `CrystGLFW#run` block definition.
159 | def gamma=(gamma : Number)
160 | LibGLFW.set_gamma @handle, gamma
161 | end
162 |
163 | # Returns the monitor's current gamma ramp.
164 | #
165 | # NOTE: This method must be called inside a `CrystGLFW#run` block definition.
166 | def gamma_ramp : GammaRamp
167 | GammaRamp.new LibGLFW.get_gamma_ramp(@handle)
168 | end
169 |
170 | # Sets the monitor's gamma ramp to the given gamma ramp.
171 | def set_gamma_ramp(gamma_ramp : GammaRamp)
172 | LibGLFW.set_gamma_ramp @handle, gamma_ramp
173 | end
174 |
175 | # Alternate syntax for `#set_gamma_ramp`.
176 | def gamma_ramp=(gamma_ramp : GammaRamp)
177 | LibGLFW.set_gamma_ramp @handle, gamma_ramp
178 | end
179 |
180 | # :nodoc:
181 | def ==(other : Monitor)
182 | @handle == other.to_unsafe
183 | end
184 |
185 | # :nodoc:
186 | def to_unsafe : Pointer(LibGLFW::Monitor)
187 | @handle
188 | end
189 |
190 | set_toggle_connection_callback
191 | end
192 | end
193 |
--------------------------------------------------------------------------------
/src/crystglfw/monitors/video_mode.cr:
--------------------------------------------------------------------------------
1 | require "lib_glfw"
2 |
3 | module CrystGLFW
4 | struct Monitor
5 | # A VideoMode object wraps an underlying GLFW Vidmode and exposes its attributes.
6 | struct VideoMode
7 | # :nodoc:
8 | def initialize(handle : Pointer(LibGLFW::Vidmode))
9 | @handle = handle
10 | end
11 |
12 | # Returns the bit depth of the red channel.
13 | def red_bits : Int32
14 | vid_mode.redBits
15 | end
16 |
17 | # Returns the bit depth of the green channel.
18 | def green_bits : Int32
19 | vid_mode.greenBits
20 | end
21 |
22 | # Returns the bit depth of the blue channel.
23 | def blue_bits : Int32
24 | vid_mode.blueBits
25 | end
26 |
27 | # Returns the size, in screen coordinates, of the video mode.
28 | def size : NamedTuple(width: Int32, height: Int32)
29 | { width: vid_mode.width, height: vid_mode.height }
30 | end
31 |
32 | # Returns the refresh rate, in Hz, of the video mode.
33 | def refresh_rate : Int32
34 | vid_mode.refreshRate
35 | end
36 |
37 | # :nodoc:
38 | def ==(other : VideoMode) : Bool
39 | @handle == other.to_unsafe
40 | end
41 |
42 | # :nodoc:
43 | def to_unsafe : Pointer(LibGLFW::Vidmode)
44 | @handle
45 | end
46 |
47 | # Dereferences the pointer to the GLFW Vidmode.
48 | private def vid_mode : LibGLFW::Vidmode
49 | @handle.value
50 | end
51 | end
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/src/crystglfw/mouse_button.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum MouseButton
3 | One = LibGLFW::MOUSE_BUTTON_1
4 | Two = LibGLFW::MOUSE_BUTTON_2
5 | Three = LibGLFW::MOUSE_BUTTON_3
6 | Four = LibGLFW::MOUSE_BUTTON_4
7 | Five = LibGLFW::MOUSE_BUTTON_5
8 | Six = LibGLFW::MOUSE_BUTTON_6
9 | Seven = LibGLFW::MOUSE_BUTTON_7
10 | Eight = LibGLFW::MOUSE_BUTTON_8
11 | Last = LibGLFW::MOUSE_BUTTON_LAST
12 | Left = LibGLFW::MOUSE_BUTTON_LEFT
13 | Right = LibGLFW::MOUSE_BUTTON_RIGHT
14 | Middle = LibGLFW::MOUSE_BUTTON_MIDDLE
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/src/crystglfw/opengl_profile.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum OpenGLProfile
3 | Any = LibGLFW::OPENGL_ANY_PROFILE
4 | Compat = LibGLFW::OPENGL_COMPAT_PROFILE
5 | Core = LibGLFW::OPENGL_CORE_PROFILE
6 | end
7 | end
--------------------------------------------------------------------------------
/src/crystglfw/release_behavior.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum ReleaseBehavior
3 | Any = LibGLFW::ANY_RELEASE_BEHAVIOR
4 | Flush = LibGLFW::RELEASE_BEHAVIOR_FLUSH
5 | None = LibGLFW::RELEASE_BEHAVIOR_NONE
6 | end
7 | end
--------------------------------------------------------------------------------
/src/crystglfw/sticky.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum Sticky
3 | Keys = LibGLFW::STICKY_KEYS
4 | MouseButtons = LibGLFW::STICKY_MOUSE_BUTTONS
5 | end
6 | end
--------------------------------------------------------------------------------
/src/crystglfw/version.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | enum Version
3 | Major = LibGLFW::VERSION_MAJOR
4 | Minor = LibGLFW::VERSION_MINOR
5 | Revision = LibGLFW::VERSION_REVISION
6 | end
7 | end
--------------------------------------------------------------------------------
/src/crystglfw/windows/cursor.cr:
--------------------------------------------------------------------------------
1 | require "lib_glfw"
2 |
3 | module CrystGLFW
4 | class Window
5 | # A Cursor represents a GLFW cursor and can either use a custom image or a system-default shape as its likeness.
6 | #
7 | # Cursors are created indirectly through windows, and are therefore always associated with a `Window`.
8 | struct Cursor
9 |
10 | enum Shape
11 | Arrow = LibGLFW::ARROW_CURSOR
12 | IBeam = LibGLFW::IBEAM_CURSOR
13 | Crosshair = LibGLFW::CROSSHAIR_CURSOR
14 | Hand = LibGLFW::HAND_CURSOR
15 | HResize = LibGLFW::HRESIZE_CURSOR
16 | VResize = LibGLFW::VRESIZE_CURSOR
17 | end
18 |
19 | enum Mode
20 | Normal = LibGLFW::CURSOR_NORMAL
21 | Hidden = LibGLFW::CURSOR_HIDDEN
22 | Disabled = LibGLFW::CURSOR_DISABLED
23 | end
24 |
25 | # :nodoc:
26 | def initialize(cursor_shape : Shape, window : Window)
27 | @handle = LibGLFW.create_standard_cursor(cursor_shape)
28 | @window = window
29 | LibGLFW.set_cursor @window, @handle
30 | end
31 |
32 | # :nodoc:
33 | def initialize(image : Image, x : Number, y : Number, window : Window)
34 | @handle = LibGLFW.create_cursor(image, x, y)
35 | @window = window
36 | LibGLFW.set_cursor @window, @handle
37 | end
38 |
39 | # Returns the cursor's window.
40 | #
41 | # ```
42 | # # Get the cursor's associated window.
43 | # window = cursor.window
44 | # ```
45 | def window : Window
46 | @window
47 | end
48 |
49 | # Returns the position of the cursor relative to its window.
50 | #
51 | # ```
52 | # cp = cursor.position
53 | # puts "The cursor position is located at (#{cp[:x]}, #{cp[:y]}) relative to its window."
54 | # ```
55 | #
56 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
57 | def position : NamedTuple(x: Float64, y: Float64)
58 | LibGLFW.get_cursor_pos @window.to_unsafe, out x, out y
59 | { x: x, y: y }
60 | end
61 |
62 | # Sets the cursor's position relative to its window.
63 | #
64 | # ```
65 | # # Set the cursor position to the top-left corner of its window.
66 | # cursor.set_position 0, 0
67 | # ```
68 | #
69 | # This method accepts the following arguments:
70 | # - *x*, the desired x coordinate of the cursor.
71 | # - *y*, the desired y coordinate of the cursor.
72 | #
73 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
74 | def set_position(x : Number, y : Number)
75 | LibGLFW.set_cursor_pos @window.to_unsafe, x, y
76 | end
77 |
78 | # Alternate syntax for `#set_position`.
79 | #
80 | # ```
81 | # # Set the cursor position to the top-left corner of its window.
82 | # cursor.position = {x: 0, y: 0}
83 | # ```
84 | #
85 | # This method accepts the following arguments:
86 | # - *pos*, the desired coordinates of the cursor's position.
87 | #
88 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
89 | def position=(pos : NamedTuple(x: Number, y: Number))
90 | set_position pos[:x], pos[:y]
91 | end
92 |
93 | # Returns true if the cursor is in its window. False otherwise.
94 | #
95 | # ```
96 | # if window.cursor.in_window?
97 | # puts "The cursor is in its window!"
98 | # else
99 | # puts "The cursor is somewhere else"
100 | # end
101 | # ```
102 | #
103 | # NOTE: This method must be called from within a `CrystGLFW#run` block definition.
104 | def in_window?
105 | wp = @window.position
106 | @window.contains? position[:x] + wp[:x], position[:y] + wp[:y]
107 | end
108 |
109 | def normal?
110 | Mode.new(LibGLFW.get_input_mode(@window, LibGLFW::CURSOR)).normal?
111 | end
112 |
113 | def hidden?
114 | Mode.new(LibGLFW.get_input_mode(@window, LibGLFW::CURSOR)).hidden?
115 | end
116 |
117 | def disabled?
118 | Mode.new(LibGLFW.get_input_mode(@window, LibGLFW::CURSOR)).disabled?
119 | end
120 |
121 | def normalize
122 | LibGLFW.set_input_mode(@window, LibGLFW::CURSOR, Mode::Normal)
123 | end
124 |
125 | def hide
126 | LibGLFW.set_input_mode(@window, LibGLFW::CURSOR, Mode::Hidden)
127 | end
128 |
129 | def disable
130 | LibGLFW.set_input_mode(@window, LibGLFW::CURSOR, Mode::Disabled)
131 | end
132 |
133 | # :nodoc:
134 | def destroy
135 | LibGLFW.destroy_cursor @handle
136 | end
137 |
138 | # :nodoc:
139 | def ==(other : Cursor)
140 | @handle == other.to_unsafe
141 | end
142 |
143 | # :nodoc:
144 | def to_unsafe
145 | @handle
146 | end
147 | end
148 | end
149 | end
150 |
--------------------------------------------------------------------------------
/src/crystglfw/windows/hint_label.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | class Window
3 | enum HintLabel
4 | Resizable = LibGLFW::RESIZABLE
5 | Visible = LibGLFW::VISIBLE
6 | Decorated = LibGLFW::DECORATED
7 | Focused = LibGLFW::FOCUSED
8 | AutoIconify = LibGLFW::AUTO_ICONIFY
9 | Floating = LibGLFW::FLOATING
10 | Maximized = LibGLFW::MAXIMIZED
11 | RedBits = LibGLFW::RED_BITS
12 | GreenBits = LibGLFW::GREEN_BITS
13 | BlueBits = LibGLFW::BLUE_BITS
14 | AlphaBits = LibGLFW::ALPHA_BITS
15 | DepthBits = LibGLFW::DEPTH_BITS
16 | StencilBits = LibGLFW::STENCIL_BITS
17 | AccumRedBits = LibGLFW::ACCUM_RED_BITS
18 | AccumGreenBits = LibGLFW::ACCUM_GREEN_BITS
19 | AccumBlueBits = LibGLFW::ACCUM_BLUE_BITS
20 | AccumAlphaBits = LibGLFW::ACCUM_ALPHA_BITS
21 | AuxBuffers = LibGLFW::AUX_BUFFERS
22 | Samples = LibGLFW::SAMPLES
23 | RefreshRate = LibGLFW::REFRESH_RATE
24 | Stereo = LibGLFW::STEREO
25 | SRGBCapable = LibGLFW::SRGB_CAPABLE
26 | Doublebuffer = LibGLFW::DOUBLEBUFFER
27 | ClientAPI = LibGLFW::CLIENT_API
28 | ContextCreationAPI = LibGLFW::CONTEXT_CREATION_API
29 | ContextVersionMajor = LibGLFW::CONTEXT_VERSION_MAJOR
30 | ContextVersionMinor = LibGLFW::CONTEXT_VERSION_MINOR
31 | ContextRobustness = LibGLFW::CONTEXT_ROBUSTNESS
32 | ContextReleaseBehavior = LibGLFW::CONTEXT_RELEASE_BEHAVIOR
33 | OpenGLForwardCompat = LibGLFW::OPENGL_FORWARD_COMPAT
34 | OpenGLDebugContext = LibGLFW::OPENGL_DEBUG_CONTEXT
35 | OpenGLProfile = LibGLFW::OPENGL_PROFILE
36 | end
37 | end
38 | end
--------------------------------------------------------------------------------
/src/crystglfw/windows/image.cr:
--------------------------------------------------------------------------------
1 | require "lib_glfw"
2 |
3 | module CrystGLFW
4 | class Window
5 | # An Image object wraps an underlying GLFW Image and exposes its attributes.
6 | struct Image
7 | @image : LibGLFW::Image
8 |
9 | # Create a new image for use as a Cursor image or a Window icon.
10 | #
11 | # ```
12 | # width, height = 16, 32
13 | # pixels = Array(UInt8).new(width * height, 255_u8)
14 | # image = CrystGLFW::Image.new(width, height, pixels)
15 | # ```
16 | #
17 | # This method accepts the following arguments:
18 | # - *width*, the width of the image, in pixels.
19 | # - *height*, the height of the image, in pixels.
20 | # - *pixels*, the pixel data, given left-to-right, top-to-bottom.
21 | #
22 | # NOTE: This method may be called outside a `CrystGLFW#run` block defintion without triggering an error.
23 | def initialize(width : Int32, height : Int32, pixels : Array(UInt8))
24 | @image = LibGLFW::Image.new
25 | @image.width = width
26 | @image.height = height
27 | @image.pixels = pixels
28 | end
29 |
30 | def size : NamedTuple(width: Int32, height: Int32)
31 | { width: @image.width, height: @image.height }
32 | end
33 |
34 | # Returns the pixel data of the image, arranged left-to-right, top-to-bottom.
35 | def pixels : Slice(UInt8)
36 | Slice.new(@image.pixels, width * height)
37 | end
38 |
39 | # :nodoc:
40 | def to_unsafe
41 | pointerof(@image)
42 | end
43 | end
44 | end
45 | end
46 |
--------------------------------------------------------------------------------
/src/crystglfw/windows/state.cr:
--------------------------------------------------------------------------------
1 | module CrystGLFW
2 | class Window
3 | enum State
4 | Focused = LibGLFW::FOCUSED
5 | Iconified = LibGLFW::ICONIFIED
6 | Resizable = LibGLFW::RESIZABLE
7 | Visible = LibGLFW::VISIBLE
8 | Decorated = LibGLFW::DECORATED
9 | Floating = LibGLFW::FLOATING
10 | Maximized = LibGLFW::MAXIMIZED
11 | end
12 | end
13 | end
--------------------------------------------------------------------------------