Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/usability/src/libraries/core/input/InputBuffer.cc @ 8027

Last change on this file since 8027 was 8027, checked in by landauf, 13 years ago

added translator map to InputBuffer for numpad keys - now they can also be used to type text into the ingame console

  • Property svn:eol-style set to native
File size: 8.6 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Reto Grieder
26 *
27 */
28
29#include "InputBuffer.h"
30
31#include "util/Clipboard.h"
32#include "core/CoreIncludes.h"
33#include "core/ConfigValueIncludes.h"
34
35namespace orxonox
36{
37    InputBuffer::InputBuffer()
38    {
39        RegisterRootObject(InputBuffer);
40
41        this->cursor_ = 0;
42        this->maxLength_ = 1024;
43        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyz \
44                               ABCDEFGHIJKLMNOPQRSTUVWXYZ \
45                               äëïöüÄËÏÖÜáâàéêèíîìóôòúûù \
46                               0123456789 \
47                               \\\"(){}[]<>.:,;_-+*/=!?|$&%^~#";
48
49        this->keyTranslator_[KeyCode::Numpad0]      = '0';
50        this->keyTranslator_[KeyCode::Numpad1]      = '1';
51        this->keyTranslator_[KeyCode::Numpad2]      = '2';
52        this->keyTranslator_[KeyCode::Numpad3]      = '3';
53        this->keyTranslator_[KeyCode::Numpad4]      = '4';
54        this->keyTranslator_[KeyCode::Numpad5]      = '5';
55        this->keyTranslator_[KeyCode::Numpad6]      = '6';
56        this->keyTranslator_[KeyCode::Numpad7]      = '7';
57        this->keyTranslator_[KeyCode::Numpad8]      = '8';
58        this->keyTranslator_[KeyCode::Numpad9]      = '9';
59        this->keyTranslator_[KeyCode::NumpadPeriod] = '.';
60        this->keyTranslator_[KeyCode::Divide]       = '/';
61        this->keyTranslator_[KeyCode::NumpadEnter]  = '\n';
62
63        this->lastKey_ = KeyCode::Unassigned;
64        this->timeSinceKeyPressed_ = 0.0f;
65        this->timeSinceKeyRepeated_ = 0.0f;
66        this->keysToRepeat_ = 0;
67
68        setConfigValues();
69    }
70
71    InputBuffer::InputBuffer(const std::string& allowedChars)
72    {
73        RegisterRootObject(InputBuffer);
74
75        this->maxLength_ = 1024;
76        this->allowedChars_ = allowedChars;
77        this->cursor_ = 0;
78
79        this->lastKey_ = KeyCode::Unassigned;
80        this->timeSinceKeyPressed_ = 0.0f;
81        this->timeSinceKeyRepeated_ = 0.0f;
82        this->keysToRepeat_ = 0;
83
84        setConfigValues();
85    }
86
87    InputBuffer::~InputBuffer()
88    {
89        for (std::list<BaseInputBufferListenerTuple*>::const_iterator it = this->listeners_.begin();
90            it != this->listeners_.end(); ++it)
91            delete *it;
92    }
93
94    void InputBuffer::setConfigValues()
95    {
96        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat delay of the input buffer");
97        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
98
99        if (keyRepeatDeleay_ < 0.0)
100        {
101            ResetConfigValue(keyRepeatDeleay_);
102        }
103        if (keyRepeatTime_ < 0.0)
104        {
105            ResetConfigValue(keyRepeatTime_);
106        }
107    }
108
109    void InputBuffer::setMaxLength(unsigned int length)
110    {
111        this->maxLength_ = length;
112        if (this->buffer_.size() > length)
113            this->buffer_.resize(length);
114    }
115
116    void InputBuffer::set(const std::string& input, bool update)
117    {
118        this->clear(false);
119        this->insert(input, update);
120    }
121
122    void InputBuffer::insert(const std::string& input, bool update)
123    {
124        for (unsigned int i = 0; i < input.size(); ++i)
125        {
126            this->insert(input[i], false);
127
128            if (update)
129                this->updated(input[i], false);
130        }
131
132        if (update)
133            this->updated();
134    }
135
136    void InputBuffer::insert(const char& input, bool update)
137    {
138        if (this->charIsAllowed(input))
139        {
140            if (this->buffer_.size() >= this->maxLength_)
141                return;
142            this->buffer_.insert(this->cursor_, 1, input);
143            ++this->cursor_;
144        }
145
146        if (update)
147            this->updated(input, true);
148    }
149
150    void InputBuffer::clear(bool update)
151    {
152        this->buffer_.clear();
153        this->cursor_ = 0;
154
155        if (update)
156            this->updated();
157    }
158
159    void InputBuffer::removeBehindCursor(bool update)
160    {
161        if (this->cursor_ > 0)
162        {
163            --this->cursor_;
164            this->buffer_.erase(this->cursor_, 1);
165
166            if (update)
167                this->updated();
168        }
169    }
170
171    void InputBuffer::removeAtCursor(bool update)
172    {
173        if (this->cursor_ < this->buffer_.size())
174        {
175            this->buffer_.erase(this->cursor_, 1);
176
177            if (update)
178                this->updated();
179        }
180    }
181
182    void InputBuffer::updated()
183    {
184        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
185        {
186            if ((*it)->bListenToAllChanges_)
187                (*it)->callFunction();
188        }
189    }
190
191    void InputBuffer::updated(const char& update, bool bSingleInput)
192    {
193        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
194        {
195            if ((!(*it)->trueKeyFalseChar_) && ((*it)->bListenToAllChanges_ || ((*it)->char_ == update)) && (!(*it)->bOnlySingleInput_ || bSingleInput))
196                (*it)->callFunction();
197        }
198    }
199
200    bool InputBuffer::charIsAllowed(const char& input)
201    {
202        if (this->allowedChars_.empty())
203            return true;
204        else
205            return (this->allowedChars_.find(input) != std::string::npos);
206    }
207
208
209    void InputBuffer::processKey(const KeyEvent& evt)
210    {
211        // Prevent disaster when switching applications
212        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
213            return;
214
215        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
216        {
217            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode()))
218                (*it)->callFunction();
219        }
220
221        if (evt.isModifierDown(KeyboardModifier::Ctrl))
222        {
223            if (evt.getKeyCode() == KeyCode::V)
224                this->insert(fromClipboard());
225            else if (evt.getKeyCode() == KeyCode::C)
226                toClipboard(this->buffer_);
227            else if (evt.getKeyCode() == KeyCode::X)
228            {
229                toClipboard(this->buffer_);
230                this->clear();
231            }
232        }
233        else if (evt.isModifierDown(KeyboardModifier::Shift))
234        {
235            if (evt.getKeyCode() == KeyCode::Insert)
236                this->insert(fromClipboard());
237            else if (evt.getKeyCode() == KeyCode::Delete)
238            {
239                toClipboard(this->buffer_);
240                this->clear();
241            }
242        }
243
244        std::map<KeyCode::ByEnum, char>::iterator it = this->keyTranslator_.find(evt.getKeyCode());
245        if (it != this->keyTranslator_.end())
246            this->insert(it->second);
247        else
248            this->insert(static_cast<char>(evt.getText()));
249    }
250
251    /**
252        @brief This update() function is called by the InputState if the InputBuffer is active.
253        @param dt Delta time
254    */
255    void InputBuffer::keyboardUpdated(float dt)
256    {
257        timeSinceKeyPressed_ += dt;
258        if (keysToRepeat_ < 10 && timeSinceKeyPressed_ > keyRepeatDeleay_)
259        {
260            // initial time out has gone by, start repeating keys
261            while (timeSinceKeyPressed_ - timeSinceKeyRepeated_ > keyRepeatTime_)
262            {
263                timeSinceKeyRepeated_ += keyRepeatTime_;
264                keysToRepeat_++;
265            }
266        }
267    }
268
269    void InputBuffer::buttonPressed(const KeyEvent& evt)
270    {
271        lastKey_ = evt.getKeyCode();
272        timeSinceKeyPressed_ = 0.0;
273        timeSinceKeyRepeated_ = keyRepeatDeleay_;
274        keysToRepeat_ = 0;
275
276        processKey(evt);
277    }
278
279    void InputBuffer::buttonHeld(const KeyEvent& evt)
280    {
281        if (evt.getKeyCode() == lastKey_)
282        {
283            while (keysToRepeat_)
284            {
285                processKey(evt);
286                keysToRepeat_--;
287            }
288        }
289    }
290}
Note: See TracBrowser for help on using the repository browser.