~ubuntu-branches/debian/sid/ember/sid

« back to all changes in this revision

Viewing changes to src/services/input/Input.h

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2009-07-23 07:46:40 UTC
  • Revision ID: james.westby@ubuntu.com-20090723074640-wh0ukzis0kda36qv
Tags: upstream-0.5.6
ImportĀ upstreamĀ versionĀ 0.5.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//
 
2
// C++ Interface: Input
 
3
//
 
4
// Description: 
 
5
//
 
6
//
 
7
// Author: Erik Hjortsberg <erik.hjortsberg@gmail.com>, (C) 2005
 
8
//
 
9
// This program is free software; you can redistribute it and/or modify
 
10
// it under the terms of the GNU General Public License as published by
 
11
// the Free Software Foundation; either version 2 of the License, or
 
12
// (at your option) any later version.
 
13
// 
 
14
// This program is distributed in the hope that it will be useful,
 
15
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
// GNU General Public License for more details.
 
18
// 
 
19
// You should have received a copy of the GNU General Public License
 
20
// along with this program; if not, write to the Free Software
 
21
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.//
 
22
//
 
23
#ifndef EMBEROGREINPUT_H
 
24
#define EMBEROGREINPUT_H
 
25
 
 
26
#include <sigc++/slot.h>
 
27
#include <sigc++/signal.h>
 
28
#include <SDL_events.h>
 
29
#include "framework/ConsoleObject.h"
 
30
#include "framework/Singleton.h"
 
31
 
 
32
#include <set>
 
33
#include <list>
 
34
#include <map>
 
