Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/gui/src/lib/shell/shell_input.cc @ 7897

Last change on this file since 7897 was 7874, checked in by bensch, 19 years ago

fixed the Shell

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