Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7237 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
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
[3955]16//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
[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
[5180]32
[1856]33using namespace std;
[1853]34
[5202]35SHELL_COMMAND(help, ShellInput, help)
36    ->describe("retrieve some help about the input mode")
37    ->setAlias("help");
[5237]38
[3245]39/**
[5249]40 * constructor
41 * this also generates a ShellCompletion automatically.
[3245]42*/
[7221]43ShellInput::ShellInput () : Text ("")
[3365]44{
[5179]45  this->pressedKey = SDLK_FIRST;
[5202]46  this->setClassID(CL_SHELL_INPUT, "ShellInput");
[4320]47
[7221]48  this->inputLine = "";
[5784]49  this->historyIT = this->history.begin();
[5245]50  this->setHistoryLength(50);
[5243]51  this->historyScrolling = false;
[5180]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++)
[5309]58  {
59    if (!evh->isSubscribed(ES_SHELL, i))
60      evh->subscribe(this, ES_SHELL, i);
61  }
[5184]62  this->completion = new ShellCompletion(this);
[3365]63}
[1853]64
[3245]65/**
[4838]66 * standard deconstructor
[3245]67*/
[5178]68ShellInput::~ShellInput ()
[3543]69{
70  // delete what has to be deleted here
[5181]71  delete this->completion;
[5182]72
[5784]73  while (!this->history.empty())
[5182]74  {
[5784]75    this->history.pop_front();
[5182]76  }
[3543]77}
[5179]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{
[7221]95  this->inputLine.clear();
96  this->setText(this->inputLine);
[5179]97}
98
99/**
[5244]100 * sets the entire text of the InputLine to text
101 * @param text the new Text to set as InputLine
102 */
[7221]103void ShellInput::setInputText(const std::string& text)
[5244]104{
[7221]105  this->inputLine = text;
106  this->setText(this->inputLine);
[5244]107}
108
109
110/**
[5179]111 * adds one character to the inputLine
112 * @param character the character to add to the inputLine
113 */
114void ShellInput::addCharacter(char character)
115{
[5244]116  if (this->historyScrolling)
117  {
[5784]118    this->history.pop_back();
[5244]119    this->historyScrolling = false;
120  }
121
[7221]122  this->inputLine += character;
123  this->setText(this->inputLine);
[5179]124}
125
126/**
127 * adds multiple Characters to thr inputLine
128 * @param characters a \\0 terminated char-array to add to the InputLine
129 */
[7221]130void ShellInput::addCharacters(const std::string& characters)
[5179]131{
[5244]132  if (this->historyScrolling)
133  {
[5784]134    this->history.pop_back();
[5244]135    this->historyScrolling = false;
136  }
137
[7221]138  this->inputLine += characters;
139  this->setText(this->inputLine);
[5179]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{
[5244]148  if (this->historyScrolling)
149  {
[5784]150    this->history.pop_back();
[5244]151    this->historyScrolling = false;
152  }
[7221]153  if (this->inputLine.size() < characterCount)
154    characterCount = this->inputLine.size();
[5244]155
[7221]156  this->inputLine.erase(this->inputLine.size() - characterCount, this->inputLine.size());
157  this->setText(this->inputLine);
[5179]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{
[7221]166  ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine.c_str());
[5179]167
[7221]168  if (this->inputLine.empty())
[5369]169    return false;
170
[7221]171  ShellCommand::execute(this->inputLine);
[5179]172
[5243]173  // removing the eventually added Entry (from scrolling) to the List
174  if (this->historyScrolling)
175  {
[5784]176    this->history.pop_back();
[5243]177    this->historyScrolling = false;
178  }
179
180  // adding the new Command to the History
[7221]181  this->history.push_back(this->inputLine);
[5784]182  if (this->history.size() > this->historyLength)
[5243]183  {
[5784]184    this->history.pop_front();
[5243]185  }
186
[5179]187  this->flush();
188
[5369]189  return true;
[5179]190}
191
[5180]192
193/**
[5243]194 * moves one entry up in the history.
195 */
196void ShellInput::historyMoveUp()
197{
198  if (!this->historyScrolling)
199  {
[7221]200    this->history.push_back(this->inputLine);
[5243]201    this->historyScrolling = true;
[5785]202    this->historyIT = --this->history.end();
[5243]203  }
204
[5785]205  if(this->historyIT != this->history.begin())
[5243]206  {
[7221]207    std::string prevElem = *(--this->historyIT);
208    /*if (prevElem == NULL) /// TODO STD
[5785]209      return;
[7221]210    else */
[5785]211    {
212      this->flush();
213      this->setInputText(prevElem);
214    }
[5243]215  }
216}
217
218/**
219 * moves one entry down in the history
220 */
221void ShellInput::historyMoveDown()
222{
223  if (!this->historyScrolling)
224    return;
[5785]225  if (this->historyIT != this->history.end())
[5243]226  {
[7221]227    std::string nextElem = *(++this->historyIT);
228    /*    if (nextElem == NULL) /// TODO FIX STD
[5785]229      return;
[7221]230    else */
[5785]231    {
232      this->flush();
233      this->setInputText(nextElem);
234    }
[5243]235  }
236}
237
238
239/**
[5180]240 * prints out some nice help about the Shell
241 */
[7221]242void ShellInput::help(const std::string& className, const std::string& functionName)
[5180]243{
[7221]244  printf("%s::%s\n", className.c_str(), functionName.c_str());
[5207]245
[7221]246  if (className.empty())
[5204]247  {
248    PRINT(0)("Help for the most important Shell-commands\n");
[5248]249    PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");
[5204]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  }
[7221]255  else if (!className.empty() && functionName.empty())
[5204]256  {
257    ShellCommandClass::help(className);
258    //PRINTF(1)("%s::%s\n", className, functionName);
259  }
[5180]260}
261
[5197]262/**
263 * ticks the ShellInput
264 * @param dt the time passed since the last update
265 */
[5180]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;
[5786]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    }
[5180]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)
[5786]305    {
[5248]306      ;//this->debug();
[5786]307    }
[5243]308    else if (event.type == SDLK_UP)
[5786]309    {
[5243]310      this->historyMoveUp();
[5786]311      this->pressedKey = event.type;
312    }
[5243]313    else if (event.type == SDLK_DOWN)
[5786]314    {
[5243]315      this->historyMoveDown();
[5786]316      this->pressedKey = event.type;
317    }
[5180]318    else if (event.type == SDLK_TAB)
[5184]319      this->completion->autoComplete();
[5180]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)
[5786]327    {
[5180]328      this->executeCommand();
[5786]329      this->pressedKey = event.type;
330    }
[5244]331    // any other keyboard key
[5180]332    else if (likely(event.type < 127))
333    {
[5786]334      this->addCharacter(event.x);
335      this->pressedKey = event.x;
[5180]336    }
[5786]337    this->delayed = this->repeatDelay;
[5180]338  }
339  else // if(!event.bPressed)
340  {
[5787]341    if (this->pressedKey == event.x || this->pressedKey == event.type)
[5180]342    {
[5786]343      this->pressedKey = 0;
[5180]344      this->delayed = 0.0;
345    }
346  }
347}
Note: See TracBrowser for help on using the repository browser.