00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "Teddy/TeddyConfig.h"
00026 #include "Teddy/PhysicalComponents/Console.h"
00027 #include "Teddy/PhysicalComponents/Style.h"
00028 #include "Teddy/PhysicalComponents/GradientFill.h"
00029 #include "Teddy/PhysicalComponents/WindowManager.h"
00030 #include "Teddy/PhysicalComponents/Label.h"
00031 #include "Teddy/Graphics/Color.h"
00032 #include "Teddy/Graphics/Font.h"
00033 #include "Teddy/Graphics/View.h"
00034 #include "Teddy/SysSupport/Messages.h"
00035 #include "Teddy/SysSupport/StdIO.h"
00036 #ifndef SWIG
00037 #include <cstdlib>
00038 using namespace std;
00039 #endif
00040 using namespace Teddy::Graphics;
00041 using namespace Teddy::Signals;
00042
00043
00044 namespace Teddy {
00045 namespace PhysicalComponents {
00046
00047
00049 Console::Console( const std::string &name, const int w, const int h )
00050 :Area( name )
00051 {
00052 this->font_width = style->monospace_font->getWidth();
00053 this->font_height = style->monospace_font->getHeight();
00054 this->width_chars = w;
00055 this->height_chars = h;
00056 this->max_height_chars = h;
00057
00058
00059 buffer_lines.reserve( 200 );
00060 for( int i=0; i<h; i++ ){
00061 buffer_lines.push_back( new string("") );
00062 }
00063
00064 topleft_x = 0;
00065 topleft_y = 0;
00066 cx = 0;
00067 cy = 0;
00068 cursor_visible = true;
00069 text_color = Color::GRAY_75;
00070
00071
00072 fill_base_pixels[0] = w * font_width;
00073 fill_base_pixels[1] = h * font_height;
00074
00075
00076
00077
00078 GradientFill *fill = new GradientFill(
00079 Color( 0.2f, 0.3f, 0.4f, 0.99f ),
00080 Color( 0.2f, 0.3f, 0.4f, 0.99f ),
00081 Color( 0.1f, 0.2f, 0.3f, 0.66f ),
00082 Color( 0.1f, 0.2f, 0.3f, 0.66f )
00083 );
00084
00085 this->insert( fill );
00086
00087
00088 drawing_ordering = post_self;
00089
00090 bind( Event::WindowFocusActiveEvent_ID, functor( this, &Console::focusActive ) );
00091 bind( Event::KeyDownEvent_ID , functor( this, &Console::keyDown ) );
00092 }
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00137
00142 #if 0
00143 void Console::setSize( const int width, const int height ){
00144 Area::setSize( width, height );
00145
00146
00147 width_chars = width / style->monospace_font->getWidth ();
00148 height_chars = height / style->monospace_font->getHeight();
00149
00150
00151
00152
00153
00154 if( topleft_y < 0 ){
00155
00156 topleft_y = 0;
00157 }
00158 }
00159 #endif
00160
00161
00163 void Console::drawSelf(){
00164 color( text_color );
00165 view->enable( View::BLEND );
00166 view->enable( View::TEXTURE_2D );
00167 view->setBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
00168
00169
00170
00171 for( int y=0; y<height_chars && (long)(y+topleft_y)<(long)(buffer_lines.size()); y++ ){
00172 string line = buffer_lines[y+topleft_y]->substr( topleft_x, width_chars );
00173 Vector2 pos( 0.0f, (float)(font_height * y) );
00174
00175 drawString( pos, line.c_str(), style->monospace_font );
00176 }
00177
00178
00179 if(
00180 cursor_visible &&
00181 (cx-topleft_x)< width_chars &&
00182 (cy-topleft_y)< height_chars &&
00183 cx>=topleft_x &&
00184 cy>=topleft_y
00185 ){
00186 Vector2 cpos( (cx-topleft_x)*font_width, (cy-topleft_y)*font_height );
00187 drawString( cpos, "_", style->monospace_font );
00188 }
00189
00190
00191
00192
00193
00194 }
00195
00196
00198 bool Console::focusActive( const Event &e ){
00199 if( e.state ){
00200 text_color = Color(0.95f,0.95f,1.00f);
00201 }else{
00202 text_color = Color(0.85f,0.85f,0.95f);
00203 }
00204 return true;
00205 }
00206
00207
00209 Console &Console::operator<<( const string &s ){
00210 buffer_lines[cy]->append( s );
00211 cx = buffer_lines[cy]->size();
00212 return *this;
00213 }
00214
00215
00217 void Console::append( int c ){
00218 switch( c ){
00219 case '\n':
00220 this->newLine();
00221 break;
00222 default:
00223
00224 *buffer_lines[cy] += c;
00225 break;
00226 }
00227 }
00228
00230 void Console::append( const char *str, int count ){
00231 for( int i=0; i<count; i ++ ){
00232 char c = str[i];
00233 switch( c ){
00234 case '\n':
00235 this->newLine();
00236 break;
00237 default:
00238 *buffer_lines[cy] += c;
00239 break;
00240 }
00241 }
00242 }
00243
00244
00246 Console &Console::setLine( const int l, const string &s ){
00247 buffer_lines[l]->assign( s );
00248 return *this;
00249 }
00250
00251
00252
00253 void Console::scroll( int x1, int y1, int x2, int y2, int dx, int dy ){
00254
00255 }
00256
00257
00258 void Console::cursorDown(){
00259 if( (long)(cy)<(long)(buffer_lines.size())-1 ){
00260 cy++;
00261 }
00262
00263 if( cy>topleft_y+height_chars-1 ){
00264 topleft_y++;
00265
00266
00267 }
00268 }
00269
00270
00271 void Console::insertLine( const int y ){
00272 buffer_lines.insert( buffer_lines.begin() + y, new string("") );
00273 }
00274
00275
00276 void Console::killLine( const int y ){
00277 string *line = buffer_lines[y];
00278 delete line;
00279 buffer_lines.erase( buffer_lines.begin() + y );
00280 }
00281
00282
00283 void Console::killChar( const int x, const int y ){
00284
00285 int right_part = buffer_lines[y]->size() - x;
00286 string new_line = buffer_lines[y]->substr( 0, x-1 );
00287 if( right_part > 0 ){
00288 new_line.append( buffer_lines[y]->substr( x, right_part ) );
00289 }
00290 buffer_lines[y]->assign( new_line );
00291 }
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00311 bool Console::keyDown( const Event &e ){
00312 string old_line;
00313 string new_line;
00314 int right_part;
00315
00316 switch( e.key.sym ){
00317
00318
00319 case SDLK_BACKSPACE:
00320
00321
00322 if( cx>0 ){
00323 killChar( cx, cy );
00324 cx--;
00325 }else{
00326 if( cy>0 ){
00327
00328 cx = buffer_lines[cy-1]->size();
00329 buffer_lines[cy-1]->append( *buffer_lines[cy] );
00330 killLine( cy );
00331 cy--;
00332 }
00333 }
00334 break;
00335
00336 case SDLK_DELETE:
00337
00338 if( (long)(cx)<(long)(buffer_lines[cy]->size()) ){
00339 killChar( cx+1, cy );
00340
00341 }else{
00342 if( (long)(cy)<(long)(buffer_lines.size()-1) ){
00343 buffer_lines[cy]->append( *buffer_lines[cy+1] );
00344 killLine( cy+1 );
00345
00346
00347
00348 }
00349 }
00350 break;
00351
00352
00353 case SDLK_RETURN:
00354 insertLine( cy+1 );
00355 cursorDown();
00356 right_part = buffer_lines[cy-1]->size()-cx;
00357
00358 if( right_part>0 ){
00359 buffer_lines[cy]->append( buffer_lines[cy-1]->substr( cx, right_part ) );
00360 }
00361
00362 if( cx>0 ){
00363 buffer_lines[cy-1]->assign( buffer_lines[cy-1]->substr( 0, cx ) );
00364
00365 }else{
00366 buffer_lines[cy-1]->assign( string("") );
00367 }
00368
00369 cx = 0;
00370 break;
00371
00372
00373 case SDLK_UP:
00374 if( cy>0 ){
00375 cy--;
00376 if( topleft_y>cy ){
00377 topleft_y--;
00378 }
00379 right_part = buffer_lines[cy]->size()-cx;
00380 if( right_part<0 ){
00381 cx += right_part;
00382 }
00383 }
00384 break;
00385 case SDLK_DOWN:
00386 cursorDown();
00387 right_part = buffer_lines[cy]->size()-cx;
00388 if( right_part<0 ){
00389 cx += right_part;
00390 }
00391 break;
00392
00393
00394 case SDLK_RIGHT:
00395 if( (long)(cx) < (long)(buffer_lines[cy]->size()) ){
00396 cx++;
00397 }
00398 break;
00399
00400 case SDLK_LEFT:
00401 if( cx>0 ){
00402 cx--;
00403 }
00404 break;
00405
00406
00407 case SDLK_HOME:
00408 cx = 0;
00409 break;
00410
00411 case SDLK_END:
00412 cx = buffer_lines[cy]->size();
00413 break;
00414
00415 case SDLK_INSERT:
00416 case SDLK_PAGEUP:
00417 case SDLK_PAGEDOWN:
00418 case SDLK_PAUSE:
00419 case SDLK_ESCAPE:
00420 case SDLK_TAB:
00421 case SDLK_CLEAR:
00422 case SDLK_PRINT:
00423 case SDLK_SYSREQ:
00424 case SDLK_BREAK:
00425 case SDLK_MENU:
00426 case SDLK_POWER:
00427 case SDLK_HELP:
00428 break;
00429
00430
00431 case SDLK_NUMLOCK:
00432 case SDLK_CAPSLOCK:
00433 case SDLK_SCROLLOCK:
00434 case SDLK_RSHIFT:
00435 case SDLK_LSHIFT:
00436 case SDLK_RCTRL:
00437 case SDLK_LCTRL:
00438 case SDLK_RALT:
00439 case SDLK_LALT:
00440 case SDLK_RMETA:
00441 case SDLK_LMETA:
00442 case SDLK_LSUPER:
00443 case SDLK_RSUPER:
00444 case SDLK_MODE:
00445 break;
00446
00447
00448 case SDLK_F1:
00449 case SDLK_F2:
00450 case SDLK_F3:
00451 case SDLK_F4:
00452 case SDLK_F5:
00453 case SDLK_F6:
00454 case SDLK_F7:
00455 case SDLK_F8:
00456 case SDLK_F9:
00457 case SDLK_F10:
00458 case SDLK_F11:
00459 case SDLK_F12:
00460 case SDLK_F13:
00461 case SDLK_F14:
00462 case SDLK_F15:
00463 break;
00464
00465
00466 case SDLK_KP0:
00467 case SDLK_KP1:
00468 case SDLK_KP2:
00469 case SDLK_KP3:
00470 case SDLK_KP4:
00471 case SDLK_KP5:
00472 case SDLK_KP6:
00473 case SDLK_KP7:
00474 case SDLK_KP8:
00475 case SDLK_KP9:
00476 break;
00477
00478
00479 default:
00480 char buf[25];
00481 unsigned int sym = e.key.unicode;
00482
00483 buf[1] = 0;
00484 if( (sym & 0xff80) == 0 ) {
00485 buf[0] = sym & 0x7f;
00486 }else{
00487 switch( sym ){
00488 case 167: buf[0] = '§'; break;
00489 case 196: buf[0] = 'Ä'; break;
00490 case 197: buf[0] = 'Å'; break;
00491 case 214: buf[0] = 'Ö'; break;
00492 case 228: buf[0] = 'ä'; break;
00493 case 229: buf[0] = 'å'; break;
00494 case 246: buf[0] = 'ö'; break;
00495 default:
00496 sprintf( buf, " %d", sym );
00497 break;
00498 }
00499 }
00500
00501
00502 old_line = *buffer_lines[cy];
00503 right_part = old_line.size()-cx;
00504 if( right_part > 0 ){
00505 new_line = old_line.substr( 0, cx );
00506 new_line.append( string(buf) );
00507 new_line.append( old_line.substr( cx, right_part ) );
00508 buffer_lines[cy]->erase();
00509 buffer_lines[cy]->append( new_line );
00510 }else{
00511 buffer_lines[cy]->append( string(buf) );
00512 }
00513 cx += strlen( buf );
00514 break;
00515 }
00516 return true;
00517 };
00518
00519
00520 };
00521 };
00522