Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: saver font-changing in the Shell

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