Ajout de "widgets" : éléments d'interface interactive

This commit is contained in:
Mattéo Delabre 2016-04-06 00:31:10 +02:00
parent a94b1cda98
commit 0aa9e86af7
5 changed files with 258 additions and 1 deletions

2
CMakeLists.txt vendored
View File

@ -3,7 +3,7 @@ project(ptf)
# Inclusion des fichiers d'en-tête et de source
include_directories(include)
file(GLOB SOURCES "src/*.cpp" "src/*.c")
file(GLOB SOURCES "src/*.cpp" "src/*.c" "src/util/*.cpp")
# Affichage de tous les avertisements
if(MSVC)

View File

@ -0,0 +1,41 @@
#ifndef __PTF_UTIL_WIDGET_BUTTON_HPP__
#define __PTF_UTIL_WIDGET_BUTTON_HPP__
#include <SFML/Graphics.hpp>
#include <functional>
#include "manager.hpp"
/**
* Affiche un bouton pouvant être cliqué
*/
class WidgetButton {
private:
Manager& manager;
std::function<void(void)> click_cb;
unsigned int shape;
sf::RectangleShape button;
sf::VertexArray button_shape;
public:
static const unsigned int ARROW_UP;
static const unsigned int ARROW_DOWN;
WidgetButton(
Manager& manager, std::function<void(void)> click_cb,
sf::Vector2f size, unsigned int shape
);
/**
* Process l'événement et renvoie true si
* on s'en est servi
*/
bool processEvent(const sf::Event& event);
/**
* Dessine le widget à la position (haut-gauche) donnée
*/
void draw(sf::Vector2f position);
};
#endif

View File

@ -0,0 +1,55 @@
#ifndef __PTF_UTIL_WIDGET_TIMER_HPP__
#define __PTF_UTIL_WIDGET_TIMER_HPP__
#include <SFML/Graphics.hpp>
#include <functional>
#include "util/widget_button.hpp"
#include "manager.hpp"
/**
* Affiche le compteur de temps pouvant (ou non)
* être modifié
*/
class WidgetTimer {
private:
Manager& manager;
std::function<void(int)> time_left_cb;
int time_left;
sf::RectangleShape timer_zone;
sf::Text timer_text;
WidgetButton timer_up;
WidgetButton timer_down;
public:
WidgetTimer(Manager& manager, std::function<void(int)> time_left_cb);
/**
* Process l'événement et renvoie true si
* on s'en est servi
*/
bool processEvent(const sf::Event& event);
/**
* Dessine le widget à la position (haut-gauche) donnée
*/
void draw(sf::Vector2f position);
/**
* Augmente le temps de 5 secondes
*/
void addTime();
/**
* Diminue le temps de 5 secondes
*/
void subtractTime();
/**
* Modifie le temps restant
*/
void setTimeLeft(int set_time_left);
};
#endif

View File

@ -0,0 +1,72 @@
#include "util/widget_button.hpp"
const unsigned int WidgetButton::ARROW_UP = 0;
const unsigned int WidgetButton::ARROW_DOWN = 1;
const sf::Color ARROW_COLOR = sf::Color(33, 33, 33);
const sf::Color CLICKED_COLOR = sf::Color(187, 222, 251);
WidgetButton::WidgetButton(
Manager& manager, std::function<void(void)> click_cb,
sf::Vector2f size, unsigned int shape
) : manager(manager), click_cb(click_cb), shape(shape), button(size) {
if (shape == WidgetButton::ARROW_UP || shape == WidgetButton::ARROW_DOWN) {
button_shape.setPrimitiveType(sf::Triangles);
button_shape.resize(3);
button_shape[0].color = ARROW_COLOR;
button_shape[1].color = ARROW_COLOR;
button_shape[2].color = ARROW_COLOR;
}
}
bool WidgetButton::processEvent(const sf::Event& event) {
if (event.type == sf::Event::MouseButtonPressed) {
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
if (event.mouseButton.button == sf::Mouse::Left) {
// clic gauche sur le bouton : appel de la callback
if (button.getGlobalBounds().contains(position)) {
click_cb();
return true;
}
}
}
return false;
}
void WidgetButton::draw(sf::Vector2f position) {
sf::RenderWindow& window = manager.getWindow();
// positionnement du bouton
button.setPosition(position);
sf::FloatRect box = button.getGlobalBounds();
sf::Vector2f center(box.left + box.width / 2, box.top + box.height / 2);
if (shape == WidgetButton::ARROW_UP) {
button_shape[0].position = center + sf::Vector2f(-5, 2);
button_shape[1].position = center + sf::Vector2f(5, 2);
button_shape[2].position = center + sf::Vector2f(0, -2);
}
if (shape == WidgetButton::ARROW_DOWN) {
button_shape[0].position = center + sf::Vector2f(-5, -2);
button_shape[1].position = center + sf::Vector2f(5, -2);
button_shape[2].position = center + sf::Vector2f(0, 2);
}
// coloration des boutons si enfoncement
button.setFillColor(sf::Color::Transparent);
if (sf::Mouse::isButtonPressed(sf::Mouse::Left)) {
sf::Vector2f mouse_position = (sf::Vector2f) sf::Mouse::getPosition(window);
if (button.getGlobalBounds().contains(mouse_position)) {
button.setFillColor(CLICKED_COLOR);
}
}
window.draw(button);
window.draw(button_shape);
}

