Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/resources/src/lib/shell/shell_input.cc @ 9783

Last change on this file since 9783 was 7221, checked in by bensch, 19 years ago

orxonox/trunk: merged the std-branche back, it runs on windows and Linux

svn merge https://svn.orxonox.net/orxonox/branches/std . -r7202:HEAD

File size: 7.7 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "shell_input.h"
19
20
21
22#include "shell_command.h"
23#include "shell_command_class.h"
24#include "shell_completion.h"
25#include "event_handler.h"
26
27#include "debug.h"
28#include "compiler.h"
29#include "stdlibincl.h"
30#include "key_names.h"
31
32
33using namespace std;
34
35SHELL_COMMAND(help, ShellInput, help)
36    ->describe("retrieve some help about the input mode")
37    ->setAlias("help");
38
39/**
40 * constructor
41 * this also generates a ShellCompletion automatically.
42*/
43ShellInput::ShellInput () : Text ("")
44{
45  this->pressedKey = SDLK_FIRST;
46  this->setClassID(CL_SHELL_INPUT, "ShellInput");
47
48  this->inputLine = "";
49  this->historyIT = this->history.begin();
50  this->setHistoryLength(50);
51  this->historyScrolling = false;
52  this->delayed = 0;
53  this->setRepeatDelay(.3, .05);
54
55  // subscribe all keyboard commands to ES_SEHLL
56  EventHandler* evh = EventHandler::getInstance();
57  for (int i = 1; i < SDLK_LAST; i++)
58  {
59    if (!evh->isSubscribed(ES_SHELL, i))
60      evh->subscribe(this, ES_SHELL, i);
61  }
62  this->completion = new ShellCompletion(this);
63}
64
65/**
66 * standard deconstructor
67*/
68ShellInput::~ShellInput ()
69{
70  // delete what has to be deleted here
71  delete this->completion;
72
73  while (!this->history.empty())
74  {
75    this->history.pop_front();
76  }
77}
78
79/**
80 * sets the Repeate-delay and rate
81 * @param repeatDelay the Delay it takes, to repeate a key
82 * @param repeatRate the rate to repeate a pressed key
83 */
84void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)
85{
86  this->repeatDelay = repeatDelay;
87  this->repeatRate = repeatRate;
88}
89
90/**
91 * deletes the InputLine
92 */
93void ShellInput::flush()
94{
95  this->inputLine.clear();
96  this->setText(this->inputLine);
97}
98
99/**
100 * sets the entire text of the InputLine to text
101 * @param text the new Text to set as InputLine
102 */
103void ShellInput::setInputText(const std::string& text)
104{
105  this->inputLine = text;
106  this->setText(this->inputLine);
107}
108
109
110/**
111 * adds one character to the inputLine
112 * @param character the character to add to the inputLine
113 */
114void ShellInput::addCharacter(char character)
115{
116  if (this->historyScrolling)
117  {
118    this->history.pop_back();
119    this->historyScrolling = false;
120  }
121
122  this->inputLine += character;
123  this->setText(this->inputLine);
124}
125
126/**
127 * adds multiple Characters to thr inputLine
128 * @param characters a \\0 terminated char-array to add to the InputLine
129 */
130void ShellInput::addCharacters(const std::string& characters)
131{
132  if (this->historyScrolling)
133  {
134    this->history.pop_back();
135    this->historyScrolling = false;
136  }
137
138  this->inputLine += characters;
139  this->setText(this->inputLine);
140}
141
142/**
143 * removes characterCount characters from the InputLine
144 * @param characterCount the count of Characters to remove from the input Line
145 */
146void ShellInput::removeCharacters(unsigned int characterCount)
147{
148  if (this->historyScrolling)
149  {
150    this->history.pop_back();
151    this->historyScrolling = false;
152  }
153  if (this->inputLine.size() < characterCount)
154    characterCount = this->inputLine.size();
155
156  this->inputLine.erase(this->inputLine.size() - characterCount, this->inputLine.size());
157  this->setText(this->inputLine);
158}
159
160/**
161 * executes the command stored in the inputLine
162 * @return true if the command was commited successfully, false otherwise
163 */
164bool ShellInput::executeCommand()
165{
166  ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine.c_str());
167
168  if (this->inputLine.empty())
169    return false;
170
171  ShellCommand::execute(this->inputLine);
172
173  // removing the eventually added Entry (from scrolling) to the List
174  if (this->historyScrolling)
175  {
176    this->history.pop_back();
177    this->historyScrolling = false;
178  }
179
180  // adding the new Command to the History
181  this->history.push_back(this->inputLine);
182  if (this->history.size() > this->historyLength)
183  {
184    this->history.pop_front();
185  }
186
187  this->flush();
188
189  return true;
190}
191
192
193/**
194 * moves one entry up in the history.
195 */
196void ShellInput::historyMoveUp()
197{
198  if (!this->historyScrolling)
199  {
200    this->history.push_back(this->inputLine);
201    this->historyScrolling = true;
202    this->historyIT = --this->history.end();
203  }
204
205  if(this->historyIT != this->history.begin())
206  {
207    std::string prevElem = *(--this->historyIT);
208    /*if (prevElem == NULL) /// TODO STD
209      return;
210    else */
211    {
212      this->flush();
213      this->setInputText(prevElem);
214    }
215  }
216}
217
218/**
219 * moves one entry down in the history
220 */
221void ShellInput::historyMoveDown()
222{
223  if (!this->historyScrolling)
224    return;
225  if (this->historyIT != this->history.end())
226  {
227    std::string nextElem = *(++this->historyIT);
228    /*    if (nextElem == NULL) /// TODO FIX STD
229      return;
230    else */
231    {
232      this->flush();
233      this->setInputText(nextElem);
234    }
235  }
236}
237
238
239/**
240 * prints out some nice help about the Shell
241 */
242void ShellInput::help(const std::string& className, const std::string& functionName)
243{
244  printf("%s::%s\n", className.c_str(), functionName.c_str());
245
246  if (className.empty())
247  {
248    PRINT(0)("Help for the most important Shell-commands\n");
249    PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");
250    PRINT(0)("input order:\n");
251    PRINT(0)("ClassName [objectName] function [parameter1, [parameter2 ...]]  or\n");
252    PRINT(0)("Alias [parameter]\n");
253    PRINT(0)("- Also try 'help className'");
254  }
255  else if (!className.empty() && functionName.empty())
256  {
257    ShellCommandClass::help(className);
258    //PRINTF(1)("%s::%s\n", className, functionName);
259  }
260}
261
262/**
263 * ticks the ShellInput
264 * @param dt the time passed since the last update
265 */
266void ShellInput::tick(float dt)
267{
268  if (this->delayed > 0.0)
269    this->delayed -= dt;
270  else if (this->pressedKey != SDLK_FIRST )
271  {
272    this->delayed = this->repeatRate;
273    switch (this->pressedKey )
274    {
275      case SDLK_BACKSPACE:
276        this->removeCharacters(1);
277        break;
278      case SDLK_UP:
279        this->historyMoveUp();
280        break;
281      case SDLK_DOWN:
282        this->historyMoveDown();
283        break;
284      default:
285      {
286        if (likely(pressedKey < 127))
287          this->addCharacter(this->pressedKey);
288      }
289    }
290  }
291}
292
293/**
294 * listens for some event
295 * @param event the Event happened
296 */
297void ShellInput::process(const Event &event)
298{
299  if (event.bPressed)
300  {
301    PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type));
302    if (event.type == SDLK_F1)
303      this->help();
304    else if (event.type == SDLK_F2)
305    {
306      ;//this->debug();
307    }
308    else if (event.type == SDLK_UP)
309    {
310      this->historyMoveUp();
311      this->pressedKey = event.type;
312    }
313    else if (event.type == SDLK_DOWN)
314    {
315      this->historyMoveDown();
316      this->pressedKey = event.type;
317    }
318    else if (event.type == SDLK_TAB)
319      this->completion->autoComplete();
320    else if (event.type == SDLK_BACKSPACE)
321    {
322      this->delayed = this->repeatDelay;
323      this->pressedKey = SDLK_BACKSPACE;
324      this->removeCharacters(1);
325    }
326    else if (event.type == SDLK_RETURN)
327    {
328      this->executeCommand();
329      this->pressedKey = event.type;
330    }
331    // any other keyboard key
332    else if (likely(event.type < 127))
333    {
334      this->addCharacter(event.x);
335      this->pressedKey = event.x;
336    }
337    this->delayed = this->repeatDelay;
338  }
339  else // if(!event.bPressed)
340  {
341    if (this->pressedKey == event.x || this->pressedKey == event.type)
342    {
343      this->pressedKey = 0;
344      this->delayed = 0.0;
345    }
346  }
347}
Note: See TracBrowser for help on using the repository browser.