Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListBox widget added. #31

Open
wants to merge 14 commits into
base: master
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
.idea
*.a
*.o
*.os
Expand Down
16 changes: 15 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ option( SFGUI_BUILD_EXAMPLES "Build examples."
option( SFGUI_BUILD_DOC "Generate API documentation." OFF)
option( SFGUI_INCLUDE_FONT "Include default font in library (DejaVuSans)." ON)
option( SFML_STATIC_LIBRARIES "Do you want to link SFML statically?" OFF)
option( SFGUI_BOOST_FILESYSTEM_SUPPORT "Do you want SFGUI to support Boost.FileSystem? (enable FilePickerDialog widget)" OFF)


# Find packages.
find_package( OpenGL REQUIRED )
find_package( SFML 2.5 REQUIRED COMPONENTS graphics window system )

CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/include/SFGUI/Config.hpp.in ${CMAKE_CURRENT_BINARY_DIR}/include/SFGUI/Config.hpp)
include_directories(${CMAKE_CURRENT_BINARY_DIR}/include)

set( INCLUDE_PATH "${PROJECT_SOURCE_DIR}/include/" )
set( SOURCE_PATH "${PROJECT_SOURCE_DIR}/src/" )

Expand Down Expand Up @@ -59,6 +63,11 @@ endif()

target_link_libraries( ${TARGET} PUBLIC sfml-graphics sfml-window sfml-system ${OPENGL_gl_LIBRARY} )

# Link to Boost.FileSystem if enabled
if( SFGUI_BOOST_FILESYSTEM_SUPPORT )
target_link_libraries( sfgui ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} )
endif()

# Tell the compiler to export when necessary.
set_target_properties( ${TARGET} PROPERTIES DEFINE_SYMBOL SFGUI_EXPORTS )

Expand Down Expand Up @@ -115,7 +124,7 @@ elseif( APPLE )
IMPORTED_LOCATION "${COREFOUNDATION_LIBRARY}"
INTERFACE_INCLUDE_DIRECTORIES "/System/Library/Frameworks/CoreFoundation.framework/Headers"
)

target_link_libraries( ${TARGET} PUBLIC CoreFoundation )
set( SHARE_PATH "${CMAKE_INSTALL_PREFIX}/share/SFGUI" )
set( LIB_PATH "lib" )
Expand Down Expand Up @@ -165,6 +174,11 @@ install(
DESTINATION include
)

install(
DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/include
DESTINATION .
)

install(
FILES README.md AUTHORS.md LICENSE.md FONT.LICENSE.md CHANGELOG.md
DESTINATION "${SHARE_PATH}"
Expand Down
11 changes: 9 additions & 2 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,15 @@ build_example( "ProgressBar" "ProgressBar.cpp" )
build_example( "SpinButton" "SpinButton.cpp" )
build_example( "Canvas" "Canvas.cpp" )
build_example( "CustomWidget" "CustomWidget.cpp" )
build_example( "ListBox" "ListBox.cpp" )
build_example( "SFGUI-Test" "Test.cpp" )

if( SFGUI_BOOST_FILESYSTEM_SUPPORT )
build_example( "FilePickerDialog" "FilePickerDialog.cpp" )
include_directories( SYSTEM ${Boost_INCLUDE_DIR} )
target_link_libraries( FilePickerDialog ${Boost_SYSTEM_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} )
endif()

# Copy data directory to build cache directory to be able to run examples from
# there. Useful for testing stuff.
# Don't try to copy if the directories are the same.
Expand All @@ -49,13 +56,13 @@ if( NOT ( "${PROJECT_SOURCE_DIR}" STREQUAL "${PROJECT_BINARY_DIR}" ) )
COMMAND "${CMAKE_COMMAND}"
ARGS -E copy_directory "${PROJECT_SOURCE_DIR}/examples/data" "${PROJECT_BINARY_DIR}/examples/data"
)

add_custom_command(
TARGET "Image"
COMMAND "${CMAKE_COMMAND}"
ARGS -E copy_directory "${PROJECT_SOURCE_DIR}/examples/data" "${PROJECT_BINARY_DIR}/examples/data"
)

add_custom_command(
TARGET "Canvas"
COMMAND "${CMAKE_COMMAND}"
Expand Down
4 changes: 2 additions & 2 deletions examples/CustomWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class MyCustomWidget : public sfg::Widget {
5.f,
inverted_color,
background_color,
20.f
20
)
);

Expand All @@ -120,7 +120,7 @@ class MyCustomWidget : public sfg::Widget {
255
),
inner_border_color,
20.f
20
)
);

Expand Down
88 changes: 88 additions & 0 deletions examples/FilePickerDialog.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
// Always include the necessary header files.
// Including SFGUI/Widgets.hpp includes everything
// you can possibly need automatically.
#include <SFGUI/SFGUI.hpp>
#include <SFGUI/Widgets.hpp>

