1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-25 20:02:40 +01:00
openrw/rwgame/MenuSystem.hpp

137 lines
2.8 KiB
C++
Raw Normal View History

2013-12-25 20:54:22 +01:00
#ifndef _GAME_MENUSYSTEM_HPP_
#define _GAME_MENUSYSTEM_HPP_
#include <string>
#include <memory>
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
2014-01-01 01:37:16 +01:00
#include <glm/glm.hpp>
2013-12-25 20:54:22 +01:00
#include <functional>
class Menu
{
sf::Font font;
public:
Menu(const sf::Font& font)
2014-01-01 01:37:16 +01:00
: font(font), activeEntry(-1) {}
2013-12-25 20:54:22 +01:00
struct MenuEntry
{
std::string name;
2014-06-01 19:26:53 +02:00
float _size;
2013-12-25 20:54:22 +01:00
2014-06-01 19:26:53 +02:00
MenuEntry(const std::string& n, float size = 38.f) : name(n), _size(size) {}
2013-12-25 20:54:22 +01:00
2014-06-01 19:26:53 +02:00
float getHeight() { return _size; }
2013-12-25 20:54:22 +01:00
2014-01-01 01:37:16 +01:00
virtual void draw(const sf::Font& font, sf::RenderWindow& window, glm::vec2& basis)
2013-12-25 20:54:22 +01:00
{
sf::Text t;
t.setFont(font);
2014-06-01 19:26:53 +02:00
t.setPosition(basis.x + 6, basis.y + 2);
2013-12-25 20:54:22 +01:00
t.setString(name);
2014-06-01 19:26:53 +02:00
auto cSize = getHeight() - 10.f;
t.setCharacterSize(cSize);
2013-12-25 20:54:22 +01:00
window.draw(t);
2013-12-27 00:18:55 +01:00
basis.y += getHeight();
2013-12-25 20:54:22 +01:00
}
2014-01-01 01:37:16 +01:00
virtual void activate(float clickX, float clickY) = 0;
2013-12-25 20:54:22 +01:00
};
struct Entry : public MenuEntry
{
std::function<void (void)> callback;
2014-06-01 19:26:53 +02:00
Entry(const std::string& title, std::function<void (void)> cb, float size)
: MenuEntry(title, size), callback(cb) {}
2013-12-25 20:54:22 +01:00
2014-01-01 01:37:16 +01:00
void activate(float clickX, float clickY) { callback(); }
2013-12-25 20:54:22 +01:00
};
2014-06-01 19:26:53 +02:00
static std::shared_ptr<MenuEntry> lambda(const std::string& n, std::function<void (void)> callback, float size = 38.f)
2013-12-25 20:54:22 +01:00
{
2014-06-01 19:26:53 +02:00
return std::shared_ptr<MenuEntry>(new Entry(n, callback, size));
2013-12-25 20:54:22 +01:00
}
std::vector<std::shared_ptr<MenuEntry>> entries;
2014-01-01 01:37:16 +01:00
/**
* Active Entry index
*/
int activeEntry;
glm::vec2 offset;
2013-12-25 20:54:22 +01:00
void addEntry(std::shared_ptr<MenuEntry> entry)
{
entries.push_back(entry);
}
void draw(sf::RenderWindow& window)
{
2014-01-01 01:37:16 +01:00
glm::vec2 basis(offset);
for(size_t i = 0;
i < entries.size();
++i)
2013-12-25 20:54:22 +01:00
{
2014-06-10 18:51:55 +02:00
if(activeEntry >= 0 && i == (unsigned) activeEntry) {
2014-06-01 19:26:53 +02:00
sf::RectangleShape rs(sf::Vector2f(250.f, entries[i]->getHeight()));
2014-01-01 01:37:16 +01:00
rs.setPosition(basis.x, basis.y);
rs.setFillColor(sf::Color::Cyan);
window.draw(rs);
}
entries[i]->draw(font, window, basis);
}
}
void hover(const float x, const float y)
{
glm::vec2 c(x - offset.x, y - offset.y);
for(size_t i = 0;
i < entries.size();
++i)
{
if( c.y > 0.f && c.y < entries[i]->getHeight() ) {
activeEntry = i;
return;
}
else {
c.y -= entries[i]->getHeight();
}
2013-12-25 20:54:22 +01:00
}
}
void click(const float x, const float y)
{
2014-01-01 01:37:16 +01:00
glm::vec2 c(x - offset.x, y - offset.y);
2013-12-25 20:54:22 +01:00
for(auto it = entries.begin();
it != entries.end();
++it)
{
if( c.y > 0.f && c.y < (*it)->getHeight() ) {
2014-01-01 01:37:16 +01:00
(*it)->activate(c.x, c.y);
2013-12-25 20:54:22 +01:00
return;
}
else {
c.y -= (*it)->getHeight();
}
}
}
2014-01-01 01:37:16 +01:00
// Activates the menu entry at the current active index.
void activate()
{
2014-06-10 18:51:55 +02:00
if(activeEntry >= 0 && (unsigned) activeEntry < entries.size()) {
2014-01-01 01:37:16 +01:00
entries[activeEntry]->activate(0.f, 0.f);
}
}
void move(int movement)
{
activeEntry = std::min<const int>(entries.size()-1, std::max<const int>(0, activeEntry + movement));
}
2013-12-25 20:54:22 +01:00
};
2014-06-01 19:26:53 +02:00
#endif