diff --git a/Code/Game/DanBiasGame/DanBiasGame.vcxproj b/Code/Game/DanBiasGame/DanBiasGame.vcxproj index 974736b4..1f0bf1ce 100644 --- a/Code/Game/DanBiasGame/DanBiasGame.vcxproj +++ b/Code/Game/DanBiasGame/DanBiasGame.vcxproj @@ -240,6 +240,7 @@ + diff --git a/Code/Game/DanBiasGame/GameClientState/Buttons/TextField.h b/Code/Game/DanBiasGame/GameClientState/Buttons/TextField.h index df3ff60e..4333f1da 100644 --- a/Code/Game/DanBiasGame/GameClientState/Buttons/TextField.h +++ b/Code/Game/DanBiasGame/GameClientState/Buttons/TextField.h @@ -1,30 +1,202 @@ /******************************************************************** - * Created by Dan Andersson, 2014 + * Text field that allows multiple lines. + * + * Written by Dan Andersson, 2014 ********************************************************************/ -#include -#include "EventButtonGUI.h" -#include "OysterMath.h" #ifndef DANBIAS_CLIENT_TEXT_FIELD_H #define DANBIAS_CLIENT_TEXT_FIELD_H +#include +#include +#include "ButtonRectangle.h" +#include "OysterMath.h" +#include "Utilities.h" + namespace DanBias { namespace Client { - template - class TextField : public EventButtonGUI + template + class TextField : public ButtonRectangle { public: - ::std::wstring text; - - TextField( std::wstring textureName, Owner owner, ::Oyster::Math::Float3 centerPos, ::Oyster::Math::Float2 size ); TextField(); + TextField( ::std::wstring backgroundTexture, ::Oyster::Math::Float3 textColor, Owner owner, Oyster::Math::Float3 pos, Oyster::Math::Float2 size, ResizeAspectRatio resize = ResizeAspectRatio_Height ); + virtual ~TextField(); + virtual void RenderText(); + + const ::std::wstring & operator[]( unsigned int i ) const; + ::std::wstring & operator[]( unsigned int i ); + + void SetTextHeight( ::Oyster::Math::Float h ); + void SetLineSpacing( ::Oyster::Math::Float ls ); + + void SetBottomAligned(); + void SetTopAligned(); + + unsigned int GetNumLines() const; + unsigned int GetMaxLineLength() const; + + void ReserveLines( unsigned int num ); + void ClearText(); + void AppendText( const ::std::wstring &text ); + + void PopBack(); + void PopFront(); private: - ::Oyster::Math::Float3 center; - ::Oyster::Math::Float2 reach; - + bool isBottomAligned; + ::Oyster::Math::Float textHeight, lineSpacing; + ::std::vector<::std::wstring> lines; }; + +// IMPLEMENTATIONS ////////////////////////////////////////////////// + + template + TextField::TextField() + : ButtonRectangle() + { + this->textHeight = 0.025f; + this->lineSpacing = 0.001f; + this->isBottomAligned = true; + } + + template + TextField::TextField( ::std::wstring backgroundTexture, ::Oyster::Math::Float3 textColor, Owner owner, Oyster::Math::Float3 pos, Oyster::Math::Float2 size, ResizeAspectRatio resize ) + : ButtonRectangle( backgroundTexture, L"", textColor, owner, pos, size, resize ) + { + this->textHeight = 0.025f; + this->lineSpacing = 0.001f; + this->isBottomAligned = true; + } + + template + TextField::~TextField() {} + + template + void TextField::RenderText() + { + ::Oyster::Math::Float lineStep = this->textHeight + this->lineSpacing; + ::Oyster::Math::Float2 rowSize = ::Oyster::Math::Float2( this->size.x, this->textHeight ); + + if( this->isBottomAligned ) + { + ::Oyster::Math::Float2 topLeft = this->pos; + topLeft.y += this->size.y - lineStep; + + auto line = this->lines.rbegin(); + for( ; line != this->lines.rend(); ++line ) + { + if( topLeft.y - lineStep >= this->pos.y ) + { + ::Oyster::Graphics::API::RenderText( (*line), topLeft, rowSize, this->textColor ); + topLeft.y -= lineStep; + } + else break; + } + } + else + { + ::Oyster::Math::Float2 topLeft = this->pos; + + auto line = this->lines.begin(); + for( ; line != this->lines.end(); ++line ) + { + if( topLeft.y + lineStep < this->size.y ) + { + ::Oyster::Graphics::API::RenderText( (*line), topLeft, rowSize, this->textColor ); + topLeft.y += lineStep; + } + else break; + } + } + } + + template + const ::std::wstring & TextField::operator[]( unsigned int i ) const + { + return this->lines[(::std::vector<::std::wstring>::size_type)i]; + } + + template + ::std::wstring & TextField::operator[]( unsigned int i ) + { + return this->lines[(::std::vector<::std::wstring>::size_type)i]; + } + + template + void TextField::SetTextHeight( ::Oyster::Math::Float h ) + { + this->textHeight = h; + } + + template + void TextField::SetLineSpacing( ::Oyster::Math::Float ls ) + { + this->lineSpacing = ls; + } + + template + void TextField::SetBottomAligned() + { + this->isBottomAligned = true; + } + + template + void TextField::SetTopAligned() + { + this->isBottomAligned = false; + } + + template + unsigned int TextField::GetNumLines() const + { + return (unsigned int)this->lines.size(); + } + + template + void TextField::ReserveLines( unsigned int num ) + { + this->lines.reserve( (::std::vector<::std::wstring>::size_type)num ); + } + + template + void TextField::ClearText() + { + this->lines.resize( 0 ); + } + + template + void TextField::AppendText( const ::std::wstring &text ) + { + ::std::vector<::std::wstring> split; + split.reserve( 10 ); + ::Utility::String::Split( split, text, L"\n", 0 ); + auto line = split.begin(); + for( ; line != split.end; ++line ) + { + this->lines.push_back( (*line) ); + } + } + + template + void TextField::PopBack() + { + this->lines.pop_back(); + } + + template + void TextField::PopFront() + { + ::std::vector<::std::wstring>::size_type i = 0, + n = this->lines.size() - 1; + for( ; i < n; ++i ) + { + this->lines[i] = this->lines[i+1]; + } + + this->lines.pop_back(); + } } } #endif \ No newline at end of file diff --git a/Code/Game/DanBiasGame/GameClientState/GameState.cpp b/Code/Game/DanBiasGame/GameClientState/GameState.cpp index a1cdb32a..edcb5289 100644 --- a/Code/Game/DanBiasGame/GameClientState/GameState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/GameState.cpp @@ -49,39 +49,7 @@ bool GameState::Init(NetworkClient* nwClient) GameState::gameStateState GameState::LoadGame() { -// Oyster::Graphics::Definitions::Pointlight plight; -// plight.Pos = Float3(315.0f, 0.0f ,5.0f); -// plight.Color = Float3(0.9f,0.7f,0.2f); -// plight.Radius = 100.0f; -// plight.Bright = 0.9f; -// Oyster::Graphics::API::AddLight(plight); -// plight.Pos = Float3(10.0f,350.0f,5.0f); -// plight.Color = Float3(0.9f,0.7f,0.3f); -// plight.Radius = 200.0f; -// plight.Bright = 0.7f; -// Oyster::Graphics::API::AddLight(plight); -// plight.Pos = Float3(350.0f,350.0f,5.0f); -// plight.Color = Float3(0.9f,0.7f,0.3f); -// plight.Radius = 200.0f; -// plight.Bright = 0.7f; -// Oyster::Graphics::API::AddLight(plight); -// plight.Pos = Float3(10.0f,350.0f,350.0f); -// plight.Color = Float3(0.9f,0.7f,0.3f); -// plight.Radius = 200.0f; -// plight.Bright = 0.7f; -// Oyster::Graphics::API::AddLight(plight); -// plight.Pos = Float3(10.0f,-15.0f,5.0f); -// plight.Color = Float3(0.0f,0.0f,1.0f); -// plight.Radius = 50.0f; -// plight.Bright = 2.0f; -// -// Oyster::Graphics::API::AddLight(plight); -//// LoadModels(); -// InitCamera(Float3(0.0f,0.0f,20.0f)); -// // hardcoded objects -//// LoadModels(); -// Float3 startPos = Float3(0,0,20.0f); -// InitCamera(startPos); + return gameStateState_playing; } diff --git a/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp index a043d3bf..c4d2b41d 100644 --- a/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LanMenuState.cpp @@ -11,6 +11,7 @@ #include "EventHandler\EventHandler.h" #include "Buttons\ButtonRectangle.h" +#include "Buttons\TextField.h" #include #include @@ -28,12 +29,13 @@ struct LanMenuState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; Graphics::API::Texture background; - EventButtonCollection button; - ::std::wstring connectIP; + EventButtonCollection guiElements; + + TextField *connectIP; unsigned short connectPort; } privData; -void OnButtonInteract_Connect( Oyster::Event::ButtonEvent& e ); +void OnButtonInteract_Connect( Oyster::Event::ButtonEvent& e ); LanMenuState::LanMenuState() {} @@ -52,16 +54,23 @@ bool LanMenuState::Init(Network::NetworkClient* nwClient) this->privData->background = Graphics::API::CreateTexture( L"grass_md.png" ); - // create buttons - ButtonRectangle *button; + // create guiElements + ButtonRectangle *guiElements; + //0.5f, 0.2f, 0.3f, 0.1f, + guiElements = new ButtonRectangle( L"earth_md.png", L"Connect", Float3(1.0f), OnButtonInteract_Connect, this, Float3(0.5f, 0.2f, 0.5f), Float2(0.3f, 0.1f), ResizeAspectRatio_Width ); + this->privData->guiElements.AddButton( guiElements ); + + this->privData->connectIP = new TextField( L"earth_md.png", Float3(1.0f), this, Float3(0.1f, 0.2f, 0.5f), Float2(0.45f, 0.1f), ResizeAspectRatio_Width ); + this->privData->connectIP->ReserveLines( 1 ); + (*this->privData->connectIP)[0] = L"127.0.0.1"; + this->privData->connectIP->SetTextHeight( 0.1f ); + this->privData->connectIP->SetLineSpacing( 0.0f ); - button = new ButtonRectangle( L"earth_md.png", OnButtonInteract_Connect, this, 0.5f, 0.2f, 0.3f, 0.1f, true ); - this->privData->button.AddButton( button ); + this->privData->guiElements.AddButton( this->privData->connectIP ); - // bind button collection to the singleton eventhandler - EventHandler::Instance().AddCollection( &this->privData->button ); + // bind guiElements collection to the singleton eventhandler + EventHandler::Instance().AddCollection( &this->privData->guiElements ); - this->privData->connectIP = L"127.0.0.1"; this->privData->connectPort = 15151; return true; @@ -88,7 +97,10 @@ bool LanMenuState::Render( ) Graphics::API::StartGuiRender(); Graphics::API::RenderGuiElement( this->privData->background, Float2(0.5f), Float2(1.0f) ); - this->privData->button.Render(); + this->privData->guiElements.RenderTexture(); + + Graphics::API::StartTextRender(); + this->privData->guiElements.RenderText(); Graphics::API::EndFrame(); return true; @@ -106,7 +118,7 @@ void LanMenuState::ChangeState( ClientState next ) { case GameClientState::ClientState_Lobby: // attempt to connect to lobby - if( !this->privData->nwClient->Connect(this->privData->connectPort, this->privData->connectIP) ) + if( !this->privData->nwClient->Connect(this->privData->connectPort, (*this->privData->connectIP)[0]) ) return; break; default: break; @@ -115,7 +127,7 @@ void LanMenuState::ChangeState( ClientState next ) this->privData->nextState = next; } -void OnButtonInteract_Connect( Oyster::Event::ButtonEvent& e ) +void OnButtonInteract_Connect( Oyster::Event::ButtonEvent& e ) { switch( e.state ) { diff --git a/Code/Game/DanBiasGame/GameClientState/LobbyAdminState.cpp b/Code/Game/DanBiasGame/GameClientState/LobbyAdminState.cpp index e6e764ea..21afb54b 100644 --- a/Code/Game/DanBiasGame/GameClientState/LobbyAdminState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LobbyAdminState.cpp @@ -23,10 +23,10 @@ struct LobbyAdminState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; Graphics::API::Texture background; - EventButtonCollection button; + EventButtonCollection guiElements; } privData; -void OnButtonInteract_Ready( Oyster::Event::ButtonEvent& e ); +void OnButtonInteract_Ready( Oyster::Event::ButtonEvent& e ); LobbyAdminState::LobbyAdminState(void) {} @@ -46,13 +46,13 @@ bool LobbyAdminState::Init(NetworkClient* nwClient) this->privData->background = Graphics::API::CreateTexture( L"grass_md.png" ); // create buttons - ButtonRectangle *button; + ButtonRectangle *button; - button = new ButtonRectangle( L"earth_md.png", OnButtonInteract_Ready, this, 0.5f, 0.2f, 0.3f, 0.1f, true ); - this->privData->button.AddButton( button ); + button = new ButtonRectangle( L"earth_md.png", L"Ready", Float3(1.0f), OnButtonInteract_Ready, this, Float3(0.5f, 0.2f, 0.5f), Float2(0.3f, 0.1f), ResizeAspectRatio_Width ); + this->privData->guiElements.AddButton( button ); // bind button collection to the singleton eventhandler - EventHandler::Instance().AddCollection( &this->privData->button ); + EventHandler::Instance().AddCollection( &this->privData->guiElements ); return true; } @@ -85,7 +85,10 @@ bool LobbyAdminState::Render( ) Graphics::API::StartGuiRender(); Graphics::API::RenderGuiElement( this->privData->background, Float2(0.5f), Float2(1.0f) ); - this->privData->button.Render(); + this->privData->guiElements.RenderTexture(); + + Graphics::API::StartTextRender(); + this->privData->guiElements.RenderText(); Graphics::API::EndFrame(); return true; @@ -139,7 +142,7 @@ void LobbyAdminState::DataRecieved( NetEvent& e ) +void OnButtonInteract_Ready( Oyster::Event::ButtonEvent& e ) { switch( e.state ) { diff --git a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp index 77ec5a86..37f10f1d 100644 --- a/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/LobbyState.cpp @@ -23,10 +23,10 @@ struct LobbyState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; Graphics::API::Texture background; - EventButtonCollection button; + EventButtonCollection guiElements; } privData; -void OnButtonInteract_Ready( Oyster::Event::ButtonEvent& e ); +void OnButtonInteract_Ready( Oyster::Event::ButtonEvent& e ); LobbyState::LobbyState(void) {} @@ -46,13 +46,13 @@ bool LobbyState::Init(NetworkClient* nwClient) this->privData->background = Graphics::API::CreateTexture( L"grass_md.png" ); // create buttons - ButtonRectangle *button; + ButtonRectangle *button; - button = new ButtonRectangle( L"earth_md.png", OnButtonInteract_Ready, this, 0.5f, 0.2f, 0.3f, 0.1f, true ); - this->privData->button.AddButton( button ); + button = new ButtonRectangle( L"earth_md.png", L"", Float3(1.0f), OnButtonInteract_Ready, this, Float3(0.5f, 0.2f, 0.5f), Float2(0.3f, 0.1f), ResizeAspectRatio_Width ); + this->privData->guiElements.AddButton( button ); // bind button collection to the singleton eventhandler - EventHandler::Instance().AddCollection( &this->privData->button ); + EventHandler::Instance().AddCollection( &this->privData->guiElements ); return true; } @@ -85,7 +85,10 @@ bool LobbyState::Render( ) Graphics::API::StartGuiRender(); Graphics::API::RenderGuiElement( this->privData->background, Float2(0.5f), Float2(1.0f) ); - this->privData->button.Render(); + this->privData->guiElements.RenderTexture(); + + Graphics::API::StartTextRender(); + this->privData->guiElements.RenderText(); Graphics::API::EndFrame(); return true; @@ -139,7 +142,7 @@ void LobbyState::DataRecieved( NetEvent& e ) +void OnButtonInteract_Ready( Oyster::Event::ButtonEvent& e ) { switch( e.state ) { diff --git a/Code/Game/DanBiasGame/GameClientState/MainState.cpp b/Code/Game/DanBiasGame/GameClientState/MainState.cpp index c7fe78c8..dc6f88b3 100644 --- a/Code/Game/DanBiasGame/GameClientState/MainState.cpp +++ b/Code/Game/DanBiasGame/GameClientState/MainState.cpp @@ -25,12 +25,12 @@ struct MainState::MyData GameClientState::ClientState nextState; NetworkClient *nwClient; Graphics::API::Texture background; - EventButtonCollection button; + EventButtonCollection guiElements; }; -void OnButtonInteract_Create( Oyster::Event::ButtonEvent& e ); -void OnButtonInteract_Join( Oyster::Event::ButtonEvent& e ); -void OnButtonInteract_Quit( Oyster::Event::ButtonEvent& e ); +void OnButtonInteract_Create( Oyster::Event::ButtonEvent& e ); +void OnButtonInteract_Join( Oyster::Event::ButtonEvent& e ); +void OnButtonInteract_Quit( Oyster::Event::ButtonEvent& e ); MainState::MainState(void) {} @@ -50,19 +50,19 @@ bool MainState::Init( NetworkClient* nwClient ) this->privData->background = Graphics::API::CreateTexture( L"grass_md.png" ); // create buttons - ButtonRectangle *button; + ButtonRectangle *button; - button = new ButtonRectangle( L"earth_md.png", OnButtonInteract_Create, this, 0.5f, 0.2f, 0.3f, 0.1f, true ); - this->privData->button.AddButton( button ); + button = new ButtonRectangle( L"earth_md.png", L"Create", Float3(1.0f), OnButtonInteract_Create, this, Float3(0.5f, 0.2f, 0.5f), Float2(0.3f, 0.1f), ResizeAspectRatio_Width ); + this->privData->guiElements.AddButton( button ); - button = new ButtonRectangle( L"skysphere_md.png", OnButtonInteract_Join, this, 0.5f, 0.4f, 0.3f, 0.1f, true ); - this->privData->button.AddButton( button ); + button = new ButtonRectangle( L"skysphere_md.png", L"Join", Float3(1.0f), OnButtonInteract_Join, this, Float3(0.5f, 0.4f, 0.5f), Float2(0.3f, 0.1f), ResizeAspectRatio_Width ); + this->privData->guiElements.AddButton( button ); - button = new ButtonRectangle( L"plane_texture_md.png", OnButtonInteract_Quit, this, 0.5f, 0.8f, 0.3f, 0.1f, true ); - this->privData->button.AddButton( button ); + button = new ButtonRectangle( L"plane_texture_md.png", L"Quit", Float3(1.0f), OnButtonInteract_Quit, this, Float3(0.5f, 0.8f, 0.5f), Float2(0.3f, 0.1f), ResizeAspectRatio_Width ); + this->privData->guiElements.AddButton( button ); // bind button collection to the singleton eventhandler - EventHandler::Instance().AddCollection( &this->privData->button ); + EventHandler::Instance().AddCollection( &this->privData->guiElements ); return true; } @@ -87,7 +87,10 @@ bool MainState::Render() Graphics::API::StartGuiRender(); Graphics::API::RenderGuiElement( this->privData->background, Float2(0.5f), Float2(1.0f) ); - this->privData->button.Render(); + this->privData->guiElements.RenderTexture(); + + Graphics::API::StartTextRender(); + this->privData->guiElements.RenderText(); Graphics::API::EndFrame(); return true; @@ -98,7 +101,7 @@ bool MainState::Release() if( this->privData ) { Graphics::API::DeleteTexture( this->privData->background ); // TODO: @todo bug caught when exiting by X - EventHandler::Instance().ReleaseCollection( &this->privData->button ); + EventHandler::Instance().ReleaseCollection( &this->privData->guiElements ); this->privData = NULL; // button collection will be autoreleased from EventHandler @@ -111,7 +114,7 @@ void MainState::ChangeState( ClientState next ) this->privData->nextState = next; } -void OnButtonInteract_Create( Oyster::Event::ButtonEvent& e ) +void OnButtonInteract_Create( Oyster::Event::ButtonEvent& e ) { switch( e.state ) { @@ -122,7 +125,7 @@ void OnButtonInteract_Create( Oyster::Event::ButtonEvent& e ) } } -void OnButtonInteract_Join( Oyster::Event::ButtonEvent& e ) +void OnButtonInteract_Join( Oyster::Event::ButtonEvent& e ) { switch( e.state ) { @@ -133,7 +136,7 @@ void OnButtonInteract_Join( Oyster::Event::ButtonEvent& e ) } } -void OnButtonInteract_Quit( Oyster::Event::ButtonEvent& e ) +void OnButtonInteract_Quit( Oyster::Event::ButtonEvent& e ) { switch( e.state ) { diff --git a/Code/Misc/Misc.vcxproj.user b/Code/Misc/Misc.vcxproj.user index 9a0b0ae0..3f030911 100644 --- a/Code/Misc/Misc.vcxproj.user +++ b/Code/Misc/Misc.vcxproj.user @@ -1,6 +1,6 @@  - true + false \ No newline at end of file