#include <SFML/Graphics.hpp>

int main() {
// Create the main SFML window
sf::RenderWindow app_window( sf::VideoMode( 800, 600 ), "SFGUI Window Example", sf::Style::Titlebar | sf::Style::Close );

// We have to do this because we don't use SFML to draw.
app_window.resetGLStates();

// Create an SFGUI. This is required before doing anything with SFGUI.
sfg::SFGUI sfgui;

// Create our main SFGUI window

// Almost everything in SFGUI is handled through smart pointers
// for automatic resource management purposes. You create them
// and they will automatically be destroyed when the time comes.

// Creation of widgets is always done with it's Create() method
// which will return a smart pointer owning the new widget.
auto window = sfg::FilePickerDialog::Create( "/home/victor" );

// Here we can set the window's title bar text.
window->SetTitle( "A really really really really long title" );

window->GetSignal( sfg::FilePickerDialog::OnCancel ).Connect(
[]()
{
std::cout << "Path selection cancelled !" << std::endl;
}
);
window->GetSignal( sfg::FilePickerDialog::OnOk ).Connect(
[window]()
{
std::cout << "Selected path : \"" << window->GetSelectedPath().toAnsiString() << "\"" << std::endl;
}
);

// For more things to set around the window refer to the
// API documentation.

// Start the game loop
while ( app_window.isOpen() ) {
// Process events
sf::Event event;

while ( app_window.pollEvent( event ) ) {
// Every frame we have to send SFML events to the window
// to enable user interactivity. Without doing this your
// GUI is nothing but a big colorful picture ;)
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();

// After drawing the rest of your game, you have to let the GUI
// render itself. If you don't do this you will never be able
// to see it ;)
sfgui.Display( app_window );

// NOTICE
// Because the window doesn't have any children it will shrink to
// it's minimum size of (0,0) resulting in you not seeing anything
// except the title bar text ;) Don't worry, in the Label example
// you'll get to see more.

// Update the window
app_window.display();
}

return EXIT_SUCCESS;
}
138 changes: 138 additions & 0 deletions examples/ListBox.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
// Always include the necessary header files.
// Including SFGUI/Widgets.hpp includes everything
// you can possibly need automatically.
#include <SFGUI/SFGUI.hpp>
#include <SFGUI/Widgets.hpp>

#include <SFML/Graphics.hpp>

int main() {
sfg::SFGUI sfgui;
sf::RenderWindow window(sf::VideoMode(800, 600), "ListBox Example");
window.setVerticalSyncEnabled(true);
window.setFramerateLimit(30);

sf::Image firstImage;
firstImage.loadFromFile("data/add.png");

sf::Image secondImage;
secondImage.loadFromFile("data/delete.png");

sfg::Desktop desktop;

auto window1 = sfg::Window::Create();
window1->SetTitle( "ListBox with ItemTextPolicy::RESIZE_LISTBOX" );

auto box1 = sfg::Box::Create( sfg::Box::Orientation::VERTICAL );
box1->SetSpacing( 5.f );
box1->PackEnd( sfg::Label::Create( "The minimum width\nof this ListBox\ncorresponds to the largest\nitem's text width." ), false, true );

auto listbox1 = sfg::ListBox::Create();
listbox1->AppendItem( "This is the first item" );
listbox1->AppendItem( "Second item" );
listbox1->AppendItem( "Third item which is a bit large" );
listbox1->AppendItem( "Fourth item" );
listbox1->AppendItem( "Fifth item" );
listbox1->AppendItem( "Sixth item" );
listbox1->AppendItem( "Last one !" );
box1->PackEnd( listbox1 );
listbox1->SetImagesSize(sf::Vector2f(32.f, 32.f));

window1->Add( box1 );

auto window2 = sfg::Window::Create();
window2->SetTitle( "ListBox with ItemTextPolicy::SHRINK" );

auto box2 = sfg::Box::Create( sfg::Box::Orientation::VERTICAL );
box2->SetSpacing( 5.f );
auto label2 = sfg::Label::Create( "The items' texts\nare shrinked if the\nListBox is not big\nenough." );
box2->PackEnd( label2, false, true );

auto listbox2 = sfg::ListBox::Create();
listbox2->AppendItem( "This is the first item (long text)" );
listbox2->AppendItem( "Second item", firstImage );
listbox2->AppendItem( "Third item which is very long !", secondImage );
listbox2->AppendItem( "Fourth item" );
listbox2->AppendItem( "Fifth item" );
listbox2->AppendItem( "Sixth item, again it's too large !" );
listbox2->AppendItem( "Last one !" );
listbox2->SetItemTextPolicy( sfg::ListBox::ItemTextPolicy::SHRINK );
box2->PackEnd( listbox2 );
listbox2->SetImagesSize(sf::Vector2f(32.f, 32.f));

window2->Add( box2 );

auto window3 = sfg::Window::Create();
window3->SetTitle( "ListBox with ItemTextPolicy::SHRINK" );

auto box3 = sfg::Box::Create( sfg::Box::Orientation::VERTICAL );
box3->SetSpacing( 5.f );
auto label3 = sfg::Label::Create( "You can select multiple\nitems in this ListBox." );
box3->PackEnd( label3, false, true );

auto listbox3 = sfg::ListBox::Create();
listbox3->AppendItem( "First item" );
listbox3->AppendItem( "Second item" );
listbox3->AppendItem( "Third item" );
listbox3->AppendItem( "Fourth item" );
listbox3->AppendItem( "Fifth item" );
listbox3->AppendItem( "Sixth item" );
listbox3->AppendItem( "Last one !" );
listbox3->SetSelectionMode( sfg::ListBox::SelectionMode::MULTI_SELECTION );
listbox3->SetSelection( {1, 3, 4, 5} );
box3->PackEnd( listbox3 );

window3->Add( box3 );

desktop.Add( window1 );
desktop.Add( window2 );
desktop.Add( window3 );

sf::Vector2f windowSize( static_cast<float>( window.getSize().x ), static_cast<float>( window.getSize().y ) );

window2->SetPosition(sf::Vector2f(windowSize.x/2.f - window2->GetRequisition().x/2.f, windowSize.y/2.f - window2->GetRequisition().y/2.f));
window3->SetPosition(sf::Vector2f(windowSize.x - window3->GetRequisition().x - 100.f, windowSize.y - window3->GetRequisition().y - 100.f));

sf::Event event;
sf::Clock clock;

window.resetGLStates();

int i = 0;

while (window.isOpen())
{
while (window.pollEvent(event))
{
desktop.HandleEvent( event );
switch(event.type)
{
case sf::Event::Closed:
window.close();
break;
case sf::Event::KeyPressed:
if( event.key.code == sf::Keyboard::R ) {
listbox3->RemoveItem(2);
} else if( event.key.code == sf::Keyboard::I ) {
listbox3->InsertItem(3, "Inserted item #" + std::to_string(i));
++i;
} else if( event.key.code == sf::Keyboard::A) {
listbox3->AppendItem("Appended item #" + std::to_string(i));
++i;
} else if( event.key.code == sf::Keyboard::P) {
listbox3->PrependItem("Prepended item #" + std::to_string(i));
++i;
}
break;
default:
break;
}
}
desktop.Update( clock.restart().asSeconds() );
window.clear();
sfgui.Display( window );
window.display();
}

return 0;
}
2 changes: 2 additions & 0 deletions include/SFGUI/Config.hpp → include/SFGUI/Config.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@
#define SFGUI_DEBUG
#include <iostream> // XXX Only for debugging purposes.
#endif

#cmakedefine SFGUI_BOOST_FILESYSTEM_SUPPORT
7 changes: 7 additions & 0 deletions include/SFGUI/Engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ class Notebook;
class Spinner;
class ComboBox;
class SpinButton;
class ListBox;

class Selector;
class RenderQueue;
Expand Down Expand Up @@ -164,6 +165,12 @@ class SFGUI_API Engine {
*/
virtual std::unique_ptr<RenderQueue> CreateSpinButtonDrawable( std::shared_ptr<const SpinButton> spinbutton ) const = 0;

/** Create drawable for listbox widgets.
* @param listbox Widget.
* @return New drawable object (unmanaged memory!).
*/
virtual std::unique_ptr<RenderQueue> CreateListBoxDrawable( std::shared_ptr<const ListBox> listbox ) const = 0;

/** Get maximum line height.
* @param font Font.
* @param font_size Font size.
Expand Down
1 change: 1 addition & 0 deletions include/SFGUI/Engines/BREW.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ class SFGUI_API BREW : public Engine {
std::unique_ptr<RenderQueue> CreateSpinnerDrawable( std::shared_ptr<const Spinner> spinner ) const override;
std::unique_ptr<RenderQueue> CreateComboBoxDrawable( std::shared_ptr<const ComboBox> combo_box ) const override;
std::unique_ptr<RenderQueue> CreateSpinButtonDrawable( std::shared_ptr<const SpinButton> spinbutton ) const override;
std::unique_ptr<RenderQueue> CreateListBoxDrawable( std::shared_ptr<const ListBox> listbox ) const override;

private:
static std::unique_ptr<RenderQueue> CreateBorder( const sf::FloatRect& rect, float border_width, const sf::Color& light_color, const sf::Color& dark_color );
Expand Down
1 change: 1 addition & 0 deletions include/SFGUI/Entry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ class SFGUI_API Entry : public Widget {

// Signals.
static Signal::SignalID OnTextChanged; //!< Fired when the text changes.
static Signal::SignalID OnReturnPressed; //!< Fired when enter is pressed.

protected:
/** Ctor.
Expand Down
Loading