/*************************************************************************** * Copyright (C) 2004 by Christoph Freundl * * Christoph.Freundl@informatik.uni-erlangen.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the * * Free Software Foundation, Inc., * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include #include "textfield.h" #include "fontfactory.h" #include "graphics.h" namespace SDLwidgets { TextField::TextField( int width, int height ) : _rendered_text( 0 ), _width( width ), _height( height ), _cursor_position( 0 ), _has_focus( false ) { m_mutex = SDL_CreateMutex(); _min_width = width; _min_height = height; // default color for a text label is white _color.r = 255; _color.g = 255; _color.b = 255; _font = FontFactory::getInstance()->createFont( "tahoma.ttf", 12 ); renderText(); updateCursorPosition(); _background = new BackgroundWidget( _width, _height ); SDL_Color black; black.r = black.g = black.b = 0; _background->setColor( black ); _background->setAlpha( SDL_ALPHA_OPAQUE ); } TextField::TextField( std::string font_name, int font_size, std::string text ) : _rendered_text( 0 ), _text( text ), _background( 0 ), _cursor_position( text.length() ), _has_focus( false ) { m_mutex = SDL_CreateMutex(); // default color for a text label is white _color.r = 255; _color.g = 255; _color.b = 255; _font = FontFactory::getInstance()->createFont( font_name, font_size ); renderText(); updateCursorPosition(); _min_width = _rendered_text->w; _min_height = _rendered_text->h; _background = new BackgroundWidget( _rendered_text->w, _rendered_text->h ); SDL_Color black; black.r = black.g = black.b = 0; _background->setColor( black ); _background->setAlpha( SDL_ALPHA_OPAQUE ); } TextField::TextField( std::string text, int width, int height ) : _rendered_text( 0 ), _text( text ), _width( width ), _height( height ), _background( 0 ), _cursor_position( text.length() ), _has_focus( false ) { m_mutex = SDL_CreateMutex(); // default color for a text label is white _color.r = 255; _color.g = 255; _color.b = 255; _font = FontFactory::getInstance()->createFont( "tahoma.ttf", 12 ); renderText(); updateCursorPosition(); _min_width = _width; _min_height = _height; _background = new BackgroundWidget( _width, _height ); SDL_Color black; black.r = black.g = black.b = 0; _background->setColor( black ); _background->setAlpha( SDL_ALPHA_OPAQUE ); } TextField::~TextField() { if ( _rendered_text ) SDL_FreeSurface( _rendered_text ); SDL_DestroyMutex( m_mutex ); } void TextField::setFont( std::string fontName, int fontSize ) { _font = FontFactory::getInstance()->createFont( fontName, fontSize ); renderText(); updateCursorPosition(); } void TextField::setColor( const SDL_Color& color ) { WidgetLeaf::setColor( color ); renderText(); updateCursorPosition(); } void TextField::draw( SDL_Surface* surface ) { SDL_Rect srcRect, destRect; srcRect.x = srcRect.y = 0; srcRect.w = _width; srcRect.h = _height; getOffset( destRect.x, destRect.y ); _background->setPosition( destRect.x, destRect.y ); _background->draw( surface ); SDL_mutexP( m_mutex ); SDL_BlitSurface( _rendered_text, &srcRect, surface, &destRect ); SDL_mutexV( m_mutex ); if ( _has_focus ) { Graphics::drawLine( surface, destRect.x + _cursor_x, destRect.y, destRect.x + _cursor_x, destRect.y + _height, &_color ); } } void TextField::renderText() { SDL_mutexP( m_mutex ); if ( _rendered_text ) SDL_FreeSurface( _rendered_text ); _rendered_text = TTF_RenderText_Solid( _font, _text.c_str(), _color ); SDL_mutexV( m_mutex ); } bool TextField::handleEvent( SDL_Event* event ) { if ( event->type == SDL_MOUSEBUTTONDOWN ) { if ( event->button.button == SDL_BUTTON_LEFT ) { if ( containsPoint( event->button.x, event->button.y ) ) { getRoot()->requestFocus( this ); } } } if ( event->type == SDL_KEYDOWN ) { if ( event->key.keysym.sym == SDLK_BACKSPACE ) { if ( _text.size() > 0 && _cursor_position > 0) { // _text.erase( _text.size()-1 ); _text.erase( _cursor_position-1, 1 ); renderText(); _cursor_position--; updateCursorPosition(); } return true; } else if ( event->key.keysym.sym == SDLK_DELETE ) { if ( _cursor_position < _text.size() ) { _text.erase( _cursor_position, 1 ); renderText(); } } else if ( event->key.keysym.sym == SDLK_LEFT ) { if ( _cursor_position > 0 ) { _cursor_position--; updateCursorPosition(); } } else if ( event->key.keysym.sym == SDLK_RIGHT ) { if ( _cursor_position < _text.size() ) { _cursor_position++; updateCursorPosition(); } } else if ( event->key.keysym.sym == SDLK_RETURN ) { fireAction( EDITING_FINISHED, this ); getRoot()->removeFocus( this ); return true; } else if ( event->key.keysym.sym == SDLK_ESCAPE ) { fireAction( EDITING_CANCELLED, this ); getRoot()->removeFocus( this ); return true; } else if ( event->key.keysym.unicode ) { // _text += static_cast( event->key.keysym.unicode & 0xFF ); _text.insert( _cursor_position, 1, static_cast( event->key.keysym.unicode & 0xFF ) ); renderText(); _cursor_position++; updateCursorPosition(); return true; } } return false; } void TextField::focusGained() { /* SDL_Color black; black.r = black.g = black.b = 0;*/ SDL_Color blue; blue.r = blue.g = 0; blue.b = 200; _background->setColor( blue ); _background->setAlpha( SDL_ALPHA_OPAQUE ); /* SDL_Color white; white.r = white.g = white.b = 255; setColor( white );*/ _has_focus = true; } void TextField::focusLost() { // _background->setAlpha( SDL_ALPHA_TRANSPARENT ); SDL_Color black; black.r = black.g = black.b = 0; _background->setColor( black ); _background->setAlpha( SDL_ALPHA_OPAQUE ); // setColor( black ); _has_focus = false; } void TextField::updateCursorPosition() { if ( _cursor_position == 0 ) _cursor_x = 0; int width; int height; TTF_SizeText( _font, _text.substr( 0, _cursor_position ).c_str(), &width, &height ); _cursor_x = width; } }