Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/orxonox/ChatInputHandler.cc @ 8085

Last change on this file since 8085 was 8079, checked in by landauf, 14 years ago

merged usability branch back to trunk

incomplete summary of the changes in this branch:

  • enhanced keyboard navigation in GUIs
  • implemented new graphics menu and changeable window size at runtime
  • added developer mode
  • HUD shows if game is paused, game pauses if ingame menu is opened
  • removed a few obsolete commands and hid some that are more for internal use
  • numpad works in console and gui
  • faster loading of level info
  • enhanced usage of compositors (Shader class)
  • improved camera handling, configurable FOV and aspect ratio
  • Property svn:eol-style set to native
File size: 10.5 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 <string>
33#include <CEGUIWindow.h>
34#include <CEGUIWindowManager.h>
35#include <elements/CEGUIListbox.h>
36#include <elements/CEGUIListboxItem.h>
37#include <elements/CEGUIListboxTextItem.h>
38
39#include "util/ScopedSingletonManager.h"
40#include "core/CoreIncludes.h"
41#include "core/GUIManager.h"
42#include "core/command/ConsoleCommand.h"
43#include "core/input/InputBuffer.h"
44#include "core/input/InputManager.h"
45#include "core/input/InputState.h"
46#include "network/Host.h"
47
48#include "PlayerManager.h"
49#include "infos/PlayerInfo.h"
50
51namespace orxonox
52{
53  /* singleton */
54  ManageScopedSingleton( ChatInputHandler, ScopeID::Graphics, false );
55
56  /* add commands to console */
57  SetConsoleCommand( "startchat", &ChatInputHandler::activate_static );
58  SetConsoleCommand( "startchat_small", &ChatInputHandler::activate_small_static );
59
60  /* constructor */
61  ChatInputHandler::ChatInputHandler()
62  {
63    /* register the object  */
64    RegisterObject(ChatInputHandler);
65
66    /* create necessary objects */
67    this->inpbuf = new InputBuffer();
68    this->disp_offset = 0;
69    assert( this->inpbuf != NULL );
70
71    /* generate chatbox ui and chatbox-inputonly ui */
72    GUIManager::getInstance().loadGUI( "ChatBox" );
73    GUIManager::getInstance().loadGUI( "ChatBox-inputonly" );
74
75    /* setup colors */
76    setupColors();
77
78    /* configure the input buffer */
79    configureInputBuffer();
80
81    this->inputState = InputManager::getInstance().createInputState( "chatinput", false, false, InputStatePriority::Dynamic );
82    this->inputState->setKeyHandler(this->inpbuf);
83  }
84
85  ChatInputHandler::~ChatInputHandler()
86  {
87    /* Clean up */
88    InputManager::getInstance().destroyState("chatinput");
89    delete this->inpbuf;
90  }
91
92  /* configure input buffer, sub for the constructor */
93  void ChatInputHandler::configureInputBuffer()
94  {
95    /* INSTALL CALLBACKS */
96    /* input has changed */
97    this->inpbuf->registerListener(this, &ChatInputHandler::inputChanged, true);
98
99    /* add a line */
100    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\r',   false);
101    this->inpbuf->registerListener(this, &ChatInputHandler::addline,         '\n',   false);
102
103    /* backspace */
104    this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\b',   true);
105    //this->inpbuf->registerListener(this, &ChatInputHandler::backspace,       '\177', true);
106
107    /* exit the chatinputhandler thingy (tbd) */
108    this->inpbuf->registerListener(this, &ChatInputHandler::exit,            '\033', true); // escape
109
110    /* delete character */
111    this->inpbuf->registerListener(this, &ChatInputHandler::deleteChar,      KeyCode::Delete);
112
113    /* cursor movement */
114    this->inpbuf->registerListener(this, &ChatInputHandler::cursorRight,     KeyCode::Right);
115    this->inpbuf->registerListener(this, &ChatInputHandler::cursorLeft,      KeyCode::Left);
116    this->inpbuf->registerListener(this, &ChatInputHandler::cursorEnd,       KeyCode::End);
117    this->inpbuf->registerListener(this, &ChatInputHandler::cursorHome,      KeyCode::Home);
118
119    /* GET WINDOW POINTERS */
120    input = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/input" );
121    inputonly = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox-inputonly/input" );
122
123    /* get pointer to the history window */
124    CEGUI::Window *history = CEGUI::WindowManager::getSingleton().getWindow( "orxonox/ChatBox/history" );
125
126    /* cast it to a listbox */
127    lb_history = dynamic_cast<CEGUI::Listbox*>(history);
128
129    /* assert wee */
130    assert( lb_history );
131  }
132
133  /* setup the colors, sub for the constructor */
134  void ChatInputHandler::setupColors()
135  {
136    /* auto variables */
137    float red = 1.0, green = 0.5, blue = 0.5;
138    int i = 0;
139
140    // three loops: red tones, blue tones and green tones
141    // reds
142    for( i = 0; i < NumberOfColors/3; ++i )
143    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
144      green += 0.2f, blue += 0.2f;
145    }
146
147    // greens
148    red = 0.5, green = 1, blue = 0.5;
149    for( ; i < NumberOfColors*2/3; ++i )
150    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
151      red += 0.2f, blue += 0.2f;
152    }
153
154    // blues
155    red = 0.5, green = 0.5, blue = 1;
156    for( ; i < NumberOfColors; ++i )
157    { this->text_colors[ i ] = CEGUI::colour( red, green, blue );
158      red += 0.2f, green += 0.2f;
159    }
160  }
161
162
163  /* activate, deactivate */
164  void ChatInputHandler::activate_static()
165  { ChatInputHandler::getInstance().activate( true ); }
166
167  void ChatInputHandler::activate_small_static()
168  { ChatInputHandler::getInstance().activate( false ); }
169
170  void ChatInputHandler::activate( bool full )
171  {
172    /* start listening */
173    InputManager::getInstance().enterState("chatinput");
174
175    /* MARK add spawning of chat widget stuff here.*/
176    if( full )
177      GUIManager::getInstance().showGUI( "ChatBox" );
178    else
179      GUIManager::getInstance().showGUI( "ChatBox-inputonly" );
180
181    this->fullchat = full;
182  }
183
184  void ChatInputHandler::deactivate()
185  {
186    /* stop listening */
187    InputManager::getInstance().leaveState("chatinput");
188
189    /* un-spawning of chat widget stuff */
190    GUIManager::getInstance().hideGUI( "ChatBox" );
191    GUIManager::getInstance().hideGUI( "ChatBox-inputonly" );
192  }
193
194
195  /* subs for incomingChat */
196  void ChatInputHandler::sub_setcolor( CEGUI::ListboxTextItem *tocolor,
197    std::string name )
198  {
199    /* sanity checks */
200    if( !tocolor )
201      COUT(2) << "Empty ListBoxTextItem given to "
202        "ChatInputhandler::sub_setcolor().\n";
203
204    /* "hash" the name */
205    int hash = 0;
206    for( int i = name.length(); i > 0; --i )
207      hash += name[i-1];
208    hash = hash % this->NumberOfColors;
209
210    /* set the color according to the hash */
211    tocolor->setTextColours( this->text_colors[ hash ] );
212  }
213
214  /* handle incoming chat */
215  void ChatInputHandler::incomingChat(const std::string& message,
216    unsigned int senderID)
217  {
218    /* look up the actual name of the sender */
219    std::string text, name = "unknown";
220
221    /* setup player name info */
222    if (senderID != CLIENTID_UNKNOWN)
223    {
224       PlayerInfo* player = PlayerManager::getInstance().getClient(senderID);
225       if (player)
226         name = player->getName();
227    }
228
229    /* assemble the text */
230    text = name + ": " + message;
231
232    /* create item */
233    CEGUI::ListboxTextItem *toadd = new CEGUI::ListboxTextItem( text );
234
235    /* setup colors */
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      sub_adjust_dispoffset( (int)(this->input->getUnclippedInnerRect().getWidth()/6),
289        cursorpos, assembled.length() );
290      this->input->setProperty( "Text", assembled.substr( disp_offset ) );
291    }
292    else
293    {
294      /* adjust curser position - magic number 5 for font width */
295      sub_adjust_dispoffset( (int)(this->inputonly->getUnclippedInnerRect().getWidth()/6),
296        cursorpos, assembled.length() );
297      this->inputonly->setProperty( "Text", assembled.substr( disp_offset) );
298    }
299
300    /* reset display offset */
301    disp_offset = 0;
302  }
303
304  void ChatInputHandler::addline()
305  {
306    /* actually do send what was input */
307    /* a) get the string out of the inputbuffer */
308    std::string msgtosend = this->inpbuf->get();
309
310    if( msgtosend.length() == 0 )
311    { this->deactivate();
312      return;
313    }
314
315    /* b) clear the input buffer */
316    if (this->inpbuf->getSize() > 0)
317      this->inpbuf->clear();
318
319    /* c) send the chat via some call */
320    Host::Chat( msgtosend );
321
322    /* d) stop listening to input - only if this is not fullchat */
323    if( !this->fullchat )
324      this->deactivate();
325
326  }
327
328  void ChatInputHandler::backspace()
329  { this->inpbuf->removeBehindCursor(); }
330
331  void ChatInputHandler::deleteChar()
332  { this->inpbuf->removeAtCursor(); }
333
334  void ChatInputHandler::cursorRight()
335  { this->inpbuf->increaseCursor(); }
336
337  void ChatInputHandler::cursorLeft()
338  { this->inpbuf->decreaseCursor(); }
339
340  void ChatInputHandler::cursorEnd()
341  { this->inpbuf->setCursorToEnd(); }
342
343  void ChatInputHandler::cursorHome()
344  { this->inpbuf->setCursorToBegin(); }
345
346  void ChatInputHandler::exit()
347  {
348    /* b) clear the input buffer */
349    if (this->inpbuf->getSize() > 0)
350      this->inpbuf->clear();
351
352    /* d) stop listening to input  */
353    this->deactivate();
354  }
355
356}
Note: See TracBrowser for help on using the repository browser.