35
 
 
36
namespace Ember {
 
37
 
 
38
class IInputAdapter;
 
39
class InputCommandMapper;
 
40
 
 
41
typedef std::set<SDLKey> KeysSet;
 
42
typedef std::list<IInputAdapter*> IInputAdapterStore;
 
43
 
 
44
 
 
45
 
 
46
/**
 
47
@brief Struct for a mouse movement.
 
48
@author Erik Hjortsberg <erik.hjortsberg@gmail.com>
 
49
*/
 
50
struct MouseMotion
 
51
{
 
52
        /**
 
53
        @brief The horizontal position of the mouse in pixels.
 
54
        */
 
55
        int xPosition; 
 
56
        /**
 
57
        @brief The vertical position of the mouse in pixels.
 
58
        */
 
59
        int yPosition;
 
60
        
 
61
        /**
 
62
        @brief The relative horizontal position of the mouse.
 
63
        This is between 0..1
 
64
        */
 
65
        float xRelativeMovement; 
 
66
        /**
 
67
        @brief The relative vertical position of the mouse.
 
68
        This is between 0..1
 
69
        */
 
70
        float yRelativeMovement;
 
71
        
 
72
        /**
 
73
        @brief The relative horizontal movement in pixels.
 
74
        The amount of pixels the cursor has moved since our last sampling point.
 
75
        */
 
76
        int xRelativeMovementInPixels; 
 
77
        /**
 
78
        @brief The relative vertical movement in pixels.
 
79
        The amount of pixels the cursor has moved since our last sampling point.
 
80
        */
 
81
        int yRelativeMovementInPixels;
 
82
        
 
83
        /**
 
84
        @brief The time since last sampling point.
 
85
        Expressed as full seconds.
 
86
        */
 
87
        float timeSinceLastMovement;
 
88
};
 
89
 
 
90
/**
 
91
@brief Expresses the position of the mouse, both in terms of pixels and relative.
 
92
 
 
93
Positions are from the upper left corner.
 
94
@author Erik Hjortsberg <erik.hjortsberg@gmail.com>
 
95
*/
 
96
struct MousePosition
 
97
{
 
98
        /**
 
99
        @brief The horizontal position of the mouse in pixels.
 
100
        */
 
101
        int xPixelPosition; 
 
102
        /**
 
103
        @brief The vertical position of the mouse in pixels.
 
104
        */
 
105
        int yPixelPosition;
 
106
        
 
107
        /**
 
108
        @brief The relative horizontal position of the mouse.
 
109
        0 is to the left, 1 is to the right.
 
110
        */
 
111
        float xRelativePosition; 
 
112
        /**
 
113
        @brief The relative vertical position of the mouse.
 
114
        0 is at the top, 1 is at the bottom.
 
115
        */
 
116
        float yRelativePosition;
 
117
        
 
118
};
 
119
 
 
120
/**
 
121
@author Erik Hjortsberg <erik.hjortsberg@gmail.com>
 
122
 
 
123
@brief This class takes care of all input and routes it to the correct place in Ember.
 
124
Right now that means that when in GUI mode, all input will be routed to the registered list of @see IInputAdapter, and when in non-gui mode (ie. movement mode), all input will be routed directly to Ember, where it can be handled by the camera and movement system.
 
125
 
 
126
Note that while keyboard input is buffered, mouse input is not.
 
127
 
 
128
You can listen to input updates either by listening directly to the events, or by registering an instance of IInputAdapter through the addAdapter and removeAdapter methods.
 
129
 
 
130
This class also provides some methods useful for standard windowing and event system integration, such as isApplicationVisible().
 
131
*/
 
132
class Input : public Ember::ConsoleObject, public Ember::Singleton<Input>
 
133
{
 
134
friend class InputCommandMapper;
 
135
 
 
136
public:
 
137
        
 
138
        /**
 
139
        @brief Command for binding keys to commands.
 
140
        */
 
141
        static const std::string BINDCOMMAND;
 
142
        
 
143
        /**
 
144
        @brief Command for unbinding keys to commands.
 
145
        */
 
146
        static const std::string UNBINDCOMMAND;
 
147
        
 
148
        
 
149
        enum MouseButton
 
150
        {
 
151
                MouseButtonLeft,
 
152
                MouseButtonRight,
 
153
                MouseButtonMiddle,
 
154
                MouseWheelUp,
 
155
                MouseWheelDown,
 
156
        };
 
157
        
 
158
        /**
 
159
        @brief Describes different input modes.
 
160
        */
 
161
        enum InputMode
 
162
        {
 
163
                /**
 
164
                @brief In gui mode, the mouse will move the cursor and allow interaction with the GUI system
 
165
                */
 
166
                IM_GUI,
 
167
                
 
168
                /**
 
169
                @brief In movement mode, the mouse will move the camera and the keys will move the player. Interaction with the gui is not possible.
 
170
                */
 
171
                IM_MOVEMENT
 
172
        };
 
173
        
 
174
   Input();
 
175
 
 
176
   virtual ~Input();
 
177
        
 
178
        /**
 
179
         * @brief Initializes the input object. Call this before you want to recieve input.
 
180
         * @param width The width of the window, in pixels.
 
181
         * @param heigh The height of the window, in pixels.
 
182
         */
 
183
        void initialize(int width, int height);
 
184
 
 
185
        /**
 
186
         * @brief Starts processing all input for a frame.
 
187
         * Call this once every frame.
 
188
         * @param evt 
 
189
         */
 
190
        void processInput();
 
191
        
 
192
        /**
 
193
         *    @brief Checks whether the application is visible and nor minimized.
 
194
         * @return True if the application is in normal shown mode, false if it's minimized.
 
195
         */
 
196
        bool isApplicationVisible();
 
197
        
 
198
        /** @brief Emitted when a key has been pressed in movement mode.
 
199
        @param the key event
 
200
        @param true if the application is in gui mode
 
201
        */
 
202
        sigc::signal<void, const SDL_keysym&, Input::InputMode> EventKeyPressed;
 
203
        
 
204
        /** @brief Emitted when a key has been released in movement mode.
 
205
        @param the key event
 
206
        @param true if the application is in gui mode
 
207
        */
 
208
        sigc::signal<void, const SDL_keysym&, Input::InputMode> EventKeyReleased;
 
209
        
 
210
        /** @brief Emitted when the mouse has moved.
 
211
        Note that when in non-gui mode, the x and y position for the mouse will always be the same for consecutive signals although the relative position will have changed.
 
212
        @param the mouse motion
 
213
        @param true if ember is in gui mode
 
214
        */
 
215
        sigc::signal<void, const MouseMotion&, InputMode> EventMouseMoved;
 
216
        
 
217
        
 
218
        /**
 
219
                @brief Emitted when a mouse button is pressed.
 
220
                @param the mouse button
 
221
                @param true if ember is in gui mode
 
222
        */
 
223
        sigc::signal<void, MouseButton, InputMode> EventMouseButtonPressed;
 
224
        
 
225
        /**
 
226
                @brief Emitted when a mouse button is released.
 
227
                @param the mouse button
 
228
                @param true if ember is in gui mode
 
229
        */
 
230
        sigc::signal<void, MouseButton, InputMode> EventMouseButtonReleased;
 
231
        
 
232
        /**
 
233
                @brief Emitted when the input mode has been changed.
 
234
                @param the new input mode
 
235
        */
 
236
        sigc::signal<void, InputMode> EventChangedInputMode;
 
237
        
 
238
        /** 
 
239
        @brief Emitted when the window is minimized or un-mininized.
 
240
        @param True if the window is active, false it it's minimized.
 
241
        */
 
242
        sigc::signal<void, bool> EventWindowActive;
 
243
        
 
244
        /**
 
245
         * @brief Returns true if the supplied key is down 
 
246
         * @param  key The key to check for.
 
247
         * @return True if the key is down
 
248
         */
 
249
        const bool isKeyDown(const SDLKey& key) const;
 
250
 
 
251
        
 
252
        
 
253
        /**
 
254
         * @brief Sets the window geometry. Call this whenever the size of the window has changed.
 
255
         * @param width The new width, in pixels.
 
256
         * @param heigh The new height, in pixels.
 
257
         */
 
258
        void setGeometry(int width, int heigh);
 
259
 
 
260
        /**
 
261
         * @brief Sets the new input mode.
 
262
         * @param mode The new mode.
 
263
         */
 
264
        void setInputMode(InputMode mode);
 
265
        
 
266
        /**
 
267
         * @brief Gets the current input mode.
 
268
         * @return The current input mode. 
 
269
         */
 
270
        InputMode getInputMode() const;
 
271
        
 
272
        
 
273
        /**
 
274
         * @brief Toggles between different input modes, returning the new mode.
 
275
         * @return The new input mode.
 
276
         */
 
277
        InputMode toggleInputMode();
 
278
        
 
279
        /**
 
280
         *  @brief Adds an adaptor to which input event will be sent. 
 
281
         *  Note that event will be sent to adapters added later first, allowing them to decide whether events should be sent to previous added adapters. This allows later added adapters to override current behaviour.
 
282
         * @see removeAdapter
 
283
         * @param adaptor An adapter instance to add. Note that ownership isn't transferred. Note that if the adapter already has been added, this will add a duplicate entry.
 
284
         */
 
285
        void addAdapter(IInputAdapter* adapter);
 
286
        
 
287
        
 
288
        /**
 
289
         *   @brief Remove an adaptor from the list of adaptors.
 
290
         * @param adaptor The adapter to remove. If the adapter isn't present already nothing will happen.
 
291
         */
 
292
        void removeAdapter(IInputAdapter* adapter);
 
293
        
 
294
 
 
295
        
 
296
        /**
 
297
         * @brief Reimplements the ConsoleObject::runCommand method
 
298
         * @param command 
 
299
         * @param args 
 
300
         */
 
301
        virtual void runCommand(const std::string &command, const std::string &args);
 
302
        
 
303
        /**
 
304
        @brief Suppress all further event handling of the current event. Call this inside event handling methods to prevent further event handling.
 
305
        */
 
306
        void suppressFurtherHandlingOfCurrentEvent();
 
307
        
 
308
        /**
 
309
        @brief Gets whether the movement mode is enabled, at which all mouse right click events will toggle between movement mode and mouse mode.
 
310
        @return True if movement mode is enabled.
 
311
        */
 
312
        bool getMovementModeEnabled() const;
 
313
        
 
314
        /**
 
315
        @brief Sets whether the movement mode is enabled, at which all mouse right click events will toggle between movement mode and mouse mode.
 
316
        @param value Whether to enable movement mode or not.
 
317
        */
 
318
        void setMovementModeEnabled(bool value);
 
319
        
 
320
        /**
 
321
         * @brief Writes the supplied text to the system clipboard.
 
322
         * This works on all platform, by using the scrap.c code found in framework.
 
323
         * @param text The text to write.
 
324
         */
 
325
        void writeToClipboard(const std::string& text);
 
326
        
 
327
        /**
 
328
         *    @brief Gets the current mouse position.
 
329
         * @return The last mouse position.
 
330
         */
 
331
        const MousePosition& getMousePosition() const;
 
332
 
 
333
protected:
 
334
 
 
335
        typedef std::map<std::string, InputCommandMapper*> InputCommandMapperStore;
 
336
        
 
337
        
 
338
        /**
 
339
         * @brief Registers a command mapper.
 
340
         * @param mapper The mapper instance to register.
 
341
         */
 
342
        void registerCommandMapper(InputCommandMapper* mapper);
 
343
        
 
344
        /**
 
345
         * @brief Deregisters a command mapper.
 
346
         * @param mapper The mapper to deregister.
 
347
         */
 
348
        void deregisterCommandMapper(InputCommandMapper* mapper);
 
349
        
 
350
        
 
351
        /**
 
352
        @brief The current input mode.
 
353
        */
 
354
        InputMode mCurrentInputMode;
 
355
        
 
356
        
 
357
        /**
 
358
         * @brief Polls all input for the mouse.
 
359
         * Call this each frame.
 
360
         * @param secondsSinceLast In whole seconds, the time since the last polling.
 
361
         */
 
362
        void pollMouse(float secondsSinceLast);
 
363
        
 
364
        /**
 
365
         * @brief Polls all needed events from the system.
 
366
         * Call this each frame.
 
367
         * @param secondsSinceLast In whole seconds, the time since the last polling.
 
368
         */
 
369
        void pollEvents(float secondsSinceLast);
 
370
        
 
371
        void keyChanged(const SDL_KeyboardEvent &keyEvent);
 
372
        
 
373
        void keyPressed(const SDL_KeyboardEvent &keyEvent);
 
374
        void keyReleased(const SDL_KeyboardEvent &keyEvent);
 
375
 
 
376
 
 
377
        /**
 
378
        @brief Keys which should not be injected as chars, ie. enter, backspace etc.
 
379
        */
 
380
        KeysSet mNonCharKeys;
 
381
        
 
382
 
 
383
        /**
 
384
        @brief A set of the keys that are currently pressed.
 
385
        */
 
386
        KeysSet mKeysPressed;
 
387
 
 
388
        /**
 
389
        @brief Saves the last mouse state.
 
390
        */
 
391
        unsigned int mMouseState;
 
392
 
 
393
        /**
 
394
        @brief The last positions of the mouse.
 
395
        */
 
396
        MousePosition mMousePosition;
 
397
        
 
398
        /**
 
399
        @brief The amount of time since the last right mouse click.
 
400
        Used for detecting double clicks.
 
401
        */
 
402
        float mTimeSinceLastRightMouseClick;
 
403
        
 
404
        /**
 
405
        @brief Store the last tick count, to use for looking up how much time has elapsed since our last event polling.
 
406
        */
 
407
        uint32_t mLastTick;
 
408
 
 
409
        /**
 
410
         *   @brief Gets the text in the clipboard and pastes it to the gui system.
 
411
         */
 
412
        void pasteFromClipboard();
 
413
        
 
414
        /**
 
415
        @brief A store of adapters to which input event will be sent, in order.
 
416
        */
 
417
        IInputAdapterStore mAdapters;
 
418
        
 
419
        /**
 
420
        @brief The dimensions of the window.
 
421
        */
 
422
        float mScreenWidth, mScreenHeight;
 
423
        
 
424
        
 
425
        /**
 
426
        @brief A store of InputCommandMappers with their state as the key.
 
427
        */
 
428
        InputCommandMapperStore mInputCommandMappers;
 
429
        
 
430
        /**
 
431
        @brief Whether no more event should be processed.
 
432
        This is checked within the event handling code only.
 
433
        */
 
434
        bool mSuppressForCurrentEvent;
 
435
        
 
436
        /**
 
437
        @brief Whether movement mode is enabled or not.
 
438
        */
 
439
        bool mMovementModeEnabled;
 
440
};
 
441
 
 
442
};
 
443
 
 
444
#endif