Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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