void DesktopExample::Run() { sf::RenderWindow render_window( sf::VideoMode( SCREEN_WIDTH, SCREEN_HEIGHT ), "SFGUI Desktop Example" ); sf::Event event; // We have to do this because we don't use SFML to draw. render_window.resetGLStates(); //// Main window //// // Widgets. m_window->SetTitle( "SFGUI Desktop Example" ); sfg::Label::Ptr intro_label( sfg::Label::Create( "Click on \"Create window\" to create any number of new windows." ) ); sfg::Button::Ptr create_window_button( sfg::Button::Create( "Create window" ) ); create_window_button->SetId( "create_window" ); // Layout. sfg::Box::Ptr main_box( sfg::Box::Create( sfg::Box::VERTICAL, 5.f ) ); main_box->Pack( intro_label, false ); main_box->Pack( create_window_button, false ); m_window->Add( main_box ); m_desktop.Add( m_window ); // Signals. create_window_button->GetSignal( sfg::Widget::OnLeftClick ).Connect( &DesktopExample::OnCreateWindowClick, this ); // Init. m_desktop.SetProperty( "Button#create_window", "FontSize", 18.f ); while( render_window.isOpen() ) { while( render_window.pollEvent( event ) ) { if( (event.type == sf::Event::Closed) || (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) ) { render_window.close(); } else if( event.type == sf::Event::Resized ) { m_desktop.UpdateViewRect( sf::FloatRect( 0, 0, static_cast<float>( render_window.getSize().x ), static_cast<float>( render_window.getSize().y ) ) ); } else { m_desktop.HandleEvent( event ); } } m_desktop.Update( 0.f ); render_window.clear(); m_sfgui.Display( render_window ); render_window.display(); } }
void CustomWidget::Run() { // Create SFML's window. sf::RenderWindow render_window( sf::VideoMode( SCREEN_WIDTH, SCREEN_HEIGHT ), "Custom Widget" ); // Create our custom widget. m_custom_widget = MyCustomWidget::Create( "Custom Text" ); // Create a simple button and connect the click signal. auto button = sfg::Button::Create( "Button" ); button->GetSignal( sfg::Widget::OnLeftClick ).Connect( std::bind( &CustomWidget::OnButtonClick, this ) ); // Create a vertical box layouter with 5 pixels spacing and add our custom widget and button // and button to it. auto box = sfg::Box::Create( sfg::Box::Orientation::VERTICAL, 5.0f ); box->Pack( m_custom_widget ); box->Pack( button, false ); // Create a window and add the box layouter to it. Also set the window's title. auto window = sfg::Window::Create(); window->SetTitle( "Custom Widget" ); window->Add( box ); // Create a desktop and add the window to it. sfg::Desktop desktop; desktop.Add( window ); // We're not using SFML to render anything in this program, so reset OpenGL // states. Otherwise we wouldn't see anything. render_window.resetGLStates(); // Main loop! sf::Event event; sf::Clock clock; while( render_window.isOpen() ) { // Event processing. while( render_window.pollEvent( event ) ) { desktop.HandleEvent( event ); // If window is about to be closed, leave program. if( event.type == sf::Event::Closed ) { render_window.close(); } } // Update SFGUI with elapsed seconds since last call. desktop.Update( clock.restart().asSeconds() ); // Rendering. render_window.clear(); m_sfgui.Display( render_window ); render_window.display(); } }
void ProgressBarExample::Run() { // Create the main SFML window sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI Progress Bar Example", sf::Style::Titlebar | sf::Style::Close ); // We have to do this because we don't use SFML to draw. app_window.resetGLStates(); // Create our main SFGUI window sfg::Window::Ptr window; window = sfg::Window::Create(); window->SetTitle( "Title" ); // Create our progress bar m_progressbar = sfg::ProgressBar::Create(); // Set how big the progress bar should be m_progressbar->SetRequisition( sf::Vector2f( 200.f, 40.f ) ); // Create a button and connect the click signal. sfg::Button::Ptr button( sfg::Button::Create( "Set Random Value" ) ); button->GetSignal( sfg::Widget::OnLeftClick ).Connect( &ProgressBarExample::OnButtonClick, this ); // Create a horizontal box layouter and add widgets to it. sfg::Box::Ptr box( sfg::Box::Create( sfg::Box::HORIZONTAL, 5.0f ) ); box->Pack( m_progressbar ); box->Pack( button, false ); // Add the box to the window. window->Add( box ); // Our clock sf::Clock clock; // Start the game loop while ( app_window.isOpen() ) { // Process events sf::Event event; while ( app_window.pollEvent( event ) ) { // Handle events window->HandleEvent( event ); // Close window : exit if ( event.type == sf::Event::Closed ) { app_window.close(); } } // Update the GUI every 5ms if( clock.getElapsedTime().asMicroseconds() >= 5000 ) { // Update() takes the elapsed time in seconds. window->Update( static_cast<float>( clock.getElapsedTime().asMicroseconds() ) / 1000000.f ); clock.restart(); } // Clear screen app_window.clear(); // Draw the GUI m_sfgui.Display( app_window ); // Update the window app_window.display(); } }
void GuessMyNumber::Run() { sf::RenderWindow render_window( sf::VideoMode( 1024, 768, 32 ), TITLE, sf::Style::Titlebar | sf::Style::Close ); sf::Event event; // We have to do this because we don't use SFML to draw. render_window.resetGLStates(); // Create widgets. sfg::Window::Ptr window( sfg::Window::Create() ); window->SetTitle( TITLE ); sfg::Button::Ptr new_game_button( sfg::Button::Create( "New game" ) ); new_game_button->GetSignal( sfg::Widget::OnLeftClick ).Connect( &GuessMyNumber::OnNewGameClick, this ); m_guess_button->SetId( "guess" ); m_guess_button->GetSignal( sfg::Widget::OnLeftClick ).Connect( &GuessMyNumber::OnGuessClick, this ); // Layout. sfg::Table::Ptr table( sfg::Table::Create() ); table->Attach( sfg::Label::Create( "Your guess:" ), sf::Rect<sf::Uint32>( 0, 0, 1, 1 ), sfg::Table::FILL, sfg::Table::FILL ); table->Attach( m_number_entry, sf::Rect<sf::Uint32>( 1, 0, 1, 1 ) ); table->Attach( sfg::Label::Create( "Tries:" ), sf::Rect<sf::Uint32>( 0, 1, 1, 1 ), sfg::Table::FILL, sfg::Table::FILL ); table->Attach( m_tries_label, sf::Rect<sf::Uint32>( 1, 1, 1, 1 ) ); table->Attach( sfg::Label::Create( "Hint:" ), sf::Rect<sf::Uint32>( 0, 2, 1, 1 ), sfg::Table::FILL, sfg::Table::FILL ); table->Attach( m_hint_label, sf::Rect<sf::Uint32>( 1, 2, 1, 1 ) ); table->SetColumnSpacings( 5.f ); table->SetRowSpacings( 5.f ); sfg::Box::Ptr buttons_box( sfg::Box::Create( sfg::Box::HORIZONTAL, 5.f ) ); buttons_box->Pack( new_game_button ); buttons_box->Pack( m_guess_button ); sfg::Box::Ptr content_vbox( sfg::Box::Create( sfg::Box::VERTICAL, 5.f ) ); content_vbox->Pack( sfg::Label::Create( "Guess my number, it's from 1 to 100!" ) ); content_vbox->Pack( table ); content_vbox->Pack( buttons_box ); window->Add( content_vbox ); ResetGame(); window->SetPosition( sf::Vector2f( static_cast<float>( render_window.getSize().x / 2 ) - window->GetAllocation().width / 2.f, static_cast<float>( render_window.getSize().y / 2 ) - window->GetAllocation().height / 2.f ) ); // Custom properties. sfg::Context::Get().GetEngine().SetProperty( "Button#guess", "BackgroundColor", sf::Color( 0, 100, 0 ) ); sfg::Context::Get().GetEngine().SetProperty( "Button#guess", "BorderColor", sf::Color( 0, 100, 0 ) ); sfg::Context::Get().GetEngine().SetProperty( "Button#guess:Prelight", "BackgroundColor", sf::Color( 0, 130, 0 ) ); sfg::Context::Get().GetEngine().SetProperty( "Button#guess:Prelight", "BorderColor", sf::Color( 0, 130, 0 ) ); sfg::Context::Get().GetEngine().SetProperty( "Button#guess > Label", "FontSize", 20.f ); // Make sure all properties are applied. window->Refresh(); while( render_window.isOpen() ) { while( render_window.pollEvent( event ) ) { if( (event.type == sf::Event::KeyPressed && event.key.code == sf::Keyboard::Escape) || event.type == sf::Event::Closed ) { render_window.close(); } window->HandleEvent( event ); } window->Update( 0.f ); render_window.clear(); m_sfgui.Display( render_window ); render_window.display(); } }
void ScrolledWindowViewportExample::Run() { // Create the main SFML window sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI ScrolledWindow and Viewport Example", sf::Style::Titlebar | sf::Style::Close ); // We have to do this because we don't use SFML to draw. app_window.resetGLStates(); // Create our main SFGUI window sfg::Window::Ptr window; window = sfg::Window::Create(); window->SetTitle( "Title" ); // Create a box with 10 pixel spacing. sfg::Box::Ptr box = sfg::Box::Create( sfg::Box::VERTICAL, 10.f ); // Create a button and connect the click signal. sfg::Button::Ptr button = sfg::Button::Create( "Add a button" ); button->GetSignal( sfg::Widget::OnLeftClick ).Connect( &ScrolledWindowViewportExample::OnButtonClick, this ); // Create a box for our ScrolledWindow. ScrolledWindows are bins // and can only contain 1 child widget. m_scrolled_window_box = sfg::Box::Create( sfg::Box::VERTICAL ); // Create the ScrolledWindow. sfg::ScrolledWindow::Ptr scrolledwindow = sfg::ScrolledWindow::Create(); // Set the ScrolledWindow to always show the horizontal scrollbar // and only show the vertical scrollbar when needed. scrolledwindow->SetScrollbarPolicy( sfg::ScrolledWindow::HORIZONTAL_ALWAYS | sfg::ScrolledWindow::VERTICAL_AUTOMATIC ); // Add the ScrolledWindow box to the ScrolledWindow // and create a new viewport automatically. scrolledwindow->AddWithViewport( m_scrolled_window_box ); // Always remember to set the minimum size of a ScrolledWindow. scrolledwindow->SetRequisition( sf::Vector2f( 500.f, 100.f ) ); // Create a viewport. sfg::Viewport::Ptr viewport = sfg::Viewport::Create(); // Always remember to set the minimum size of a Viewport. viewport->SetRequisition( sf::Vector2f( 500.f, 200.f ) ); // Set the vertical adjustment values of the Viewport. viewport->GetVerticalAdjustment()->SetLower( 0.f ); viewport->GetVerticalAdjustment()->SetUpper( 100000000.f ); // Create a box for our Viewport. Viewports are bins // as well and can only contain 1 child widget. sfg::Box::Ptr viewport_box = sfg::Box::Create( sfg::Box::VERTICAL ); sf::err() << "Generating random strings, please be patient..." << std::endl; // Create some random text. for( int i = 0; i < 200; i++ ) { std::string str; for( int j = 0; j < 20; j++ ) { str += static_cast<char>( 65 + rand() % 26 ); } // Add the text to the Viewport box. viewport_box->Pack( sfg::Label::Create( str.c_str() ) ); } // Add the Viewport box to the viewport. viewport->Add( viewport_box ); // Add everything to our box. box->Pack( button, false, true ); box->Pack( scrolledwindow, false, true ); box->Pack( viewport, true, true ); // Add the box to the window. window->Add( box ); sf::Clock clock; // Start the game loop while ( app_window.isOpen() ) { // Process events sf::Event event; while ( app_window.pollEvent( event ) ) { // Handle events window->HandleEvent( event ); // Close window : exit if ( event.type == sf::Event::Closed ) { app_window.close(); } } // Update the GUI every 1ms if( clock.getElapsedTime().asMicroseconds() >= 1000 ) { float delta = static_cast<float>( clock.getElapsedTime().asMicroseconds() ) / 1000000.f; // Update() takes the elapsed time in seconds. window->Update( delta ); // Add a nice automatic scrolling effect to our viewport ;) viewport->GetVerticalAdjustment()->SetValue( viewport->GetVerticalAdjustment()->GetValue() + delta * 10.f ); clock.restart(); } // Clear screen app_window.clear(); // Draw the GUI m_sfgui.Display( app_window ); // Update the window app_window.display(); } }
void EntryExample::Run() { // Create the main SFML window sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI Entry Example", sf::Style::Titlebar | sf::Style::Close ); // We have to do this because we don't use SFML to draw. app_window.resetGLStates(); // Create our main SFGUI window auto window = sfg::Window::Create(); window->SetTitle( "Title" ); // Create our box. auto box = sfg::Box::Create( sfg::Box::Orientation::HORIZONTAL ); // Create a button. auto button = sfg::Button::Create(); button->SetLabel( "Set" ); // Connect the button. button->GetSignal( sfg::Widget::OnLeftClick ).Connect( std::bind( &EntryExample::ButtonClick, this ) ); // Create a label. m_label = sfg::Label::Create(); m_label->SetText( "no text yet" ); // Create our entry widget itself. m_entry = sfg::Entry::Create(); // Until now all widgets only expanded to fit the text inside of it. // This is not the case with the entry widget which can be empty // but still has to have a reasonable size. // To disable the automatic sizing of widgets in general you can // use the SetRequisition() method. it takes an sf::Vector as it's // parameter. Depending on which side you want to have a minimum size, // you set the corresponding value in the vector. // Here we chose to set the minimum x size of the widget to 80. m_entry->SetRequisition( sf::Vector2f( 80.f, 0.f ) ); // Setting sizing back to automatic is as easy as setting // x and y sizes to 0. // Pack into box box->Pack( m_entry ); box->Pack( button ); box->Pack( m_label ); // Set box spacing box->SetSpacing( 5.f ); // Add our box to the window window->Add( box ); sf::Clock clock; // Update an initial time to construct the GUI before drawing begins. // This makes sure that there are no frames in which no GUI is visible. window->Update( 0.f ); // Start the game loop while ( app_window.isOpen() ) { // Process events sf::Event event; while ( app_window.pollEvent( event ) ) { // Handle events window->HandleEvent( event ); // Close window : exit if ( event.type == sf::Event::Closed ) { app_window.close(); } } // Update the GUI every 5ms if( clock.getElapsedTime().asMicroseconds() >= 5000 ) { // Update() takes the elapsed time in seconds. window->Update( static_cast<float>( clock.getElapsedTime().asMicroseconds() ) / 1000000.f ); clock.restart(); } // Clear screen app_window.clear(); // Draw the GUI m_sfgui.Display( app_window ); // Update the window app_window.display(); } }
void SpinnerExample::Run() { // Create the main SFML window sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI Spinner Example", sf::Style::Titlebar | sf::Style::Close ); // We have to do this because we don't use SFML to draw. app_window.resetGLStates(); // Create our main SFGUI window auto window = sfg::Window::Create(); window->SetTitle( "Title" ); // Create our spinner m_spinner = sfg::Spinner::Create(); // Set how big the spinner should be m_spinner->SetRequisition( sf::Vector2f( 40.f, 40.f ) ); // Create a button and connect the click signal. auto button = sfg::Button::Create( "Toggle" ); button->GetSignal( sfg::Widget::OnLeftClick ).Connect( std::bind( &SpinnerExample::OnButtonClick, this ) ); // Create a horizontal box layouter and add widgets to it. auto box = sfg::Box::Create( sfg::Box::Orientation::HORIZONTAL, 5.0f ); box->Pack( m_spinner ); box->Pack( button, false ); // Add the box to the window. window->Add( box ); // Our clock to make the spinner spin ;) sf::Clock clock; // Update an initial time to construct the GUI before drawing begins. // This makes sure that there are no frames in which no GUI is visible. window->Update( 0.f ); // Start the game loop while ( app_window.isOpen() ) { // Process events sf::Event event; while ( app_window.pollEvent( event ) ) { // Handle events window->HandleEvent( event ); // Close window : exit if ( event.type == sf::Event::Closed ) { app_window.close(); } } // Update the GUI every 5ms if( clock.getElapsedTime().asMicroseconds() >= 5000 ) { // Update() takes the elapsed time in seconds. window->Update( static_cast<float>( clock.getElapsedTime().asMicroseconds() ) / 1000000.f ); clock.restart(); } // Clear screen app_window.clear(); // Draw the GUI m_sfgui.Display( app_window ); // Update the window app_window.display(); } }
void Application::Run() { sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI Button Example", sf::Style::Titlebar | sf::Style::Close ); // We have to do this because we don't use SFML to draw. app_window.resetGLStates(); window = sfg::Window::Create(); window->SetTitle( "Title" ); sfg::Box::Ptr box = sfg::Box::Create( sfg::Box::VERTICAL ); window->Add( box ); // Possibility 1, normal function sfg::Button::Ptr button1 = sfg::Button::Create(); button1->SetLabel( "Clicky 1" ); button1->OnLeftClick.Connect( &Foo ); box->Pack( button1, false ); // Possibility 2, this class sfg::Button::Ptr button2 = sfg::Button::Create(); button2->SetLabel( "Clicky 2" ); button2->OnLeftClick.Connect( &Application::Bar, this ); box->Pack( button2, false ); // Possibility 3, objects BazClass baz_array[3] = { BazClass( 1 ), BazClass( 2 ), BazClass( 3 ) }; for( int i = 0; i < 3; i++ ) { std::stringstream sstr; sstr << "Clicky " << i + 3; sfg::Button::Ptr button = sfg::Button::Create(); button->SetLabel( sstr.str() ); // This is just a more complicated way of passing a pointer to a // BazClass to Connect() when the BazClass object is part of an array. // Passing normal pointers such as &baz1 would also work. button->OnLeftClick.Connect( &BazClass::Baz, &( baz_array[i] ) ); box->Pack( button, false ); } // Notice that with possibility 3 you can do very advanced things. The tricky // part of implementing it this way is that the method address has to be // known at compile time, which means that only the instanciated object itself // is able to pick how it will behave when that method is called on it. This // way you can also connect signals to dynamically determined behavior. // For further reading on this topic refer to Design Patterns and as // specialized cases similar to the one in this example the // Factory Method Pattern and Abstract Factory Pattern. while ( app_window.isOpen() ) { sf::Event event; while ( app_window.pollEvent( event ) ) { window->HandleEvent( event ); if ( event.type == sf::Event::Closed ) { app_window.close(); } } // Update the GUI, note that you shouldn't normally // pass 0 seconds to the update method. window->Update( 0.f ); // Clear screen app_window.clear(); // Draw the GUI m_sfgui.Display( app_window ); // Update the window app_window.display(); } // If you have any global or static widgets, // you need to reset their pointers before your // application exits. window.reset(); }
bool UpgradeBuilding::enter(sfg::SFGUI& sfgui, sf::RenderWindow& window, Character *ptrCharacter) { // Check if the given pointer is null if(ptrCharacter == nullptr) throw std::runtime_error( "Problem with the character pointer in the fuel menu" ); //If so, throw an error // Else, store it in the class else m_ptrCharacter = ptrCharacter; // Set the money Label setMoneyLabel(); // Set the state of the buttons verifyButtonsState(); // Set the fraction of the life bar who's full m_lifeBar->SetFraction( m_ptrCharacter->getLife().fractionOfLifeFull() ); // Create an event and clock object sf::Event event; sf::Clock clock; // Be sure m_wanToQuit is set to false m_wantToExit = false; // Show the gui window m_window->Show(true); while ( !m_wantToExit ) { while ( window.pollEvent( event ) ) { // Handle events m_window->HandleEvent( event ); // Close window, return false to close the app properly if( event.type == sf::Event::Closed ) { // Set the member pointer to null to avoid memory leaks m_ptrCharacter = nullptr; // Don't show the gui window m_window->Show(false); return false; } if( event.type == sf::Event::KeyPressed ) { if(event.key.code == sf::Keyboard::Escape) m_wantToExit = true; } } // Update the GUI m_window->Update( clock.restart().asSeconds() ); // Draw the GUI, but don't clear the screen! sfgui.Display( window ); // Update the window window.display(); } // Set the member pointer to null to avoid memory leaks m_ptrCharacter = nullptr; // Don't show the gui window m_window->Show(false); // Return true, we want to continue the game return true; }
void ButtonsExample::Run() { // Create the main SFML window sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI Buttons Example", sf::Style::Titlebar | sf::Style::Close ); // We have to do this because we don't use SFML to draw. app_window.resetGLStates(); // Create our main SFGUI window m_window = sfg::Window::Create(); m_window->SetTitle( "Title" ); // Create a Box to contain all our fun buttons ;) sfg::Box::Ptr box = sfg::Box::Create( sfg::Box::VERTICAL, 5.f ); // Create the Button itself. m_button = sfg::Button::Create( "Click me" ); // Add the Button to the Box box->Pack( m_button ); // So that our Button has a meaningful purpose // (besides just looking awesome :P) we need to tell it to connect // to a callback of our choosing to notify us when it is clicked. m_button->GetSignal( sfg::Widget::OnLeftClick ).Connect( &ButtonsExample::ButtonClick, this ); // If attempting to connect to a class method you need to provide // a pointer to it as the second parameter after the function address. // Refer to the Signals example for more information. // Create the ToggleButton itself. m_toggle_button = sfg::ToggleButton::Create( "Toggle me" ); // Connect the OnToggle signal to our handler. m_toggle_button->GetSignal( sfg::ToggleButton::OnToggle ).Connect( &ButtonsExample::ButtonToggle, this ); // Add the ToggleButton to the Box box->Pack( m_toggle_button ); // Create the CheckButton itself. m_check_button = sfg::CheckButton::Create( "Check me" ); // Since a CheckButton is also a ToggleButton we can use // ToggleButton signals to handle events for CheckButtons. m_check_button->GetSignal( sfg::ToggleButton::OnToggle ).Connect( &ButtonsExample::ButtonCheck, this ); // Add the CheckButton to the Box box->Pack( m_check_button ); // Just to keep things tidy ;) box->Pack( sfg::Separator::Create() ); // Create our RadioButtons. // RadioButtons each have a group they belong to. If not specified, // a new group is created by default for each RadioButton. You can // then use RadioButton::SetGroup() to set the group of a RadioButton // after you create them. If you already know which buttons will belong // to the same group you can just pass the group of the first button // to the following buttons when you construct them as we have done here. m_radio_button1 = sfg::RadioButton::Create( "Either this" ); m_radio_button2 = sfg::RadioButton::Create( "Or this", m_radio_button1->GetGroup() ); m_radio_button3 = sfg::RadioButton::Create( "Or maybe even this", m_radio_button1->GetGroup() ); // Set the third RadioButton to be the active one. // By default none of the RadioButtons are active at start. m_radio_button3->SetActive( true ); // Here we use the same handler for all three RadioButtons. // RadioButtons are CheckButtons and therefore also ToggleButtons, // hence we can use ToggleButton signals with RadioButtons as well. m_radio_button1->GetSignal( sfg::ToggleButton::OnToggle ).Connect( &ButtonsExample::ButtonSelect, this ); m_radio_button2->GetSignal( sfg::ToggleButton::OnToggle ).Connect( &ButtonsExample::ButtonSelect, this ); m_radio_button3->GetSignal( sfg::ToggleButton::OnToggle ).Connect( &ButtonsExample::ButtonSelect, this ); // Add the RadioButtons to the Box box->Pack( m_radio_button1 ); box->Pack( m_radio_button2 ); box->Pack( m_radio_button3 ); // Finally add the Box to the window. m_window->Add( box ); // Start the game loop while ( app_window.isOpen() ) { // Process events sf::Event event; while ( app_window.pollEvent( event ) ) { // Handle events m_window->HandleEvent( event ); // Close window : exit if ( event.type == sf::Event::Closed ) { app_window.close(); } } // Update the GUI, note that you shouldn't normally // pass 0 seconds to the update method. m_window->Update( 0.f ); // Clear screen app_window.clear(); // Draw the GUI m_sfgui.Display( app_window ); // Update the window app_window.display(); } }
void ComboBoxExample::Run() { // Create the main SFML window sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI Combo Box Example", sf::Style::Titlebar | sf::Style::Close ); // We have to do this because we don't use SFML to draw. app_window.resetGLStates(); // Create our main SFGUI window auto window = sfg::Window::Create(); window->SetTitle( "Title" ); // Create the combo box itself. m_combo_box = sfg::ComboBox::Create(); // Set the entries of the combo box. m_combo_box->AppendItem( "Bar" ); m_combo_box->PrependItem( "Foo" ); m_sel_label = sfg::Label::Create( L"Please select an item!" ); auto add_button = sfg::Button::Create( L"Add item" ); auto remove_button = sfg::Button::Create( L"Remove first item" ); auto clear_button = sfg::Button::Create( L"Clear items" ); auto hbox = sfg::Box::Create( sfg::Box::Orientation::HORIZONTAL, 5 ); hbox->Pack( m_combo_box ); hbox->Pack( add_button, false ); hbox->Pack( remove_button, false ); hbox->Pack( clear_button, false ); auto vbox = sfg::Box::Create( sfg::Box::Orientation::VERTICAL, 5 ); vbox->Pack( hbox, false ); vbox->Pack( m_sel_label, true ); // Add the combo box to the window window->Add( vbox ); // So that our combo box has a meaningful purpose (besides just looking // awesome :P) we need to tell it to connect to a callback of our choosing to // notify us when it is clicked. m_combo_box->GetSignal( sfg::ComboBox::OnSelect ).Connect( std::bind( &ComboBoxExample::OnComboSelect, this ) ); add_button->GetSignal( sfg::Widget::OnLeftClick ).Connect( std::bind( &ComboBoxExample::OnAddItemClick, this ) ); remove_button->GetSignal( sfg::Widget::OnLeftClick ).Connect( std::bind( &ComboBoxExample::OnRemoveItemClick, this ) ); clear_button->GetSignal( sfg::Widget::OnLeftClick ).Connect( std::bind( &ComboBoxExample::OnClearClick, this ) ); // If attempting to connect to a class method you need to provide // a pointer to it as the second parameter after the function address. // Start the game loop while ( app_window.isOpen() ) { // Process events sf::Event event; while ( app_window.pollEvent( event ) ) { // Handle events window->HandleEvent( event ); // Close window : exit if ( event.type == sf::Event::Closed ) { app_window.close(); } } // Update the GUI, note that you shouldn't normally // pass 0 seconds to the update method. window->Update( 0.f ); // Clear screen app_window.clear(); // Draw the GUI m_sfgui.Display( app_window ); // Update the window app_window.display(); } }
void SampleApp::Run() { sf::Event event; //m_window.SetFramerateLimit( 60 ); //m_window.EnableVerticalSync( true ); // Tune Renderer m_sfgui.TuneUseFBO( true ); m_sfgui.TuneAlphaThreshold( .2f ); m_sfgui.TuneCull( true ); // Create widgets. m_wndmain = sfg::Window::Create( sfg::Window::TITLEBAR | sfg::Window::BACKGROUND | sfg::Window::RESIZE ); m_wndmain->SetTitle( L"Example application" ); sfg::Button::Ptr btnaddbuttonh( sfg::Button::Create( L"Add button horizontally" ) ); sfg::Button::Ptr btnaddbuttonv( sfg::Button::Create( L"Add button vertically" ) ); m_titlebar_toggle = sfg::ToggleButton::Create( "Toggle titlebar" ); m_titlebar_toggle->SetActive( true ); { sf::Image add_image; if( add_image.loadFromFile( "data/add.png" ) ) { sfg::Image::Ptr image( sfg::Image::Create( add_image ) ); btnaddbuttonh->SetImage( image ); image = sfg::Image::Create( add_image ); btnaddbuttonv->SetImage( image ); } } sfg::Button::Ptr btnhidewindow( sfg::Button::Create( L"Close window" ) ); btnhidewindow->SetId( "close" ); { sf::Image close_image; if( close_image.loadFromFile( "data/delete.png" ) ) { sfg::Image::Ptr image( sfg::Image::Create( close_image ) ); btnhidewindow->SetImage( image ); } } sfg::Button::Ptr btntogglespace( sfg::Button::Create( L"Box Spacing") ); sfg::Button::Ptr btnloadstyle( sfg::Button::Create( L"Load theme") ); m_entry = sfg::Entry::Create( L"Type" ); m_entry->SetRequisition( sf::Vector2f( 100.f, .0f ) ); m_entry->AppendText( L" something!" ); m_limit_check = sfg::CheckButton::Create( L"Limit to 4 chars" ); m_limit_check->SetId( "limit_check" ); sfg::Entry::Ptr password( sfg::Entry::Create() ); password->HideText( '*' ); // Layout. sfg::Box::Ptr boxtoolbar( sfg::Box::Create( sfg::Box::HORIZONTAL ) ); boxtoolbar->SetSpacing( 5.f ); boxtoolbar->Pack( btnaddbuttonh, false ); boxtoolbar->Pack( btnaddbuttonv, false ); boxtoolbar->Pack( m_titlebar_toggle, false ); boxtoolbar->Pack( btnhidewindow, false ); boxtoolbar->Pack( m_entry, true ); boxtoolbar->Pack( m_limit_check, false ); sfg::Frame::Ptr frame1( sfg::Frame::Create( L"Toolbar 1" ) ); frame1->Add( boxtoolbar ); sfg::Box::Ptr boxtoolbar2( sfg::Box::Create( sfg::Box::HORIZONTAL ) ); boxtoolbar2->SetSpacing( 5.f ); boxtoolbar2->Pack( btntogglespace, false ); boxtoolbar2->Pack( btnloadstyle, false ); m_boxbuttonsh = sfg::Box::Create( sfg::Box::HORIZONTAL ); m_boxbuttonsh->SetSpacing( 5.f ); m_boxbuttonsv = sfg::Box::Create( sfg::Box::VERTICAL ); m_boxbuttonsv->SetSpacing( 5.f ); sfg::Entry::Ptr username_entry( sfg::Entry::Create() ); username_entry->SetMaximumLength( 8 ); m_progress = sfg::ProgressBar::Create( sfg::ProgressBar::HORIZONTAL ); m_progress->SetRequisition( sf::Vector2f( 0.f, 20.f ) ); m_progress_vert = sfg::ProgressBar::Create( sfg::ProgressBar::VERTICAL ); m_progress_vert->SetRequisition( sf::Vector2f( 20.f, 0.f ) ); sfg::Separator::Ptr separatorv( sfg::Separator::Create( sfg::Separator::VERTICAL ) ); m_table = sfg::Table::Create(); m_table->Attach( sfg::Label::Create( L"Please login using your username and password (span example)." ), sf::Rect<sf::Uint32>( 0, 0, 2, 1 ), sfg::Table::FILL, sfg::Table::FILL | sfg::Table::EXPAND ); m_table->Attach( sfg::Label::Create( L"Username:"******"Password:"******"Login" ), sf::Rect<sf::Uint32>( 2, 1, 1, 2 ), sfg::Table::FILL, sfg::Table::FILL ); m_table->Attach( separatorv, sf::Rect<sf::Uint32>( 3, 0, 1, 3 ), sfg::Table::FILL, sfg::Table::FILL ); m_table->Attach( m_progress_vert, sf::Rect<sf::Uint32>( 4, 0, 1, 3 ), sfg::Table::FILL, sfg::Table::FILL ); m_table->SetRowSpacings( 5.f ); m_table->SetColumnSpacings( 5.f ); m_scrolled_window_box = sfg::Box::Create( sfg::Box::VERTICAL ); for( int i = 0; i < 5; i++ ) { sfg::Box::Ptr box = sfg::Box::Create( sfg::Box::HORIZONTAL ); for( int j = 0; j < 20; j++ ) { box->Pack( sfg::Button::Create( L"One button among many" ), true ); } m_scrolled_window_box->Pack( box, false ); } m_scrolled_window = sfg::ScrolledWindow::Create(); m_scrolled_window->SetRequisition( sf::Vector2f( .0f, 160.f ) ); m_scrolled_window->SetScrollbarPolicy( sfg::ScrolledWindow::HORIZONTAL_AUTOMATIC | sfg::ScrolledWindow::VERTICAL_AUTOMATIC ); m_scrolled_window->SetPlacement( sfg::ScrolledWindow::TOP_LEFT ); m_scrolled_window->AddWithViewport( m_scrolled_window_box ); sfg::Scrollbar::Ptr scrollbar( sfg::Scrollbar::Create() ); scrollbar->SetRange( .0f, 100.f ); m_scale = sfg::Scale::Create(); m_scale->SetAdjustment( scrollbar->GetAdjustment() ); m_scale->SetRequisition( sf::Vector2f( 100.f, .0f ) ); boxtoolbar2->Pack( m_scale, false ); m_combo_box = sfg::ComboBox::Create(); for( int index = 0; index < 30; ++index ) { std::stringstream sstr; sstr << "Item " << index; m_combo_box->AppendItem( sstr.str() ); } boxtoolbar2->Pack( m_combo_box, true ); sfg::Frame::Ptr frame2( sfg::Frame::Create( L"Toolbar 2" ) ); frame2->Add( boxtoolbar2 ); frame2->SetAlignment( sf::Vector2f( .8f, .0f ) ); sfg::Separator::Ptr separatorh( sfg::Separator::Create( sfg::Separator::HORIZONTAL ) ); sfg::Box::Ptr box_image( sfg::Box::Create( sfg::Box::HORIZONTAL ) ); box_image->SetSpacing( 15.f ); sfg::Fixed::Ptr fixed_container( sfg::Fixed::Create() ); sfg::Button::Ptr fixed_button( sfg::Button::Create( L"I'm at (34,61)" ) ); fixed_container->Put( fixed_button, sf::Vector2f( 34.f, 61.f ) ); box_image->Pack( fixed_container, false ); sf::Image sfgui_logo; m_image = sfg::Image::Create(); if( sfgui_logo.loadFromFile( "data/sfgui.png" ) ) { m_image->SetImage( sfgui_logo ); box_image->Pack( m_image, false ); } sfg::Button::Ptr mirror_image( sfg::Button::Create( L"Mirror Image" ) ); box_image->Pack( mirror_image, false ); sfg::Box::Ptr spinner_box( sfg::Box::Create( sfg::Box::VERTICAL ) ); m_spinner = sfg::Spinner::Create(); m_spinner->SetRequisition( sf::Vector2f( 40.f, 40.f ) ); m_spinner->Start(); sfg::ToggleButton::Ptr spinner_toggle( sfg::ToggleButton::Create( L"Spin") ); spinner_toggle->SetActive( true ); spinner_box->SetSpacing( 5.f ); spinner_box->Pack( m_spinner, false ); spinner_box->Pack( spinner_toggle, false ); box_image->Pack( spinner_box, false ); sfg::Box::Ptr radio_box( sfg::Box::Create( sfg::Box::VERTICAL ) ); sfg::RadioButton::Ptr radio1( sfg::RadioButton::Create( "Radio 1" ) ); sfg::RadioButton::Ptr radio2( sfg::RadioButton::Create( "Radio 2", radio1->GetGroup() ) ); sfg::RadioButton::Ptr radio3( sfg::RadioButton::Create( "Radio 3", radio2->GetGroup() ) ); radio_box->Pack( radio1 ); radio_box->Pack( radio2 ); radio_box->Pack( radio3 ); box_image->Pack( radio_box, false ); sfg::SpinButton::Ptr spinbutton( sfg::SpinButton::Create( scrollbar->GetAdjustment() ) ); spinbutton->SetRequisition( sf::Vector2f( 80.f, 0.f ) ); spinbutton->SetDigits( 3 ); sfg::Box::Ptr spinbutton_box( sfg::Box::Create( sfg::Box::VERTICAL ) ); spinbutton_box->Pack( spinbutton, false, false ); box_image->Pack( spinbutton_box, false, false ); sfg::ComboBox::Ptr aligned_combo_box( sfg::ComboBox::Create() ); aligned_combo_box->AppendItem( L"I'm way over here" ); aligned_combo_box->AppendItem( L"Me too" ); aligned_combo_box->AppendItem( L"Me three" ); aligned_combo_box->SelectItem( 0 ); sfg::Alignment::Ptr alignment( sfg::Alignment::Create() ); alignment->Add( aligned_combo_box ); box_image->Pack( alignment, true ); alignment->SetAlignment( sf::Vector2f( 1.f, .5f ) ); alignment->SetScale( sf::Vector2f( 0.f, .01f ) ); sfg::Box::Ptr boxmain( sfg::Box::Create( sfg::Box::VERTICAL ) ); boxmain->SetSpacing( 5.f ); boxmain->Pack( scrollbar, false ); boxmain->Pack( m_progress, false ); boxmain->Pack( frame1, false ); boxmain->Pack( frame2, false ); boxmain->Pack( m_boxbuttonsh, false ); boxmain->Pack( m_boxbuttonsv, false ); boxmain->Pack( box_image, true ); boxmain->Pack( separatorh, false ); boxmain->Pack( m_table, true ); boxmain->Pack( m_scrolled_window ); sfg::Notebook::Ptr notebook1( sfg::Notebook::Create() ); sfg::Notebook::Ptr notebook2( sfg::Notebook::Create() ); sfg::Notebook::Ptr notebook3( sfg::Notebook::Create() ); sfg::Notebook::Ptr notebook4( sfg::Notebook::Create() ); notebook1->SetTabPosition( sfg::Notebook::TOP ); notebook2->SetTabPosition( sfg::Notebook::RIGHT ); notebook3->SetTabPosition( sfg::Notebook::BOTTOM ); notebook4->SetTabPosition( sfg::Notebook::LEFT ); sfg::Box::Ptr vertigo_box( sfg::Box::Create( sfg::Box::HORIZONTAL ) ); sfg::Button::Ptr vertigo_button( sfg::Button::Create( L"Vertigo" ) ); vertigo_box->Pack( vertigo_button, true, true ); notebook1->AppendPage( boxmain, sfg::Label::Create( "Page Name Here" ) ); notebook1->AppendPage( notebook2, sfg::Label::Create( "Another Page" ) ); notebook2->AppendPage( notebook3, sfg::Label::Create( "Yet Another Page" ) ); notebook2->AppendPage( sfg::Label::Create( L"" ), sfg::Label::Create( "Dummy Page" ) ); notebook3->AppendPage( notebook4, sfg::Label::Create( "And Another Page" ) ); notebook3->AppendPage( sfg::Label::Create( L"" ), sfg::Label::Create( "Dummy Page" ) ); notebook4->AppendPage( vertigo_box, sfg::Label::Create( "And The Last Page" ) ); notebook4->AppendPage( sfg::Label::Create( L"" ), sfg::Label::Create( "Dummy Page" ) ); m_wndmain->Add( notebook1 ); // Signals. btnaddbuttonh->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnAddButtonHClick, this ); btnaddbuttonv->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnAddButtonVClick, this ); m_titlebar_toggle->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnToggleTitlebarClick, this ); btnhidewindow->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnHideWindowClicked, this ); btntogglespace->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnToggleSpaceClick, this ); m_limit_check->GetSignal( sfg::ToggleButton::OnToggle ).Connect( &SampleApp::OnLimitCharsToggle, this ); btnloadstyle->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnLoadThemeClick, this ); m_scale->GetAdjustment()->GetSignal( sfg::Adjustment::OnChange ).Connect( &SampleApp::OnAdjustmentChange, this ); spinner_toggle->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnToggleSpinner, this ); mirror_image->GetSignal( sfg::Widget::OnLeftClick ).Connect( &SampleApp::OnMirrorImageClick, this ); spinbutton->SetValue( 20.f ); spinbutton->GetAdjustment()->SetMinorStep( .8f ); m_wndmain->SetPosition( sf::Vector2f( 100.f, 100.f ) ); // Another window sfg::Window::Ptr second_window( sfg::Window::Create( sfg::Window::TITLEBAR | sfg::Window::BACKGROUND | sfg::Window::RESIZE ) ); second_window->SetId( "second_window" ); second_window->SetTitle( "Resize this window to see ad-hoc wrapping." ); sfg::Box::Ptr box( sfg::Box::Create( sfg::Box::VERTICAL, 5.f ) ); sfg::Label::Ptr lipsum = sfg::Label::Create( "Nullam ut ante leo. Quisque consequat condimentum pulvinar. " "Duis a enim sapien, ut vestibulum est. Vestibulum commodo, orci non gravida. " "Aliquam sed pretium lacus. " "Nullam placerat mauris vel nulla sagittis pellentesque. " "Suspendisse in justo dui.\n" "Ut dolor massa, gravida eu facilisis convallis, convallis sed odio.\n" "Nunc placerat consequat vehicula." ); lipsum->SetRequisition( sf::Vector2f( 400.f, 0.f ) ); lipsum->SetLineWrap( true ); box->Pack( lipsum ); second_window->Add( box ); second_window->SetPosition( sf::Vector2f( 10.f, 10.f ) ); second_window->SetId( "second_window" ); m_desktop.Add( second_window ); sfg::Window::Ptr third_window( sfg::Window::Create( sfg::Window::TITLEBAR | sfg::Window::BACKGROUND | sfg::Window::RESIZE ) ); m_gl_canvas = sfg::Canvas::Create( true ); m_gl_canvas->SetRequisition( sf::Vector2f( 200.f, 150.f ) ); third_window->Add( m_gl_canvas ); third_window->SetId( "third_window" ); third_window->SetTitle( "Embedded OpenGL drawing" ); third_window->SetPosition( sf::Vector2f( 480.f, 20.f ) ); m_desktop.Add( third_window ); sf::Texture texture; texture.loadFromImage( sfgui_logo ); m_canvas_sprite.setTexture( texture ); sfg::Window::Ptr fourth_window( sfg::Window::Create( sfg::Window::TITLEBAR | sfg::Window::BACKGROUND | sfg::Window::RESIZE ) ); m_sfml_canvas = sfg::Canvas::Create(); m_sfml_canvas->SetRequisition( sf::Vector2f( static_cast<float>( texture.getSize().x ), static_cast<float>( texture.getSize().y ) ) ); fourth_window->Add( m_sfml_canvas ); fourth_window->SetId( "fourth_window" ); fourth_window->SetTitle( "Embedded SFML drawing" ); fourth_window->SetPosition( sf::Vector2f( 760.f, 20.f ) ); m_desktop.Add( fourth_window ); // Add window to desktop m_desktop.Add( m_wndmain ); // Play around with resource manager. sf::Font my_font; my_font.loadFromFile( "data/linden_hill.otf" ); m_desktop.GetEngine().GetResourceManager().AddFont( "custom_font", my_font, false ); // false -> do not manage! // Set properties. m_desktop.SetProperty( "Button#close:Normal", "Color", sf::Color::Yellow ); // #close is sufficient since there is only 1 widget with this id m_desktop.SetProperty( "#close", "FontName", "data/linden_hill.otf" ); m_desktop.SetProperty( "#close", "FontSize", 15.f ); // Multiple properties can be set at once to save calls. m_desktop.SetProperties( "Window#second_window > Box > Label {" " FontName: custom_font;" " FontSize: 18;" "}" ); m_fps_counter = 0; m_fps_clock.restart(); sf::Clock clock; sf::Clock frame_time_clock; sf::Int64 frame_times[5000]; std::size_t frame_times_index = 0; while( m_window.isOpen() ) { while( m_window.pollEvent( event ) ) { if( event.type == sf::Event::Closed ) { m_window.close(); } else if( event.type == sf::Event::Resized ) { m_desktop.UpdateViewRect( sf::FloatRect( 0.f, 0.f, static_cast<float>( event.size.width ), static_cast<float>( event.size.height ) ) ); } m_desktop.HandleEvent( event ); } m_window.draw( m_background_sprite ); sf::Uint64 microseconds = clock.getElapsedTime().asMicroseconds(); // Only update every 5ms if( microseconds > 5000 ) { m_desktop.Update( static_cast<float>( microseconds ) / 1000000.f ); clock.restart(); // Only refresh canvas contents every 5ms too m_gl_canvas->Bind(); m_gl_canvas->Clear( sf::Color( 0, 0, 0, 0 ), true ); RenderCustomGL(); m_gl_canvas->Display(); m_gl_canvas->Unbind(); m_sfml_canvas->Bind(); m_sfml_canvas->Clear( sf::Color( 0, 0, 0, 0 ) ); RenderCustomSFML(); m_sfml_canvas->Display(); m_sfml_canvas->Unbind(); m_window.setActive( true ); } m_sfgui.Display( m_window ); m_window.display(); sf::Int64 frame_time = frame_time_clock.getElapsedTime().asMicroseconds(); frame_time_clock.restart(); frame_times[ frame_times_index ] = frame_time; frame_times_index = ( frame_times_index + 1 ) % 5000; if( m_fps_clock.getElapsedTime().asMicroseconds() >= 1000000 ) { m_fps_clock.restart(); sf::Int64 total_time = 0; for( std::size_t index = 0; index < 5000; ++index ) { total_time += frame_times[index]; } std::stringstream sstr; sstr << "SFGUI test -- FPS: " << m_fps_counter << " -- Frame Time (microsecs): min: " << *std::min_element( frame_times, frame_times + 5000 ) << " max: " << *std::max_element( frame_times, frame_times + 5000 ) << " avg: " << static_cast<float>( total_time ) / 5000.f; m_window.setTitle( sstr.str() ); m_fps_counter = 0; } ++m_fps_counter; } glDeleteLists( m_custom_draw_display_list, 1 ); }