Mercurial > projects > mde
comparison mde/input/Input.d @ 132:264028f4115a
Cleaned up mde.imde and a couple of widget functions.
New mde.menus module to add default menus.
The input singleton is now created in mde.input.Input instead of mde.imde.
author | Diggory Hardy <diggory.hardy@gmail.com> |
---|---|
date | Fri, 23 Jan 2009 14:59:05 +0000 |
parents | a2ef6b549101 |
children | 4084f07f2c7a |
comparison
equal
deleted
inserted
replaced
131:9cff74f68b84 | 132:264028f4115a |
---|---|
141 } | 141 } |
142 | 142 |
143 /** Adds a callback delegate for key events (both DOWN and UP) with this ID. | 143 /** Adds a callback delegate for key events (both DOWN and UP) with this ID. |
144 * | 144 * |
145 * Delegate receives event status. */ | 145 * Delegate receives event status. */ |
146 void addButtonCallback (inputID id, ButtonCallback dg) { | 146 Input addButtonCallback (inputID id, ButtonCallback dg) { |
147 buttonCallbacks[id] ~= dg; | 147 buttonCallbacks[id] ~= dg; |
148 return this; | |
148 } | 149 } |
149 | 150 |
150 /** Adds a callback delegate for axis events with this ID. | 151 /** Adds a callback delegate for axis events with this ID. |
151 * | 152 * |
152 * Delegate receives event status (as per what getAxis returns). */ | 153 * Delegate receives event status (as per what getAxis returns). */ |
153 void addAxisCallback (inputID id, AxisCallback dg) { | 154 Input addAxisCallback (inputID id, AxisCallback dg) { |
154 axisCallbacks[id] ~= dg; | 155 axisCallbacks[id] ~= dg; |
156 return this; | |
155 } | 157 } |
156 | 158 |
157 /** Adds a callback delegate for mouse motion/joystick ball events with this ID. | 159 /** Adds a callback delegate for mouse motion/joystick ball events with this ID. |
158 * | 160 * |
159 * Delegate receives event status. As the name suggests, this is relative motion not screen | 161 * Delegate receives event status. As the name suggests, this is relative motion not screen |
160 * position, with sensitivity adjustments applied. | 162 * position, with sensitivity adjustments applied. |
161 * | 163 * |
162 * (A separate callback for mouse screen position changes is not | 164 * (A separate callback for mouse screen position changes is not |
163 * necessary since this will be triggered by the same event - use mouseScreenPos from within the | 165 * necessary since this will be triggered by the same event - use mouseScreenPos from within the |
164 * function to get new screen coordinates.) */ | 166 * function to get new screen coordinates.) */ |
165 void addRelMotionCallback (inputID id, RelMotionCallback dg) { | 167 Input addRelMotionCallback (inputID id, RelMotionCallback dg) { |
166 relMotionCallbacks[id] ~= dg; | 168 relMotionCallbacks[id] ~= dg; |
169 return this; | |
167 } | 170 } |
168 | 171 |
169 /** Adds a callback delegate for all mouse clicks & releases. | 172 /** Adds a callback delegate for all mouse clicks & releases. |
170 * | 173 * |
171 * Delegate recieves x,y screen position (at time of click/release), button index (1 for left, | 174 * Delegate recieves x,y screen position (at time of click/release), button index (1 for left, |
173 * released (true if pressed). | 176 * released (true if pressed). |
174 * | 177 * |
175 * The point of this over a standard button callback is firstly to avoid mouse configuration for | 178 * The point of this over a standard button callback is firstly to avoid mouse configuration for |
176 * the GUI, and secondly to give the pointer position at the time of the event, not the time the | 179 * the GUI, and secondly to give the pointer position at the time of the event, not the time the |
177 * callback gets called. */ | 180 * callback gets called. */ |
178 void addMouseClickCallback (MouseClickCallback dg) { | 181 Input addMouseClickCallback (MouseClickCallback dg) { |
179 mouseClickCallbacks ~= dg; | 182 mouseClickCallbacks ~= dg; |
183 return this; | |
180 } | 184 } |
181 | 185 |
182 /** Adds a callback delegate for all mouse motion events. | 186 /** Adds a callback delegate for all mouse motion events. |
183 * | 187 * |
184 * Really just for graphical user interfaces. Use addRelMotionCallback for relative motion (for | 188 * Really just for graphical user interfaces. Use addRelMotionCallback for relative motion (for |
185 * manipulating 3D views, etc.). */ | 189 * manipulating 3D views, etc.). */ |
186 void addMouseMotionCallback (MouseMotionCallback dg) { | 190 Input addMouseMotionCallback (MouseMotionCallback dg) { |
187 mouseMotionCallbacks ~= dg; | 191 mouseMotionCallbacks ~= dg; |
192 return this; | |
188 } | 193 } |
189 | 194 |
190 /** Sets a callback delegate to recieve key presses as a Utf-8 char[]. | 195 /** Sets a callback delegate to recieve key presses as a Utf-8 char[]. |
191 * | 196 * |
192 * Since it is normal to type into only one location at once, setting a new LetterCallback | 197 * Since it is normal to type into only one location at once, setting a new LetterCallback |
204 } | 209 } |
205 letterCallback = dg; | 210 letterCallback = dg; |
206 } | 211 } |
207 | 212 |
208 /** Feed an SDL_Event struct (only uses if it's a key, mouse or joystick event). | 213 /** Feed an SDL_Event struct (only uses if it's a key, mouse or joystick event). |
209 * | 214 * |
210 * Other types of event functions may be added. Returns true if the event was used, false if not | 215 * Other types of event functions may be added. Returns true if the event |
211 * or no config was available. Hmm... doesn't seem very useful, but has practically no cost. | 216 * was used, false if not or no config was available. Hmm... doesn't seem |
212 * (Due to lack of use of this feature, false is returned even for used events when no config is | 217 * very useful, but has practically no cost. |
213 * available). | 218 * |
214 * | 219 * May throw InputClassExceptions (on configuration errors). Catching the |
215 * May throw InputClassExceptions (on configuration errors). Catching the exception and continuing should | 220 * exception and continuing should be fine. */ |
216 * be fine. */ | 221 bool send (ref SDL_Event event) { |
217 bool opCall (ref SDL_Event event) { | |
218 /* Non-config events. | 222 /* Non-config events. |
219 * | 223 * |
220 * Handle these first so that if no config exists some functionality at least is retained. | 224 * Handle these first so that if no config exists some functionality at |
225 * least is retained. | |
221 * | 226 * |
222 * Coordinates don't need adjusting (they put the top-left most pixel at 0,0). | 227 * Coordinates don't need adjusting (they put the top-left most pixel at 0,0). |
223 */ | 228 * |
229 * If no config, exit from this switch. */ | |
224 switch (event.type) { | 230 switch (event.type) { |
225 case SDL_KEYDOWN: | 231 case SDL_KEYDOWN: |
226 if (letterCallback) { | 232 if (letterCallback) { |
227 try | 233 try |
228 letterCallback (event.key.keysym.sym, Utf.toString ([cast(wchar)event.key.keysym.unicode], cast(char[])utfBuf)); | 234 letterCallback (event.key.keysym.sym, Utf.toString ([cast(wchar)event.key.keysym.unicode], cast(char[])utfBuf)); |
250 logger.error (CB_EXC ~ e.msg); | 256 logger.error (CB_EXC ~ e.msg); |
251 } | 257 } |
252 break; | 258 break; |
253 | 259 |
254 default: | 260 default: |
255 } | 261 if (!config) return false; // event not used |
256 | 262 } |
257 /* No config available, so don't try to access it and segfault. | 263 if (!config) return true; // event used |
258 * Don't log a message because this function is called per-event (i.e. frequently). | |
259 * A message should already have been logged by loadConfig anyway. */ | |
260 if (!config) return false; | |
261 | 264 |
262 switch (event.type) { | 265 switch (event.type) { |
263 // Keyboard events: | 266 // Keyboard events: |
264 case SDL_KEYDOWN: | 267 case SDL_KEYDOWN: |
265 case SDL_KEYUP: | 268 case SDL_KEYUP: |
386 void loadConfig (char[] file, char[] profile = "Default") { | 389 void loadConfig (char[] file, char[] profile = "Default") { |
387 Config.load(file); | 390 Config.load(file); |
388 Config* c_p = profile in Config.configs; | 391 Config* c_p = profile in Config.configs; |
389 if (c_p) config = *c_p; | 392 if (c_p) config = *c_p; |
390 else { | 393 else { |
394 logger.error ("Config profile \""~profile~"\" not found: input won't work unless a valid profile is loaded!"); | |
391 throw new ConfigLoadException; | 395 throw new ConfigLoadException; |
392 logger.error ("Config profile \""~profile~"\" not found: input won't work unless a valid profile is loaded!"); | 396 } |
393 } | 397 } |
398 | |
399 /** For now, use as a singleton. (Could be changed later to allow multiple | |
400 * "players". */ | |
401 static Input singleton () { | |
402 if (instance is null) | |
403 instance = new Input(); | |
404 return instance; | |
394 } | 405 } |
395 | 406 |
396 private: | 407 private: |
397 // Static constructor for event stream (fills es_*_fcts tables). | 408 // Static constructor for event stream (fills es_*_fcts tables). |
398 static this () { | 409 static this () { |
412 } | 423 } |
413 } | 424 } |
414 | 425 |
415 static const CB_EXC = "Callback exception: "; | 426 static const CB_EXC = "Callback exception: "; |
416 | 427 |
428 static Input instance; | |
417 static Logger logger; | 429 static Logger logger; |
418 | 430 |
419 Config config; // Configuration | 431 Config config; // Configuration |
420 char[6] utfBuf; // Buffer for Utf.toString; reallocates if less than 5. | 432 char[6] utfBuf; // Buffer for Utf.toString; reallocates if less than 5. |
421 | 433 |