Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/chat/ChatInputHandler.cc @ 10535

Last change on this file since 10535 was 9675, checked in by landauf, 11 years ago

merged branch 'libs' back to trunk. orxonox now compiles and runs with ogre 1.8 and it compiles (but doesn't run) with cegui 0.8

  • Property svn:eol-style set to native
File size: 11.1 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
31#include <cassert>
32#include <cstddef>
33#include <string>
34
35#if CEGUI_VERSION >= 0x000800
36#   include <CEGUI/Window.h>
37#   include <CEGUI/WindowManager.h>
38#   include <CEGUI/widgets/Listbox.h>
39#   include <CEGUI/widgets/ListboxItem.h>
40#   include <CEGUI/widgets/ListboxTextItem.h>
41#else
42#   include <CEGUIWindow.h>
43#   include <CEGUIWindowManager.h>
44#   include <elements/CEGUIListbox.h>
45#   include <elements/CEGUIListboxItem.h>
46#   include <elements/CEGUIListboxTextItem.h>
47#endif
48
49#include "util/ScopedSingletonManager.h"
50#include "core/CoreIncludes.h"
51#include "core/GUIManager.h"
52#include "core/command/ConsoleCommand.h"
53#include "core/input/InputBuffer.h"
54#include "core/input/InputManager.h"
55#include "core/input/InputState.h"
56
57#include "chat/ChatManager.h"
58#include "PlayerManager.h"
59#include "infos/PlayerInfo.h"
60
61namespace orxonox
62{
63  /* singleton */
64  ManageScopedSingleton( ChatInputHandler, ScopeID::Graphics, false );
65
66  /* add commands to console */
67  SetConsoleCommand( "startchat", &ChatInputHandler::activate_static );
68  SetConsoleCommand( "startchat_small", &ChatInputHandler::activate_small_static );
69
70  /* constructor */
71  ChatInputHandler::ChatInputHandler()
72  {
73    /* register the object  */
74    RegisterObject(ChatInputHandler);
75
76    /* create necessary objects */
77    this->inpbuf = new InputBuffer();
78    this->disp_offset = 0;
79    assert( this->inpbuf != NULL );
80
81    /* generate chatbox ui and chatbox-inputonly ui */
82    GUIManager::getInstance().loadGUI( "ChatBox" );
83    GUIManager::getInstance().loadGUI( "ChatBox-inputonly" );
84
85    /* setup colors */
86    setupColors();
87
88    /* configure the input buffer */
89    configureInputBuffer();
90
91    this->inputState = InputManager::getInstance().createInputState( "chatinput", false, false, InputStatePriority::Dynamic );
92    this->inputState->setKeyHandler(this->inpbuf);
93  }
94
95  ChatInputHandler::~ChatInputHandler()
96  {
97    /* Clean up */
98    InputManager::getInstance().destroyState("chatinput");
99    delete this->inpbuf;
100  }
101
102  /* configure input buffer, sub for the constructor */
103  void ChatInputHandler::configureInputBuffer()
104  {
105    /* INSTALL CALLBACKS */
106    /* input has changed */
107    this->inpbuf->registerListener(this, &ChatInputHandler::inputChanged, true);
108
109    /* add a line */
110    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\r',   false);
111    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\n',   false);
112
113    /* backspace */
114    this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\b',   true);
115    //this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\177', true);
116
117    /* exit the chatinputhandler thingy (tbd) */
118    this->inpbuf->registerListener(this, &ChatInputHandler::exit,            '\033', true); // escape
119
120    /* delete character */
121    this->inpbuf->registerListener(this, &ChatInputHandler::deleteChar,      KeyCode::Delete);
122
123    /* cursor movement */
124    this->inpbuf->registerListener(this, &ChatInputHandler::cursorRight,     KeyCode::Right);
125    this->inpbuf->registerListener(this, &ChatInputHandler::cursorLeft,      KeyCode::Left);
126    this->inpbuf->registerListener(this, &ChatInputHandler::cursorEnd,       KeyCode::End);
127    this->inpbuf->registerListener(this, &ChatInputHandler::cursorHome,      KeyCode::Home);
128
129    /* GET WINDOW POINTERS */
130#if CEGUI_VERSION >= 0x000800
131    input = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getChild( "orxonox/ChatBox/input" );
132    inputonly = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getChild( "orxonox/ChatBox-inputonly/input" );
133    CEGUI::Window *history = CEGUI::System::getSingleton().getDefaultGUIContext().getRootWindow()->getChild( "orxonox/ChatBox/history" );
134#else
135    input = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/input" );
136    inputonly = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox-inputonly/input" );
137    CEGUI::Window *history = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/history" );
138#endif
139
140    /* cast it to a listbox */
141    lb_history = dynamic_cast<CEGUI::Listbox*>(history);
142
143    /* assert wee */
144    assert( lb_history );
145  }
146
147  /* setup the colors, sub for the constructor */
148  void ChatInputHandler::setupColors()
149  {
150    /* auto variables */
151    float red = 1.0, green = 0.5, blue = 0.5;
152    int i = 0;
153
154    // three loops: red tones, blue tones and green tones
155    // reds
156    for( i = 0; i < NumberOfColors/3; ++i )
157    { this->text_colors[ i ] = CEGUIColour( red, green, blue );
158      green += 0.2f, blue += 0.2f;
159    }
160
161    // greens
162    red = 0.5, green = 1, blue = 0.5;
163    for( ; i < NumberOfColors*2/3; ++i )
164    { this->text_colors[ i ] = CEGUIColour( red, green, blue );
165      red += 0.2f, blue += 0.2f;
166    }
167
168    // blues
169    red = 0.5, green = 0.5, blue = 1;
170    for( ; i < NumberOfColors; ++i )
171    { this->text_colors[ i ] = CEGUIColour( red, green, blue );
172      red += 0.2f, green += 0.2f;
173    }
174  }
175
176
177  /* activate, deactivate */
178  void ChatInputHandler::activate_static()
179  { ChatInputHandler::getInstance().activate( true ); }
180
181  void ChatInputHandler::activate_small_static()
182  { ChatInputHandler::getInstance().activate( false ); }
183
184  void ChatInputHandler::activate( bool full )
185  {
186    /* start listening */
187    InputManager::getInstance().enterState("chatinput");
188
189    /* MARK add spawning of chat widget stuff here.*/
190    if( full )
191      GUIManager::getInstance().showGUI( "ChatBox" );
192    else
193      GUIManager::getInstance().showGUI( "ChatBox-inputonly" );
194
195    this->fullchat = full;
196  }
197
198  void ChatInputHandler::deactivate()
199  {
200    /* stop listening */
201    InputManager::getInstance().leaveState("chatinput");
202
203    /* un-spawning of chat widget stuff */
204    GUIManager::getInstance().hideGUI( "ChatBox" );
205    GUIManager::getInstance().hideGUI( "ChatBox-inputonly" );
206  }
207
208
209  /* subs for incomingChat */
210  void ChatInputHandler::sub_setcolor( CEGUI::ListboxTextItem *tocolor,
211    std::string name )
212  {
213    /* sanity checks */
214    if( !tocolor )
215      orxout(internal_warning) << "Empty ListBoxTextItem given to "
216        "ChatInputhandler::sub_setcolor()." << endl;
217
218    /* "hash" the name */
219    int hash = 0;
220    for( int i = name.length(); i > 0; --i )
221      hash += name[i-1];
222    hash = hash % this->NumberOfColors;
223
224    /* set the color according to the hash */
225    tocolor->setTextColours( this->text_colors[ hash ] );
226  }
227
228  /* handle incoming chat */
229  void ChatInputHandler::incomingChat(const std::string& message, const std::string& name)
230  {
231    /* create item */
232    CEGUI::ListboxTextItem *toadd = new CEGUI::ListboxTextItem( message );
233
234    /* setup colors */
235    if (name != "")
236      sub_setcolor( toadd, name );
237
238    /* now add */
239    this->lb_history->addItem( dynamic_cast<CEGUI::ListboxItem*>(toadd) );
240    this->lb_history->ensureItemIsVisible(
241      dynamic_cast<CEGUI::ListboxItem*>(toadd) );
242
243    /* make sure the history handles it */
244    this->lb_history->handleUpdatedItemData();
245  }
246
247
248  /* sub for inputchanged */
249  void ChatInputHandler::sub_adjust_dispoffset( int maxlen,
250    int cursorpos,
251    int inplen )
252  {
253    /* already start offsetting 5 characters before end */
254    if( cursorpos+5 > maxlen )
255    {
256      /* always stay 5 characters ahead of end, looks better */
257      ((disp_offset = cursorpos-maxlen+5) >= 0) ? 1 : disp_offset = 0;
258
259      /* enforce visibility of cursor */
260      (disp_offset > cursorpos ) ? disp_offset = 0 : 1;
261    }
262
263    /* make sure we don't die at substr */
264    if( inplen <= disp_offset ) disp_offset = 0;
265  }
266
267  /* callbacks for InputBuffer */
268  void ChatInputHandler::inputChanged()
269  {
270    /* update the cursor and the window */
271    std::string raw = this->inpbuf->get();
272    int cursorpos = this->inpbuf->getCursorPosition();
273
274    /* get string before cursor */
275    std::string left = raw.substr( 0, cursorpos );
276
277    /* see if there's a string after the cursor */
278    std::string right = "";
279    if( raw.length() >= left.length()+1 )
280      right = raw.substr( cursorpos );
281
282    /* set the text */
283    std::string assembled = "$ " + left + "|" + right;
284
285    if( this->fullchat )
286    {
287      /* adjust curser position - magic number 5 for font width */
288#if CEGUI_VERSION >= 0x000800
289      sub_adjust_dispoffset( (int)(this->input->getUnclippedInnerRect().get().getWidth()/6), cursorpos, assembled.length() );
290#else
291      sub_adjust_dispoffset( (int)(this->input->getUnclippedInnerRect().getWidth()/6), cursorpos, assembled.length() );
292#endif
293      this->input->setProperty( "Text", assembled.substr( disp_offset ) );
294    }
295    else
296    {
297      /* adjust curser position - magic number 5 for font width */
298#if CEGUI_VERSION >= 0x000800
299      sub_adjust_dispoffset( (int)(this->inputonly->getUnclippedInnerRect().get().getWidth()/6), cursorpos, assembled.length() );
300#else
301      sub_adjust_dispoffset( (int)(this->inputonly->getUnclippedInnerRect().getWidth()/6), cursorpos, assembled.length() );
302#endif
303      this->inputonly->setProperty( "Text", assembled.substr( disp_offset) );
304    }
305
306    /* reset display offset */
307    disp_offset = 0;
308  }
309
310  void ChatInputHandler::addline()
311  {
312    /* actually do send what was input */
313    /* a) get the string out of the inputbuffer */
314    std::string msgtosend = this->inpbuf->get();
315
316    if( msgtosend.length() == 0 )
317    { this->deactivate();
318      return;
319    }
320
321    /* b) clear the input buffer */
322    if (this->inpbuf->getSize() > 0)
323      this->inpbuf->clear();
324
325    /* c) send the chat via some call */
326    ChatManager::chat( msgtosend );
327
328    /* d) stop listening to input - only if this is not fullchat */
329    if( !this->fullchat )
330      this->deactivate();
331
332  }
333
334  void ChatInputHandler::backspace()
335  { this->inpbuf->removeBehindCursor(); }
336
337  void ChatInputHandler::deleteChar()
338  { this->inpbuf->removeAtCursor(); }
339
340  void ChatInputHandler::cursorRight()
341  { this->inpbuf->increaseCursor(); }
342
343  void ChatInputHandler::cursorLeft()
344  { this->inpbuf->decreaseCursor(); }
345
346  void ChatInputHandler::cursorEnd()
347  { this->inpbuf->setCursorToEnd(); }
348
349  void ChatInputHandler::cursorHome()
350  { this->inpbuf->setCursorToBegin(); }
351
352  void ChatInputHandler::exit()
353  {
354    /* b) clear the input buffer */
355    if (this->inpbuf->getSize() > 0)
356      this->inpbuf->clear();
357
358    /* d) stop listening to input  */
359    this->deactivate();
360  }
361
362}
Note: See TracBrowser for help on using the repository browser.