Skip to content

ListBox widget added. #31

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

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;
}
23 changes: 23 additions & 0 deletions include/SFGUI/Button.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ class Image;
*/
class SFGUI_API Button : public Bin {
public:
enum Alignment {
CENTER,
LEFT = 0x1,
RIGHT = 0x2,
TOP = 0x4,
BOTTOM = 0x8,
HORIZONTAL = LEFT + RIGHT,
VERTICAL = TOP + BOTTOM,
};

typedef std::shared_ptr<Button> Ptr; //!< Shared pointer.
typedef std::shared_ptr<const Button> PtrConst; //!< Shared pointer.

Expand All @@ -24,6 +34,16 @@ class SFGUI_API Button : public Bin {

const std::string& GetName() const override;

/** Set alignment.
* @param alignment Alignment.
*/
void SetAlignment(Alignment alignment);

/** Get alignment.
* @return Alignment.
*/
const Alignment& GetAlignment() const;

/** Set label.
* @param label Label.
*/
Expand Down Expand Up @@ -69,6 +89,9 @@ class SFGUI_API Button : public Bin {
void AllocateChild();

sf::String m_label;
Alignment m_alignment;
};

}

sfg::Button::Alignment operator|(sfg::Button::Alignment a, sfg::Button::Alignment b);
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
5 changes: 5 additions & 0 deletions include/SFGUI/Desktop.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ class SFGUI_API Desktop {
*/
void BringToFront( std::shared_ptr<const Widget> child );

/** Is any widget focused.
* @return true if any widget is focused, false otherwise.
*/
bool IsAnyWidgetFocused();

private:
typedef std::deque<std::shared_ptr<Widget>> WidgetsList;

Expand Down
Loading