Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: moving up and down through the buffer with [PageUp] and [PageDown] enabled

File size: 8.8 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:
12   main-programmer: ...
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"
23#include "shell_completion.h"
[5180]24#include "event_handler.h"
[5179]25
26#include "debug.h"
27#include "list.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/**
[4838]40 * standard constructor
41 * @todo this constructor is not jet implemented - do it
[3245]42*/
[5178]43ShellInput::ShellInput ()
[3365]44{
[5179]45  this->pressedKey = SDLK_FIRST;
[5202]46  this->setClassID(CL_SHELL_INPUT, "ShellInput");
[4320]47
[5179]48  this->inputLine = new char[1];
49  this->inputLine[0] = '\0';
[5243]50  this->history = new tList<char>;
51  this->historyIT = this->history->getIterator();
[5245]52  this->setHistoryLength(50);
[5243]53  this->historyScrolling = false;
[5180]54  this->delayed = 0;
55  this->setRepeatDelay(.3, .05);
56
57  // subscribe all keyboard commands to ES_SEHLL
58  EventHandler* evh = EventHandler::getInstance();
59  for (int i = 1; i < SDLK_LAST; 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->inputLine;
72  delete this->completion;
[5182]73
[5243]74  char* histEl = this->historyIT->firstElement();
[5182]75  while (histEl != NULL)
76  {
77    delete[] histEl;
[5243]78    histEl = this->historyIT->nextElement();
[5182]79  }
[5243]80  delete this->historyIT;
81  delete this->history;
[3543]82}
[5179]83
84/**
85 * sets the Repeate-delay and rate
86 * @param repeatDelay the Delay it takes, to repeate a key
87 * @param repeatRate the rate to repeate a pressed key
88 */
89void ShellInput::setRepeatDelay(float repeatDelay, float repeatRate)
90{
91  this->repeatDelay = repeatDelay;
92  this->repeatRate = repeatRate;
93}
94
95/**
96 * deletes the InputLine
97 */
98void ShellInput::flush()
99{
100  if (likely(this->inputLine != NULL))
101  {
102    delete[] this->inputLine;
103  }
104  this->inputLine = new char[1];
105  *this->inputLine = '\0';
106  this->setText(this->inputLine, true);
107}
108
109/**
[5244]110 * sets the entire text of the InputLine to text
111 * @param text the new Text to set as InputLine
112 */
113void ShellInput::setInputText(const char* text)
114{
115  delete[] this->inputLine;
116  if (text == NULL)
117  {
118    this->inputLine = new char[1];
119    this->inputLine[0] = '\0';
120  }
121  else
122  {
123    this->inputLine = new char[strlen(text)+1];
124    strcpy(this->inputLine, text);
125  }
126  this->setText(this->inputLine, true);
127}
128
129
130/**
[5179]131 * adds one character to the inputLine
132 * @param character the character to add to the inputLine
133 */
134void ShellInput::addCharacter(char character)
135{
[5244]136  if (this->historyScrolling)
137  {
138    delete[] this->history->lastElement();
139    this->history->remove(this->history->lastElement());
140    this->historyScrolling = false;
141  }
142
[5182]143  char* addCharLine = new char[strlen(this->inputLine)+2];
[5179]144
145  sprintf(addCharLine, "%s%c", this->inputLine, character);
[5182]146  delete[] this->inputLine;
[5179]147  this->inputLine = addCharLine;
[5182]148  this->setText(this->inputLine, true);
[5179]149}
150
151/**
152 * adds multiple Characters to thr inputLine
153 * @param characters a \\0 terminated char-array to add to the InputLine
154 */
155void ShellInput::addCharacters(const char* characters)
156{
[5244]157  if (this->historyScrolling)
158  {
159    delete[] this->history->lastElement();
160    this->history->remove(this->history->lastElement());
161    this->historyScrolling = false;
162  }
163
[5182]164  char* addCharLine = new char[strlen(this->inputLine)+strlen(characters)+1];
[5179]165
166  sprintf(addCharLine, "%s%s", this->inputLine, characters);
[5182]167  delete[] this->inputLine;
[5179]168  this->inputLine = addCharLine;
[5182]169  this->setText(this->inputLine, true);
[5179]170}
171
172/**
173 * removes characterCount characters from the InputLine
174 * @param characterCount the count of Characters to remove from the input Line
175 */
176void ShellInput::removeCharacters(unsigned int characterCount)
177{
[5244]178  if (this->historyScrolling)
179  {
180    delete[] this->history->lastElement();
181    this->history->remove(this->history->lastElement());
182    this->historyScrolling = false;
183  }
184
[5179]185  if (strlen(this->inputLine) == 0)
186    return;
187
188  if (characterCount > strlen(this->inputLine))
189    characterCount = strlen(this->inputLine);
190
[5182]191  char* removeCharLine = new char[strlen(this->inputLine)-characterCount+1];
[5179]192
[5182]193  strncpy(removeCharLine, this->inputLine, strlen(this->inputLine)-characterCount);
194  removeCharLine[strlen(this->inputLine)-characterCount] = '\0';
195  delete[] this->inputLine;
[5179]196  this->inputLine = removeCharLine;
[5182]197  this->setText(this->inputLine, true);
[5179]198}
199
200/**
201 * executes the command stored in the inputLine
202 * @return true if the command was commited successfully, false otherwise
203 */
204bool ShellInput::executeCommand()
205{
206  ShellBuffer::addBufferLineStatic("Execute Command: %s\n", this->inputLine);
207
208  char* newCommand = new char[strlen(this->inputLine)+1];
209  strcpy(newCommand, this->inputLine);
210
[5243]211  // removing the eventually added Entry (from scrolling) to the List
212  if (this->historyScrolling)
213  {
214    delete[] this->history->lastElement();
[5244]215    this->history->remove(this->history->lastElement());
[5243]216    this->historyScrolling = false;
217  }
218
219  // adding the new Command to the History
220  this->history->add(newCommand);
221  if (this->history->getSize() > this->historyLength)
222  {
223    delete[] this->history->firstElement();
224    this->history->remove(this->history->firstElement());
225  }
226
[5179]227  ShellCommandBase::execute(this->inputLine);
228
229  this->flush();
230
231  return false;
232}
233
[5180]234
235/**
[5243]236 * moves one entry up in the history.
237 */
238void ShellInput::historyMoveUp()
239{
240  if (!this->historyScrolling)
241  {
[5244]242    char* currentText = new char[strlen(this->inputLine)+1];
243    strcpy(currentText, this->inputLine);
244    this->history->add(currentText);
[5243]245    this->historyScrolling = true;
246    this->historyIT->lastElement();
247  }
248
249  char* prevElem = this->historyIT->prevStep();
250  if (prevElem == NULL)
251    return;
252  else
253  {
254    this->flush();
[5244]255    this->setInputText(prevElem);
[5243]256  }
257}
258
259/**
260 * moves one entry down in the history
261 */
262void ShellInput::historyMoveDown()
263{
264  if (!this->historyScrolling)
265    return;
266  char* nextElem = this->historyIT->nextStep();
267  if (nextElem == NULL)
268    return;
269  else
270  {
271    this->flush();
[5244]272    this->setInputText(nextElem);
[5243]273  }
274}
275
276
277/**
[5180]278 * prints out some nice help about the Shell
279 */
[5204]280void ShellInput::help(const char* className, const char* functionName)
[5180]281{
[5207]282  printf("%s::%s\n", className, functionName);
283
[5204]284  if (strlen(className) == 0)
285  {
286    PRINT(0)("Help for the most important Shell-commands\n");
[5248]287    PRINT(0)("F1 - HELP; F2 - DEBUG; '`' - open/close shell\n");
[5204]288    PRINT(0)("input order:\n");
289    PRINT(0)("ClassName [objectName] function [parameter1, [parameter2 ...]]  or\n");
290    PRINT(0)("Alias [parameter]\n");
291    PRINT(0)("- Also try 'help className'");
292  }
293  else if (strlen (className) > 0 && strlen (functionName) == 0)
294  {
295    ShellCommandClass::help(className);
296    //PRINTF(1)("%s::%s\n", className, functionName);
297  }
[5180]298}
299
[5197]300/**
301 * ticks the ShellInput
302 * @param dt the time passed since the last update
303 */
[5180]304void ShellInput::tick(float dt)
305{
306  if (this->delayed > 0.0)
307    this->delayed -= dt;
308  else if (this->pressedKey != SDLK_FIRST )
309  {
310    this->delayed = this->repeatRate;
311    if (this->pressedKey == SDLK_BACKSPACE)
312      this->removeCharacters(1);
313    else if (pressedKey < 127)
314      this->addCharacter(this->pressedKey);
315  }
316}
317
318/**
319 * listens for some event
320 * @param event the Event happened
321 */
322void ShellInput::process(const Event &event)
323{
324  if (event.bPressed)
325  {
326    PRINTF(5)("Shell received command %s\n", SDLKToKeyname(event.type));
327    if (event.type == SDLK_F1)
328      this->help();
329    else if (event.type == SDLK_F2)
[5248]330      ;//this->debug();
[5243]331    else if (event.type == SDLK_UP)
332      this->historyMoveUp();
333    else if (event.type == SDLK_DOWN)
334      this->historyMoveDown();
[5180]335    else if (event.type == SDLK_TAB)
[5184]336      this->completion->autoComplete();
[5180]337    else if (event.type == SDLK_BACKSPACE)
338    {
339      this->delayed = this->repeatDelay;
340      this->pressedKey = SDLK_BACKSPACE;
341      this->removeCharacters(1);
342    }
343    else if (event.type == SDLK_RETURN)
344      this->executeCommand();
[5244]345    // any other keyboard key
[5180]346    else if (likely(event.type < 127))
347    {
348      Uint8 *keystate = SDL_GetKeyState(NULL);
349      this->delayed = this->repeatDelay;
350      if (unlikely( keystate[SDLK_LSHIFT] || keystate[SDLK_RSHIFT] ))
351      {
352        this->pressedKey = event.type-32;
353        this->addCharacter(event.type-32);
354      }
355      else
356      {
357        this->pressedKey = event.type;
358        this->addCharacter(event.type);
359      }
360    }
361  }
362  else // if(!event.bPressed)
363  {
364    if (this->pressedKey == event.type || (this->pressedKey == event.type - 32))
365    {
366      this->pressedKey = SDLK_FIRST;
367      this->delayed = 0.0;
368    }
369  }
370}
Note: See TracBrowser for help on using the repository browser.