Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7465 was 7458, checked in by bensch, 19 years ago

trunk: Single Line in ShellCommand again

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