Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/shell/shell_input.cc @ 7740

Last change on this file since 7740 was 7729, checked in by bensch, 19 years ago

orxonox/trunk: better debug names
As DEBUG and ERROR are already given to windows.h and other files:
DEBUG is renamed to DEBUG_LEVEL
and all
NO, ERR, WARN, INFO, DEBUG, vDEBUG
are renamed to
ORX_NONE, ORX_ERR, ORX_WARN, ORX_INFO, ORX_DEBUG, ORX_vDEBUG

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