/* $Id: wopgui.cpp,v 1.46.2.4 2006/03/26 09:34:01 chfreund Exp $ */ #include "wopgui.hpp" #include #include #include "client.hpp" #include "string.hpp" #include "wopsettings.hpp" #include "playerconfigwindow.hpp" #include "version.hpp" #include "fontfactory.h" #include "layout.h" #include "image.h" #include "textarea.h" using namespace SDLwidgets; WopGUI::WopGUI( Client* client, SDL_Surface* surface ) : m_client ( client ), m_splashScreen ( 0 ), m_surfaceWidth ( surface->w ), m_surfaceHeight( surface->h ) { const SDL_Color black = { 0, 0, 0, 0}, lightBlue = {100, 100, 255, 0}; Widget::setDefaultColor( black ); TextButton::setDefaultColor( black ); TextButton::setDefaultHighlightColor( lightBlue ); TextButton::setDefaultHighlightAlpha( 120 ); m_mutex = SDL_CreateMutex(); std::string fontPath( WopSettings::getInstance()->getData() ); fontPath += "/images/gui"; SDLwidgets::FontFactory::getInstance()->setFontPath( fontPath ); m_root = new RootContainer( surface ); std::ostringstream str; str << "Version "; str << getWopVersion().getString(); m_versionLabel = new TextLabel( str.str() ); m_versionLabel->setPosition( m_root->getWidth() - m_versionLabel->getWidth(), m_root->getHeight() - m_versionLabel->getHeight() ); m_fpsLabel = new TextLabel( "0.0 fps" ); m_fpsLabel->setPosition( 0, 0 ); const SDL_Color background = {0, 0, 255, 0}; m_chatInputWindow.input = new TextField( 600, 20 ); m_chatInputWindow.input->setFont( "tahoma.ttf", 12 ); m_chatInputWindow.input->addActionListener( this ); m_chatInputWindow.window = new WopWindow( m_chatInputWindow.input, "Enter chat message" ); m_chatInputWindow.window->setPosition( 16, 150 ); m_messageWindow.messageArea = new MessageWidget( 560, 50 ); m_messageWindow.messageArea->setFont( "tahomabd.ttf", 11 ); m_messageWindow.window = new BackgroundWidget( m_messageWindow.messageArea, background, 20 ); m_messageWindow.window->setPosition( 0, 430 ); m_weaponWindow.indicators = new WeaponWindow(); m_weaponWindow.window = new BackgroundWidget( m_weaponWindow.indicators, background, 20 ); m_weaponWindow.window->setWidth( 75 ); m_weaponWindow.window->setPosition( 560, 426 ); std::ostringstream path; path << WopSettings::getInstance()->getData(); path << "/images/gui/health.png"; Image* healthImage = new Image( path.str().c_str() ); m_healthWidget.indicator = new WeaponIndicator( 75, 12 ); const SDL_Color healthColor = {207, 0, 0, 0}; m_healthWidget.indicator->setColor( healthColor ); m_healthWidget.container = new WidgetComposite( 0, 0 ); HorizontalLayout* healthLayout = new HorizontalLayout( m_healthWidget.container ); m_healthWidget.container->setLayout( healthLayout ); m_healthWidget.container->add( healthImage ); m_healthWidget.container->add( m_healthWidget.indicator ); m_healthWidget.container->setPosition( 551, 5 ); std::ostringstream path2; path2 << WopSettings::getInstance()->getData(); path2 << "/images/gui/rope.png"; Image* ropeImage = new Image( path2.str().c_str() ); m_ropeWidget.indicator = new WeaponIndicator( 75, 12 ); const SDL_Color ropeColor = {219, 205, 0, 0}; m_ropeWidget.indicator->setColor( ropeColor ); m_ropeWidget.container = new WidgetComposite( 0, 0 ); HorizontalLayout* ropeLayout = new HorizontalLayout( m_ropeWidget.container ); m_ropeWidget.container->setLayout( ropeLayout ); m_ropeWidget.container->add( ropeImage ); m_ropeWidget.container->add( m_ropeWidget.indicator ); m_ropeWidget.container->setPosition( 551, 7 + m_healthWidget.container->getHeight() ); std::ostringstream path3; path3 << WopSettings::getInstance()->getData(); path3 << "/images/gui/ammo.png"; Image* activeWeaponImage = new Image( path3.str().c_str() ); m_activeWeaponWidget.indicator = new WeaponIndicator( 75, 12 ); const SDL_Color ammoColor = {167, 167, 217, 0}; m_activeWeaponWidget.indicator->setColor( ammoColor ); m_activeWeaponWidget.container = new WidgetComposite( 0, 0 ); HorizontalLayout* activeWeaponLayout = new HorizontalLayout( m_activeWeaponWidget.container ); m_activeWeaponWidget.container->setLayout( activeWeaponLayout ); m_activeWeaponWidget.container->add( activeWeaponImage ); m_activeWeaponWidget.container->add( m_activeWeaponWidget.indicator ); m_activeWeaponWidget.container->setPosition( 551, 9 + m_healthWidget.container->getHeight() + m_ropeWidget.container->getHeight() ); std::ostringstream path4; path4 << WopSettings::getInstance()->getData(); path4 << "/images/gui/fuel.png"; Image* fuelImage = new Image( path4.str().c_str() ); m_fuelWidget.indicator = new WeaponIndicator( 75, 12 ); const SDL_Color fuelColor = {66, 181, 0, 0}; m_fuelWidget.indicator->setColor( fuelColor ); m_fuelWidget.container = new WidgetComposite( 0, 0 ); HorizontalLayout* fuelLayout = new HorizontalLayout( m_fuelWidget.container ); m_fuelWidget.container->setLayout( fuelLayout ); m_fuelWidget.container->add( fuelImage ); m_fuelWidget.container->add( m_fuelWidget.indicator ); m_fuelWidget.container->setPosition( 551, 11 + m_healthWidget.container->getHeight() + m_ropeWidget.container->getHeight()+m_activeWeaponWidget.container->getHeight() ); m_serverListWindow = 0; m_scoreTableWindow.scoreTable = new ScoreTable(); m_scoreTableWindow.window = new WopWindow( m_scoreTableWindow.scoreTable, "Scores" ); m_scoreTableWindow.window->setPosition( 100, 70 ); m_initializationWindow.progressBar = new WeaponIndicator( 200, 20 ); const SDL_Color progressBarColor = {50, 50, 255, 0}; m_initializationWindow.progressBar->setColor( progressBarColor ); m_initializationWindow.title = new TextLabel( "tahoma.ttf", 12, "Stand by..." ); m_initializationWindow.title->setColor( black ); m_initializationWindow.title->setPosition( 0, 21 ); WidgetComposite* initializationWidget = new WidgetComposite(); initializationWidget->setLayout( new VerticalLayout( initializationWidget ) ); initializationWidget->add( m_initializationWindow.progressBar ); initializationWidget->add( m_initializationWindow.title ); m_initializationWindow.window = new WopWindow( initializationWidget, "Loading sprites" ); m_initializationWindow.window->setPosition( 210, 360 ); m_progressWindow.progressBar = new WeaponIndicator( 200, 20 ); m_progressWindow.progressBar->setColor( progressBarColor ); m_progressWindow.title = new TextLabel( "tahoma.ttf", 12, "Stay tuned..." ); m_progressWindow.title->setColor( black ); m_progressWindow.title->setPosition( 0, 21 ); WidgetComposite* progressWidget = new WidgetComposite(); progressWidget->setLayout( new VerticalLayout( progressWidget ) ); progressWidget->add( m_progressWindow.progressBar ); progressWidget->add( m_progressWindow.title ); m_progressWindow.window = new WopWindow( progressWidget, "New player is joining" ); m_progressWindow.window->setPosition( 210, 200 ); m_optionsWindow = new OptionsWindow( WopSettings::getInstance(), 300, 400 ); m_optionsWindow->addActionListener( this ); m_optionsWindow->setPosition( ( m_surfaceWidth - m_optionsWindow->getWidth() ) / 2, ( m_surfaceHeight - m_optionsWindow->getHeight() ) / 2 ); m_keyConfigWindow = new KeyConfigWindow( m_client->getKeyboardConfig(), 540, 400 ); m_keyConfigWindow->addActionListener( this ); m_keyConfigWindow->setPosition( ( m_surfaceWidth - m_keyConfigWindow->getWidth() ) / 2, ( m_surfaceHeight - m_keyConfigWindow->getHeight() ) / 2 ); m_creditsWindow = new CreditsWindow(); m_creditsWindow->addActionListener( this ); m_creditsWindow->setPosition ( ( m_root->getWidth() - m_creditsWindow->getWidth() ) / 2, ( m_root->getHeight() - m_creditsWindow->getHeight() ) / 2 ); m_gameInfoWindow = new GameInfoWindow( this ); m_gameInfoWindow->addActionListener( this ); m_gameInfoWindow->setPosition ( ( m_root->getWidth() - m_gameInfoWindow->getWidth() ) / 2, ( m_root->getHeight() - m_gameInfoWindow->getHeight() ) / 2 ); WidgetComposite* sewContent = new WidgetComposite(); VerticalLayout* sewContentLayout = new VerticalLayout( sewContent ); sewContentLayout->setSpacing( 5 ); sewContent->setLayout( sewContentLayout ); m_serverEnterWindow.addressField = new TextField( 300, 20 ); m_serverEnterWindow.addressField->setHorizontalStretch( FILL ); m_serverEnterWindow.addressField->addActionListener( this ); sewContent->add( m_serverEnterWindow.addressField ); WidgetComposite* sewButtons = new WidgetComposite(); HorizontalLayout* sewButtonsLayout = new HorizontalLayout( sewButtons ); sewButtons->setLayout( sewButtonsLayout ); m_serverEnterWindow.connectButton = new TextButton( "Connect" ); m_serverEnterWindow.connectButton->setHighlightable( true ); m_serverEnterWindow.connectButton->addActionListener( this ); m_serverEnterWindow.connectButton->setHorizontalStretch( FILL ); sewButtons->add( m_serverEnterWindow.connectButton ); sewButtonsLayout->setStretch( m_serverEnterWindow.connectButton, FILL ); m_serverEnterWindow.backButton = new TextButton( "Back" ); m_serverEnterWindow.backButton->setHighlightable( true ); m_serverEnterWindow.backButton->addActionListener( this ); m_serverEnterWindow.backButton->setHorizontalStretch( FILL ); sewButtons->add( m_serverEnterWindow.backButton ); sewButtonsLayout->setStretch( m_serverEnterWindow.backButton, FILL ); sewButtons->setWidth( 300 ); sewContent->add( sewButtons ); m_serverEnterWindow.window = new WopWindow( sewContent, "Enter server name or address" ); m_serverEnterWindow.window->setPosition ( ( m_root->getWidth() - m_serverEnterWindow.window->getWidth() ) / 2, ( m_root->getHeight() - m_serverEnterWindow.window->getHeight() ) / 2 ); m_infoBox.text = new TextLabel( "", 14 ); m_infoBox.text->setColor( black ); m_infoBox.text->setHorizontalStretch( FILL ); m_infoBox.window = new WopWindow( m_infoBox.text, "Information" ); m_infoBox.window->setPosition ( ( m_root->getWidth() - m_infoBox.window->getWidth() ) / 2, ( m_root->getHeight() - m_infoBox.window->getHeight() ) / 2 ); createMainMenu(); } WopGUI::~WopGUI() { delete m_chatInputWindow.window; delete m_messageWindow.window; delete m_weaponWindow.window; SDL_DestroyMutex( m_mutex ); } void WopGUI::actionPerformed( Uint32 cmd, void* source ) { if ( source == m_mainMenu.startButton && cmd == Button::BUTTON_PRESSED ) { hideMainMenu(); m_client->startLocalServer(); // m_client->connectToLocalServer(); LOG( 2 ) INFO( "Waiting for server to initialize\n" ); SDL_Delay( 1000 ); LOG( 2 ) INFO( "Connecting to local server\n" ); IPaddress address; SDLNet_ResolveHost( &address, "127.0.0.1", 0xb8b8 ); RemoteServerEntry serverEntry( address ); m_client->connectToServer( serverEntry ); } else if ( source == m_mainMenu.joinButton && cmd == Button::BUTTON_PRESSED ) { hideMainMenu(); SDL_mutexP( m_mutex ); std::vector entries = m_client->lookForServers(); SDL_mutexV( m_mutex ); showServerListWindow( entries ); } else if ( source == m_mainMenu.join2Button && cmd == Button::BUTTON_PRESSED ) { hideMainMenu(); SDL_mutexP( m_mutex ); m_root->add( m_serverEnterWindow.window ); m_root->requestFocus( m_serverEnterWindow.addressField ); SDL_mutexV( m_mutex ); } else if ( source == m_mainMenu.optionsButton && cmd == Button::BUTTON_PRESSED ) { hideMainMenu(); showOptionsWindow(); } else if ( source == m_mainMenu.creditButton && cmd == Button::BUTTON_PRESSED ) { hideMainMenu(); showCreditsWindow(); } else if ( source == m_mainMenu.exitButton && cmd == Button::BUTTON_PRESSED ) { m_client->exit(); } else if ( source == m_creditsWindow && cmd == CreditsWindow::BACK_PRESSED ) { hideCreditsWindow(); showMainMenu(); } else if ( source == m_optionsWindow ) { if ( cmd == OptionsWindow::BACK_PRESSED ) { hideOptionsWindow(); showMainMenu(); } if ( cmd == OptionsWindow::SAVE_PRESSED ) { String path( "" ); WopSettings::getInstance()->writeConfigFile( path ); hideOptionsWindow(); showMainMenu(); } else if ( cmd == OptionsWindow::CONFIG_KEYS_PRESSED ) { hideOptionsWindow(); m_keyConfigWindow->updateKeys(); showKeyConfigWindow(); } } else if ( source == m_keyConfigWindow && cmd == KeyConfigWindow::BACK_PRESSED ) { m_client->getKeyboardConfig()->writeSettings( WopSettings::getInstance() ); hideKeyConfigWindow(); showOptionsWindow(); } else if ( source == m_serverEnterWindow.addressField && cmd == TextField::EDITING_CANCELLED ) { SDL_mutexP( m_mutex ); m_root->removeFocus( m_serverEnterWindow.addressField ); m_root->remove( m_serverEnterWindow.window ); SDL_mutexV( m_mutex ); showMainMenu(); } else if ( source == m_serverEnterWindow.connectButton && cmd == Button::BUTTON_PRESSED ) { SDL_mutexP( m_mutex ); m_root->remove( m_serverEnterWindow.window ); SDL_mutexV( m_mutex ); m_client->connectToServer( m_serverEnterWindow.addressField->getText() ); } else if ( source == m_serverEnterWindow.backButton && cmd == Button::BUTTON_PRESSED ) { SDL_mutexP( m_mutex ); m_root->remove( m_serverEnterWindow.window ); SDL_mutexV( m_mutex ); showMainMenu(); } else if ( source == m_serverListWindow ) { switch( cmd ) { // FIXME: move variable declarations out of cases case ServerListWindow::BACK_PRESSED: hideServerListWindow(); showMainMenu(); break; case ServerListWindow::REFRESH_PRESSED: { hideServerListWindow(); SDL_mutexP( m_mutex ); m_serverListWindow->clearEntries(); std::vector entries = m_client->lookForServers(); SDL_mutexV( m_mutex ); showServerListWindow( entries ); break; } case ServerListWindow::CONNECT_PRESSED: if ( m_serverListWindow->getSelectedIndex() != -1 ) { hideServerListWindow(); m_client->connectToServer( *m_serverListWindow->getSelectedServer() ); } break; } } else if ( source == m_gameInfoWindow ) { switch( cmd ) { case GameInfoWindow::CONFIGURE_PRESSED: { hideGameInfoWindow(); PlayerConfigWindow* pcw = new PlayerConfigWindow( m_gameInfoWindow->getSelectedPlayer() ); pcw->setPosition( ( m_root->getWidth() - pcw->getWidth() ) / 2, ( m_root->getHeight() - pcw->getHeight() ) / 2 ); SDL_mutexP( m_mutex ); m_root->add( pcw ); SDL_mutexV( m_mutex ); break; } case GameInfoWindow::GO_PRESSED: hideGameInfoWindow(); m_client->setActive( m_gameInfoWindow->getPlayer(), m_gameInfoWindow->getBots() ); break; case GameInfoWindow::BACK_PRESSED: hideGameInfoWindow(); m_client->disconnect(); /* SDL_mutexP( m_mutex ); m_serverListWindow->clearEntries(); std::vector entries = m_client->lookForServers(); SDL_mutexV( m_mutex ); showServerListWindow( entries );*/ break; } } else if ( source == m_chatInputWindow.input ) { switch ( cmd ) { // FIXME: move variable declarations out of cases case TextField::EDITING_FINISHED: if ( m_chatInputWindow.input->getText().size() > 0 ) { String message( m_chatInputWindow.input->getText().c_str() ); m_client->sendChatMessage( message ); m_chatInputWindow.input->clear(); } SDL_mutexP( m_mutex ); m_root->remove( m_chatInputWindow.window ); m_root->removeFocus( m_chatInputWindow.input ); SDL_mutexV( m_mutex ); break; case TextField::EDITING_CANCELLED: SDL_mutexP( m_mutex ); m_root->remove( m_chatInputWindow.window ); m_root->removeFocus( m_chatInputWindow.input ); SDL_mutexV( m_mutex ); break; } } } void WopGUI::showMessage( String message, const SDL_Color& color ) { SDL_mutexP( m_mutex ); std::string s( message.getString() ); m_messageWindow.messageArea->addMessage( s, color ); SDL_mutexV( m_mutex ); } void WopGUI::showServerListWindow( std::vector& servers ) { SDL_mutexP( m_mutex ); m_serverListWindow = new ServerListWindow( 540, 400 ); m_serverListWindow->setEntries( servers ); m_serverListWindow->addActionListener( this ); m_serverListWindow->setPosition( ( m_surfaceWidth - m_serverListWindow->getWidth() ) / 2, ( m_surfaceHeight - m_serverListWindow->getHeight() ) / 2 ); // m_serverListWindow->setPosition( 50, 40 ); m_lastServerUpdate = SDL_GetTicks(); m_root->add( m_serverListWindow ); SDL_mutexV( m_mutex ); } bool WopGUI::handleEvent( SDL_Event* event ) { return m_root->handleEvent( event ); } void WopGUI::draw() { SDL_mutexP( m_mutex ); if( m_messageWindow.blinkState > 0 ) { m_messageWindow.blinkState -= 25; if( m_messageWindow.blinkState < 0 ) m_messageWindow.blinkState = 0; const SDL_Color color = {m_messageWindow.blinkState, 0, 255-m_messageWindow.blinkState, 0}; m_messageWindow.window->setColor( color ); m_messageWindow.window->setAlpha( min( 255, 20 + m_messageWindow.blinkState/2 )); } // hide info box after certain time if ( m_root->contains( m_infoBox.window ) ) { if ( SDL_GetTicks() - m_infoBox.startTicks >= m_infoBox.duration ) m_root->remove( m_infoBox.window ); } m_root->draw(); SDL_mutexV( m_mutex ); } void WopGUI::createMainMenu() { WidgetComposite* container = new WidgetComposite(); VerticalLayout* layout = new VerticalLayout( container ); container->setLayout( layout ); m_mainMenu.startButton = new TextButton( "Host game" ); m_mainMenu.startButton->setHighlightable( true ); m_mainMenu.startButton->addActionListener( this ); m_mainMenu.startButton->setHorizontalStretch( FILL ); container->add( m_mainMenu.startButton ); m_mainMenu.joinButton = new TextButton( "Connect to LAN server" ); m_mainMenu.joinButton->setHighlightable( true ); m_mainMenu.joinButton->addActionListener( this ); m_mainMenu.joinButton->setHorizontalStretch( FILL ); container->add( m_mainMenu.joinButton ); m_mainMenu.join2Button = new TextButton( "Connect to Internet server" ); m_mainMenu.join2Button->setHighlightable( true ); m_mainMenu.join2Button->addActionListener( this ); m_mainMenu.join2Button->setHorizontalStretch( FILL ); container->add( m_mainMenu.join2Button ); m_mainMenu.optionsButton = new TextButton( "Options" ); m_mainMenu.optionsButton->setHighlightable( true ); m_mainMenu.optionsButton->addActionListener( this ); m_mainMenu.optionsButton->setHorizontalStretch( FILL ); container->add( m_mainMenu.optionsButton ); m_mainMenu.creditButton = new TextButton( "Credits" ); m_mainMenu.creditButton->setHighlightable( true ); m_mainMenu.creditButton->addActionListener( this ); m_mainMenu.creditButton->setHorizontalStretch( FILL ); container->add( m_mainMenu.creditButton ); m_mainMenu.exitButton = new TextButton( "Exit" ); m_mainMenu.exitButton->setHighlightable( true ); m_mainMenu.exitButton->addActionListener( this ); m_mainMenu.exitButton->setHorizontalStretch( FILL ); container->add( m_mainMenu.exitButton ); container->setWidth( 300 ); m_mainMenu.window = new WopWindow( container, "Main menu" ); m_mainMenu.window->setPosition ( ( m_root->getWidth() - m_mainMenu.window->getWidth() ) / 2, ( m_root->getHeight() - m_mainMenu.window->getHeight() ) / 2 ); } void WopGUI::showInfoBox( std::string text, Uint32 duration ) { if ( duration > 0 ) { m_infoBox.text->setText( text ); m_infoBox.text->doLayout(); m_infoBox.duration = duration; m_infoBox.startTicks = SDL_GetTicks(); SDL_mutexP( m_mutex ); m_infoBox.window->setPosition ( ( m_root->getWidth() - m_infoBox.window->getWidth() ) / 2, ( m_root->getHeight() - m_infoBox.window->getHeight() ) / 2 ); m_root->add( m_infoBox.window ); SDL_mutexV( m_mutex ); } } void WopGUI::toggleFps() { SDL_mutexP( m_mutex ); if ( m_root->contains( m_fpsLabel ) ) m_root->remove( m_fpsLabel ); else m_root->add( m_fpsLabel ); SDL_mutexV( m_mutex ); }