Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/orxonox/ChatInputHandler.cc @ 7739

Last change on this file since 7739 was 7236, checked in by landauf, 14 years ago

replaced the temporary names of all ConsoleCommand related classes and functions by their real names

  • Property svn:eol-style set to native
File size: 10.3 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Sandro 'smerkli' Merkli
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29#include "ChatInputHandler.h"
30#include "util/ScopedSingletonManager.h"
31#include "core/CoreIncludes.h"
32#include "core/GUIManager.h"
33#include "core/CorePrereqs.h"
34#include "core/command/ConsoleCommand.h"
35#include <CEGUIWindow.h>
36#include <elements/CEGUIListbox.h>
37#include <elements/CEGUIListboxItem.h>
38#include <elements/CEGUIListboxTextItem.h>
39#include <CEGUIWindowManager.h>
40#include <string>
41
42namespace orxonox
43{
44  /* singleton */
45  ManageScopedSingleton( ChatInputHandler, ScopeID::Graphics, false );
46
47  /* add commands to console */
48  SetConsoleCommand( "startchat", &ChatInputHandler::activate_static );
49  SetConsoleCommand( "startchat_small", &ChatInputHandler::activate_small_static );
50
51  /* constructor */
52  ChatInputHandler::ChatInputHandler()
53  {
54    /* register the object  */
55    RegisterObject(ChatInputHandler);
56
57    /* create necessary objects */
58    this->inpbuf = new InputBuffer();
59    this->disp_offset = 0;
60    assert( this->inpbuf != NULL );
61
62    /* generate chatbox ui and chatbox-inputonly ui */
63    GUIManager::getInstance().loadGUI( "ChatBox" );
64    GUIManager::getInstance().loadGUI( "ChatBox-inputonly" );
65
66    /* setup colors */
67    setupColors();
68
69    /* configure the input buffer */
70    configureInputBuffer();
71
72    this->inputState = InputManager::getInstance().createInputState( "chatinput", false, false, InputStatePriority::Dynamic );
73    this->inputState->setKeyHandler(this->inpbuf);
74  }
75
76  /* configure input buffer, sub for the constructor */
77  void ChatInputHandler::configureInputBuffer()
78  {
79    /* INSTALL CALLBACKS */
80    /* input has changed */
81    this->inpbuf->registerListener(this, &ChatInputHandler::inputChanged, true);
82
83    /* add a line */
84    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\r',   false);
85    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\n',   false);
86
87    /* backspace */
88    this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\b',   true);
89    //this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\177', true);
90
91    /* exit the chatinputhandler thingy (tbd) */
92    this->inpbuf->registerListener(this, &ChatInputHandler::exit,            '\033', true); // escape
93
94    /* delete character */
95    this->inpbuf->registerListener(this, &ChatInputHandler::deleteChar,      KeyCode::Delete);
96
97    /* cursor movement */
98    this->inpbuf->registerListener(this, &ChatInputHandler::cursorRight,     KeyCode::Right);
99    this->inpbuf->registerListener(this, &ChatInputHandler::cursorLeft,      KeyCode::Left);
100    this->inpbuf->registerListener(this, &ChatInputHandler::cursorEnd,       KeyCode::End);
101    this->inpbuf->registerListener(this, &ChatInputHandler::cursorHome,      KeyCode::Home);
102
103    /* GET WINDOW POINTERS */
104    input = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/input" );
105    inputonly = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox-inputonly/input" );
106
107    /* get pointer to the history window */
108    CEGUI::Window *history = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/history" );
109
110    /* cast it to a listbox */
111    lb_history = dynamic_cast<CEGUI::Listbox*>(history);
112
113    /* assert wee */
114    assert( lb_history );
115  }
116
117  /* setup the colors, sub for the constructor */
118  void ChatInputHandler::setupColors()
119  {
120    /* auto variables */
121    float red = 1.0, green = 0.5, blue = 0.5;
122    int i = 0;
123
124    // three loops: red tones, blue tones and green tones
125    // reds
126    for( i = 0; i < NumberOfColors/3; ++i )
127    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
128      assert( this->text_colors[ i ] );
129      green += 0.2, blue += 0.2;
130    }
131
132    // greens
133    red = 0.5, green = 1, blue = 0.5;
134    for( ; i < NumberOfColors*2/3; ++i )
135    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
136      assert( this->text_colors[ i ] );
137      red += 0.2, blue += 0.2;
138    }
139
140    // blues
141    red = 0.5, green = 0.5, blue = 1;
142    for( ; i < NumberOfColors; ++i )
143    { this->text_colors[ i ] = new CEGUI::colour( red, green, blue );
144      assert( this->text_colors[ i ] );
145      red += 0.2, green += 0.2;
146    }
147  }
148
149
150  /* activate, deactivate */
151  void ChatInputHandler::activate_static()
152  { ChatInputHandler::getInstance().activate( true ); }
153
154  void ChatInputHandler::activate_small_static()
155  { ChatInputHandler::getInstance().activate( false ); }
156
157  void ChatInputHandler::activate( bool full )
158  {
159    /* start listening */
160    InputManager::getInstance().enterState("chatinput");
161
162    /* MARK add spawning of chat widget stuff here.*/
163    if( full )
164      GUIManager::getInstance().showGUI( "ChatBox" );
165    else
166      GUIManager::getInstance().showGUI( "ChatBox-inputonly" );
167
168    this->fullchat = full;
169  }
170
171  void ChatInputHandler::deactivate()
172  {
173    /* stop listening */
174    InputManager::getInstance().leaveState("chatinput");
175
176    /* un-spawning of chat widget stuff */
177    GUIManager::getInstance().hideGUI( "ChatBox" );
178    GUIManager::getInstance().hideGUI( "ChatBox-inputonly" );
179  }
180
181
182  /* subs for incomingChat */
183  void ChatInputHandler::sub_setcolor( CEGUI::ListboxTextItem *tocolor,
184    std::string name )
185  {
186    /* sanity checks */
187    if( !tocolor )
188      COUT(2) << "Empty ListBoxTextItem given to "
189        "ChatInputhandler::sub_setcolor().\n";
190
191    /* "hash" the name */
192    int hash = 0;
193    for( int i = name.length(); i > 0; --i )
194      hash += name[i-1];
195    hash = hash % this->NumberOfColors;
196
197    /* set the color according to the hash */
198    tocolor->setTextColours( *(this->text_colors[ hash ]) );
199  }
200
201  /* handle incoming chat */
202  void ChatInputHandler::incomingChat(const std::string& message,
203    unsigned int senderID)
204  {
205    /* look up the actual name of the sender */
206    std::string text, name = "unknown";
207
208    /* setup player name info */
209    if (senderID != CLIENTID_UNKNOWN)
210    {
211       PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
212       if (player)
213         name = player->getName();
214    }
215
216    /* assemble the text */
217    text = name + ": " + message;
218
219    /* create item */
220    CEGUI::ListboxTextItem *toadd = new CEGUI::ListboxTextItem( text );
221
222    /* setup colors */
223    sub_setcolor( toadd, name );
224
225    /* now add */
226    this->lb_history->addItem( dynamic_cast<CEGUI::ListboxItem*>(toadd) );
227    this->lb_history->ensureItemIsVisible(
228      dynamic_cast<CEGUI::ListboxItem*>(toadd) );
229
230    /* make sure the history handles it */
231    this->lb_history->handleUpdatedItemData();
232  }
233
234
235  /* sub for inputchanged */
236  void ChatInputHandler::sub_adjust_dispoffset( int maxlen,
237    int cursorpos,
238    int inplen )
239  {
240    /* already start offsetting 5 characters before end */
241    if( cursorpos+5 > maxlen )
242    {
243      /* always stay 5 characters ahead of end, looks better */
244      ((disp_offset = cursorpos-maxlen+5) >= 0) ? 1 : disp_offset = 0;
245
246      /* enforce visibility of cursor */
247      (disp_offset > cursorpos ) ? disp_offset = 0 : 1;
248    }
249
250    /* make sure we don't die at substr */
251    if( inplen <= disp_offset ) disp_offset = 0;
252  }
253
254  /* callbacks for InputBuffer */
255  void ChatInputHandler::inputChanged()
256  {
257    /* update the cursor and the window */
258    std::string raw = this->inpbuf->get();
259    int cursorpos = this->inpbuf->getCursorPosition();
260
261    /* get string before cursor */
262    std::string left = raw.substr( 0, cursorpos );
263
264    /* see if there's a string after the cursor */
265    std::string right = "";
266    if( raw.length() >= left.length()+1 )
267      right = raw.substr( cursorpos );
268
269    /* set the text */
270    std::string assembled = "$ " + left + "|" + right;
271
272    if( this->fullchat )
273    {
274      /* adjust curser position - magic number 5 for font width */
275      sub_adjust_dispoffset( (this->input->getUnclippedInnerRect().getWidth()/6),
276        cursorpos, assembled.length() );
277      this->input->setProperty( "Text", assembled.substr( disp_offset ) );
278    }
279    else
280    {
281      /* adjust curser position - magic number 5 for font width */
282      sub_adjust_dispoffset( (this->inputonly->getUnclippedInnerRect().getWidth()/6),
283        cursorpos, assembled.length() );
284      this->inputonly->setProperty( "Text", assembled.substr( disp_offset) );
285    }
286
287    /* reset display offset */
288    disp_offset = 0;
289  }
290
291  void ChatInputHandler::addline()
292  {
293    /* actually do send what was input */
294    /* a) get the string out of the inputbuffer */
295    std::string msgtosend = this->inpbuf->get();
296
297    if( msgtosend.length() == 0 )
298    { this->deactivate();
299      return;
300    }
301
302    /* b) clear the input buffer */
303    if (this->inpbuf->getSize() > 0)
304      this->inpbuf->clear();
305
306    /* c) send the chat via some call */
307    Host::Chat( msgtosend );
308
309    /* d) stop listening to input - only if this is not fullchat */
310    if( !this->fullchat )
311      this->deactivate();
312
313  }
314
315  void ChatInputHandler::backspace()
316  { this->inpbuf->removeBehindCursor(); }
317
318  void ChatInputHandler::deleteChar()
319  { this->inpbuf->removeAtCursor(); }
320
321  void ChatInputHandler::cursorRight()
322  { this->inpbuf->increaseCursor(); }
323
324  void ChatInputHandler::cursorLeft()
325  { this->inpbuf->decreaseCursor(); }
326
327  void ChatInputHandler::cursorEnd()
328  { this->inpbuf->setCursorToEnd(); }
329
330  void ChatInputHandler::cursorHome()
331  { this->inpbuf->setCursorToBegin(); }
332
333  void ChatInputHandler::exit()
334  {
335    /* b) clear the input buffer */
336    if (this->inpbuf->getSize() > 0)
337      this->inpbuf->clear();
338
339    /* d) stop listening to input  */
340    this->deactivate();
341  }
342
343}
Note: See TracBrowser for help on using the repository browser.