1 // Written in the D programming language.
2 /++
3  + Authors: KanzakiKino
4  + Copyright: KanzakiKino 2018
5  + License: LGPL-3.0
6 ++/
7 module g4d.glfw.handler;
8 import g4d.glfw.lib,
9        g4d.glfw.type;
10 import gl3n.linalg;
11 import std.string;
12 
13 ///
14 alias WindowMoveHandler    = void delegate ( vec2i );
15 ///
16 alias WindowResizeHandler  = void delegate ( vec2i );
17 ///
18 alias WindowCloseHandler   = void delegate ();
19 ///
20 alias WindowRefreshHandler = void delegate ();
21 ///
22 alias WindowFocusHandler   = void delegate ( bool );
23 ///
24 alias WindowIconifyHandler = void delegate ( bool );
25 ///
26 alias FbResizeHandler      = void delegate ( vec2i );
27 
28 ///
29 alias MouseButtonHandler = void delegate ( MouseButton, bool );
30 ///
31 alias MouseMoveHandler   = void delegate ( vec2 );
32 ///
33 alias MouseEnterHandler  = void delegate ( bool );
34 ///
35 alias MouseScrollHandler = void delegate ( vec2 );
36 ///
37 alias KeyHandler         = void delegate ( Key, KeyState );
38 ///
39 alias CharacterHandler   = void delegate ( dchar );
40 
41 /// A collection of window handlers.
42 struct EventHandler
43 {
44     /// An exception throwed in handlers is saved here temporary.
45     Exception throwedException = null;
46 
47     ///
48     WindowMoveHandler    onWindowMove    = null;
49     ///
50     WindowResizeHandler  onWindowResize  = null;
51     ///
52     WindowCloseHandler   onWindowClose   = null;
53     ///
54     WindowRefreshHandler onWindowRefresh = null;
55     ///
56     WindowFocusHandler   onWindowFocus   = null;
57     ///
58     WindowIconifyHandler onWindowIconify = null;
59     ///
60     FbResizeHandler      onFbResize      = null;
61 
62     ///
63     MouseButtonHandler onMouseButton = null;
64     ///
65     MouseMoveHandler   onMouseMove   = null;
66     ///
67     MouseEnterHandler  onMouseEnter  = null;
68     ///
69     MouseScrollHandler onMouseScroll = null;
70     ///
71     KeyHandler         onKey         = null;
72     ///
73     CharacterHandler   onCharacter   = null;
74 
75     protected static pure string genFunc ( string handler, string args = "", string hndlargs = "" )
76     {
77         if ( args != "" ) {
78             args = ','~args;
79         }
80         return q{
81             function ( GLFWwindow* win %ARGS% ) nothrow
82             {
83                 auto ptr = cast(EventHandler*) glfwGetWindowUserPointer( win );
84                 if ( ptr.%HANDLER% ) {
85                     try {
86                         ptr.%HANDLER%( %HANDLER_ARGS% );
87                     } catch ( Exception e ) {
88                         ptr.throwedException = e;
89                     }
90                 }
91             }
92         }
93         .replace( "%HANDLER%", handler )
94         .replace( "%ARGS%", args )
95         .replace( "%HANDLER_ARGS%", hndlargs );
96     }
97 
98     private static extern(C) GLFWwindowposfun __wp =
99         mixin( genFunc( "onWindowMove", q{int x,int y}, q{vec2i(x,y)} ) );
100     private static extern(C) GLFWwindowsizefun __ws =
101         mixin( genFunc( "onWindowResize", q{int x,int y}, q{vec2i(x,y)} ) );
102     private static extern(C) GLFWwindowclosefun __wc =
103         mixin( genFunc( "onWindowClose" ) );
104     private static extern(C) GLFWwindowrefreshfun __wr =
105         mixin( genFunc( "onWindowRefresh" ) );
106     private static extern(C) GLFWwindowfocusfun __wf =
107         mixin( genFunc( "onWindowFocus", q{int t}, q{t == GLFW_TRUE} ) );
108     private static extern(C) GLFWwindowfocusfun __wi =
109         mixin( genFunc( "onWindowIconify", q{int t}, q{t == GLFW_TRUE} ) );
110     private static extern(C) GLFWframebuffersizefun __fs =
111         mixin( genFunc( "onFbResize", q{int x, int y}, q{vec2i(x,y)} ) );
112 
113     private static extern(C) GLFWmousebuttonfun __mb =
114         mixin( genFunc( "onMouseButton", q{int b, int a, int m}, q{cast(MouseButton)b, a == GLFW_PRESS} ) );
115     private static extern(C) GLFWcursorposfun __mm =
116         mixin( genFunc( "onMouseMove", q{double x, double y}, q{vec2(x,y)} ) );
117     private static extern(C) GLFWcursorenterfun __me =
118         mixin( genFunc( "onMouseEnter", q{int t}, q{t == GLFW_TRUE} ) );
119     private static extern(C) GLFWscrollfun __ms =
120         mixin( genFunc( "onMouseScroll", q{double x, double y}, q{vec2(x,y)} ) );
121     private static extern(C) GLFWkeyfun __k =
122         mixin( genFunc( "onKey", q{int k, int code, int a, int m}, q{cast(Key)k, cast(KeyState)a} ) );
123     private static extern(C) GLFWcharfun __c =
124         mixin( genFunc( "onCharacter", q{uint c}, q{cast(dchar)c} ) );
125 
126     ///
127     this ( GLFWwindow* win )
128     {
129         enforce!glfwSetWindowUserPointer( win, &this );
130 
131         enforce!glfwSetWindowPosCallback      ( win, __wp );
132         enforce!glfwSetWindowSizeCallback     ( win, __ws );
133         enforce!glfwSetWindowCloseCallback    ( win, __wc );
134         enforce!glfwSetWindowRefreshCallback  ( win, __wr );
135         enforce!glfwSetWindowFocusCallback    ( win, __wf );
136         enforce!glfwSetWindowIconifyCallback  ( win, __wi );
137         enforce!glfwSetFramebufferSizeCallback( win, __fs );
138 
139         enforce!glfwSetMouseButtonCallback( win, __mb );
140         enforce!glfwSetCursorPosCallback  ( win, __mm );
141         enforce!glfwSetCursorEnterCallback( win, __me );
142         enforce!glfwSetScrollCallback     ( win, __ms );
143         enforce!glfwSetKeyCallback        ( win, __k );
144         enforce!glfwSetCharCallback       ( win, __c );
145     }
146 }