From e04be824aa6b66069e25550009f8793387dc104d Mon Sep 17 00:00:00 2001 From: Daniel Evans Date: Wed, 25 Dec 2013 19:54:22 +0000 Subject: [PATCH] Menu Framework --- tests/CMakeLists.txt | 5 +-- tests/test_menu.cpp | 32 +++++++++++++++ viewer/MenuSystem.hpp | 91 +++++++++++++++++++++++++++++++++++++++++++ viewer/main.cpp | 23 +++++++++-- 4 files changed, 145 insertions(+), 6 deletions(-) create mode 100644 tests/test_menu.cpp create mode 100644 viewer/MenuSystem.hpp diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e2642659..cf28b3fe 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -5,12 +5,11 @@ ADD_DEFINITIONS(-DBOOST_TEST_DYN_LINK) add_executable(run_tests ${TEST_SOURCES}) include_directories(include) -include_directories(${PROJECT_SOURCE_DIR}/engine/include) find_package(Boost COMPONENTS unit_test_framework REQUIRED) -include_directories(../framework2/include /usr/include/bullet) +include_directories(../framework2/include ../viewer /usr/include/bullet) -target_link_libraries(run_tests renderware sfml-window sfml-system GL GLEW BulletDynamics BulletCollision LinearMath ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) +target_link_libraries(run_tests renderware sfml-window sfml-system sfml-graphics GL GLEW BulletDynamics BulletCollision LinearMath ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY}) add_test(UnitTests run_tests) diff --git a/tests/test_menu.cpp b/tests/test_menu.cpp new file mode 100644 index 00000000..0474b742 --- /dev/null +++ b/tests/test_menu.cpp @@ -0,0 +1,32 @@ +#include +#include "test_globals.hpp" +#include + +BOOST_AUTO_TEST_SUITE(MenuUnitTests) + +BOOST_AUTO_TEST_CASE(menu_test_click) +{ + bool clickered = false; + sf::Font f; + Menu test(f); + test.addEntry(Menu::lambda("Test", [&]{ clickered = true; })); + + BOOST_CHECK(! clickered ); + + // Click underneath the menu item. + test.click(0.f, -1.f); + + BOOST_CHECK(! clickered ); + + float h = test.entries.at(0)->getHeight(); + + test.click(0.f, h + 1.f); + + BOOST_CHECK(! clickered ); + + test.click(0.f, h / 2.f); + + BOOST_CHECK( clickered ); +} + +BOOST_AUTO_TEST_SUITE_END() diff --git a/viewer/MenuSystem.hpp b/viewer/MenuSystem.hpp new file mode 100644 index 00000000..b81cabdf --- /dev/null +++ b/viewer/MenuSystem.hpp @@ -0,0 +1,91 @@ +#ifndef _GAME_MENUSYSTEM_HPP_ +#define _GAME_MENUSYSTEM_HPP_ +#include +#include +#include +#include +#include + +class Menu +{ + sf::Font font; +public: + + Menu(const sf::Font& font) + : font(font) {} + + struct MenuEntry + { + std::string name; + + MenuEntry(const std::string& n) : name(n) {} + + float getHeight() { return 50.f; } + + virtual void draw(const sf::Font& font, sf::RenderWindow& window, sf::Vector2f& basis) + { + sf::Text t; + t.setFont(font); + t.setPosition(basis); + t.setString(name); + window.draw(t); + basis.y += 50.f; + } + + virtual void activate(sf::Vector2f click) = 0; + }; + + struct Entry : public MenuEntry + { + std::function callback; + + Entry(const std::string& title, std::function cb) + : MenuEntry(title), callback(cb) {} + + void activate(sf::Vector2f click) { callback(); } + }; + + static std::shared_ptr lambda(const std::string& n, std::function callback) + { + return std::shared_ptr(new Entry(n, callback)); + } + + std::vector> entries; + + sf::Vector2f offset; + + void addEntry(std::shared_ptr entry) + { + entries.push_back(entry); + } + + void draw(sf::RenderWindow& window) + { + sf::Vector2f basis(offset); + for(auto it = entries.begin(); + it != entries.end(); + ++it) + { + (*it)->draw(font, window, basis); + } + } + + void click(const float x, const float y) + { + sf::Vector2f c(x - offset.x, y - offset.y); + for(auto it = entries.begin(); + it != entries.end(); + ++it) + { + if( c.y > 0.f && c.y < (*it)->getHeight() ) { + (*it)->activate(c); + return; + } + else { + c.y -= (*it)->getHeight(); + } + } + } +}; + +#endif \ No newline at end of file diff --git a/viewer/main.cpp b/viewer/main.cpp index a298a3ac..dbdc69d4 100644 --- a/viewer/main.cpp +++ b/viewer/main.cpp @@ -14,12 +14,12 @@ #include #include +#include "MenuSystem.hpp" #include #include #include #include -#include constexpr int WIDTH = 800, HEIGHT = 600; @@ -298,6 +298,7 @@ void handleInputEvent(sf::Event &event) break; case sf::Keyboard::M: mouseGrabbed = ! mouseGrabbed; + window.setMouseCursorVisible(! mouseGrabbed); break; case sf::Keyboard::P: debugMode+=1; @@ -320,7 +321,7 @@ void handleInputEvent(sf::Event &event) break; case sf::Event::KeyReleased: switch(event.key.code) { - case sf::Keyboard::Space: + case sf::Keyboard::LShift: moveSpeed = 20.f; break; case sf::Keyboard::W: @@ -670,7 +671,13 @@ int main(int argc, char *argv[]) init(argv[optind], loadWorld); sf::Clock clock; - + + /*Menu mainMenu(font); + mainMenu.offset = sf::Vector2f(50.f, 100.f); + mainMenu.addEntry(Menu::lambda("Test", [] { std::cout << "Test" << std::endl; })); + mainMenu.addEntry(Menu::lambda("Options", [] { std::cout << "Options" << std::endl; })); + mainMenu.addEntry(Menu::lambda("Exit", [] { window.close(); }));*/ + float accum = 0.f; float ts = 1.f / 60.f; @@ -680,6 +687,14 @@ int main(int argc, char *argv[]) handleGlobalEvent(event); handleCommandEvent(event); handleInputEvent(event); + + if(! mouseGrabbed) { + switch(event.type) { + case sf::Event::MouseButtonPressed: + mainMenu.click(event.mouseButton.x, event.mouseButton.y); + break; + } + } } accum += clock.restart().asSeconds(); @@ -690,6 +705,8 @@ int main(int argc, char *argv[]) } render(); + + mainMenu.draw(window); window.display(); }