Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

moved keycode translator from InputBuffer to Keyboard, now it works also in the GUI

  • Property svn:eol-style set to native
File size: 7.7 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->lastKey_ = KeyCode::Unassigned;
50        this->timeSinceKeyPressed_ = 0.0f;
51        this->timeSinceKeyRepeated_ = 0.0f;
52        this->keysToRepeat_ = 0;
53
54        setConfigValues();
55    }
56
57    InputBuffer::InputBuffer(const std::string& allowedChars)
58    {
59        RegisterRootObject(InputBuffer);
60
61        this->maxLength_ = 1024;
62        this->allowedChars_ = allowedChars;
63        this->cursor_ = 0;
64
65        this->lastKey_ = KeyCode::Unassigned;
66        this->timeSinceKeyPressed_ = 0.0f;
67        this->timeSinceKeyRepeated_ = 0.0f;
68        this->keysToRepeat_ = 0;
69
70        setConfigValues();
71    }
72
73    InputBuffer::~InputBuffer()
74    {
75        for (std::list<BaseInputBufferListenerTuple*>::const_iterator it = this->listeners_.begin();
76            it != this->listeners_.end(); ++it)
77            delete *it;
78    }
79
80    void InputBuffer::setConfigValues()
81    {
82        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat delay of the input buffer");
83        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
84
85        if (keyRepeatDeleay_ < 0.0)
86        {
87            ResetConfigValue(keyRepeatDeleay_);
88        }
89        if (keyRepeatTime_ < 0.0)
90        {
91            ResetConfigValue(keyRepeatTime_);
92        }
93    }
94
95    void InputBuffer::setMaxLength(unsigned int length)
96    {
97        this->maxLength_ = length;
98        if (this->buffer_.size() > length)
99            this->buffer_.resize(length);
100    }
101
102    void InputBuffer::set(const std::string& input, bool update)
103    {
104        this->clear(false);
105        this->insert(input, update);
106    }
107
108    void InputBuffer::insert(const std::string& input, bool update)
109    {
110        for (unsigned int i = 0; i < input.size(); ++i)
111        {
112            this->insert(input[i], false);
113
114            if (update)
115                this->updated(input[i], false);
116        }
117
118        if (update)
119            this->updated();
120    }
121
122    void InputBuffer::insert(const char& input, bool update)
123    {
124        if (this->charIsAllowed(input))
125        {
126            if (this->buffer_.size() >= this->maxLength_)
127                return;
128            this->buffer_.insert(this->cursor_, 1, input);
129            ++this->cursor_;
130        }
131
132        if (update)
133            this->updated(input, true);
134    }
135
136    void InputBuffer::clear(bool update)
137    {
138        this->buffer_.clear();
139        this->cursor_ = 0;
140
141        if (update)
142            this->updated();
143    }
144
145    void InputBuffer::removeBehindCursor(bool update)
146    {
147        if (this->cursor_ > 0)
148        {
149            --this->cursor_;
150            this->buffer_.erase(this->cursor_, 1);
151
152            if (update)
153                this->updated();
154        }
155    }
156
157    void InputBuffer::removeAtCursor(bool update)
158    {
159        if (this->cursor_ < this->buffer_.size())
160        {
161            this->buffer_.erase(this->cursor_, 1);
162
163            if (update)
164                this->updated();
165        }
166    }
167
168    void InputBuffer::updated()
169    {
170        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
171        {
172            if ((*it)->bListenToAllChanges_)
173                (*it)->callFunction();
174        }
175    }
176
177    void InputBuffer::updated(const char& update, bool bSingleInput)
178    {
179        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
180        {
181            if ((!(*it)->trueKeyFalseChar_) && ((*it)->bListenToAllChanges_ || ((*it)->char_ == update)) && (!(*it)->bOnlySingleInput_ || bSingleInput))
182                (*it)->callFunction();
183        }
184    }
185
186    bool InputBuffer::charIsAllowed(const char& input)
187    {
188        if (this->allowedChars_.empty())
189            return true;
190        else
191            return (this->allowedChars_.find(input) != std::string::npos);
192    }
193
194
195    void InputBuffer::processKey(const KeyEvent& evt)
196    {
197        // Prevent disaster when switching applications
198        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
199            return;
200
201        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
202        {
203            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.getKeyCode()))
204                (*it)->callFunction();
205        }
206
207        if (evt.isModifierDown(KeyboardModifier::Ctrl))
208        {
209            if (evt.getKeyCode() == KeyCode::V)
210                this->insert(fromClipboard());
211            else if (evt.getKeyCode() == KeyCode::C)
212                toClipboard(this->buffer_);
213            else if (evt.getKeyCode() == KeyCode::X)
214            {
215                toClipboard(this->buffer_);
216                this->clear();
217            }
218        }
219        else if (evt.isModifierDown(KeyboardModifier::Shift))
220        {
221            if (evt.getKeyCode() == KeyCode::Insert)
222                this->insert(fromClipboard());
223            else if (evt.getKeyCode() == KeyCode::Delete)
224            {
225                toClipboard(this->buffer_);
226                this->clear();
227            }
228        }
229
230        this->insert(static_cast<char>(evt.getText()));
231    }
232
233    /**
234        @brief This update() function is called by the InputState if the InputBuffer is active.
235        @param dt Delta time
236    */
237    void InputBuffer::keyboardUpdated(float dt)
238    {
239        timeSinceKeyPressed_ += dt;
240        if (keysToRepeat_ < 10 && timeSinceKeyPressed_ > keyRepeatDeleay_)
241        {
242            // initial time out has gone by, start repeating keys
243            while (timeSinceKeyPressed_ - timeSinceKeyRepeated_ > keyRepeatTime_)
244            {
245                timeSinceKeyRepeated_ += keyRepeatTime_;
246                keysToRepeat_++;
247            }
248        }
249    }
250
251    void InputBuffer::buttonPressed(const KeyEvent& evt)
252    {
253        lastKey_ = evt.getKeyCode();
254        timeSinceKeyPressed_ = 0.0;
255        timeSinceKeyRepeated_ = keyRepeatDeleay_;
256        keysToRepeat_ = 0;
257
258        processKey(evt);
259    }
260
261    void InputBuffer::buttonHeld(const KeyEvent& evt)
262    {
263        if (evt.getKeyCode() == lastKey_)
264        {
265            while (keysToRepeat_)
266            {
267                processKey(evt);
268                keysToRepeat_--;
269            }
270        }
271    }
272}
Note: See TracBrowser for help on using the repository browser.