89
src/util/widget_timer.cpp Normal file
View File

@ -0,0 +1,89 @@
#include <cmath>
#include "util/widget_timer.hpp"
/**
* Formattage du temps en m:ss
*/
std::string formatTime(int time) {
std::string minutes = std::to_string(time / 60);
std::string seconds = std::to_string(time % 60);
// ajout d'un zéro devant les secondes si nécessaire
if (seconds.size() == 1) {
seconds = "0" + seconds;
}
return minutes + ":" + seconds;
}
WidgetTimer::WidgetTimer(Manager& manager, std::function<void(int)> time_left_cb) :
manager(manager), time_left_cb(time_left_cb), timer_zone(sf::Vector2f(100, 32)),
timer_up(manager, std::bind(&WidgetTimer::addTime, this), sf::Vector2f(30, 16), WidgetButton::ARROW_UP),
timer_down(manager, std::bind(&WidgetTimer::addTime, this), sf::Vector2f(30, 16), WidgetButton::ARROW_DOWN) {
// initialisation des formes
timer_text.setFont(manager.getResourceManager().getFont("main_font.ttf"));
timer_text.setCharacterSize(24);
timer_text.setColor(sf::Color::Black);
}
bool WidgetTimer::processEvent(const sf::Event& event) {
// gestion des boutons
if (timer_up.processEvent(event)) {
return true;
}
if (timer_down.processEvent(event)) {
return true;
}
if (event.type == sf::Event::MouseButtonPressed) {
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
// clic dans le widget : ne rien faire, mais empêcher le traversement
if (timer_zone.getGlobalBounds().contains(position)) {
return true;
}
}
if (event.type == sf::Event::MouseWheelScrolled && event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel) {
// scroll sur le timer : modification du temps alloué au niveau
sf::Vector2f position(event.mouseWheelScroll.x, event.mouseWheelScroll.y);
if (timer_zone.getGlobalBounds().contains(position)) {
time_left_cb(time_left + round(event.mouseWheelScroll.delta));
return true;
}
}
return false;
}
void WidgetTimer::draw(sf::Vector2f position) {
sf::RenderWindow& window = manager.getWindow();
// zone de fond du timer
timer_zone.setPosition(position);
window.draw(timer_zone);
// affichage du temps du niveau
timer_text.setPosition(position + sf::Vector2f(35 - round(timer_text.getGlobalBounds().width / 2), 0));
timer_text.setString(formatTime(time_left));
window.draw(timer_text);
// affichage des boutons
timer_up.draw(position + sf::Vector2f(70, 0));
timer_down.draw(position + sf::Vector2f(70, 16));
}
void WidgetTimer::addTime() {
time_left_cb(time_left + 5);
}
void WidgetTimer::subtractTime() {
time_left_cb(time_left - 5);
}
void WidgetTimer::setTimeLeft(int set_time_left) {
time_left = set_time_left;
}