From dca255f7bdde571d88fb8e70f8e0310f092b8872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matt=C3=A9o=20Delabre?= Date: Tue, 19 Apr 2016 17:52:05 +0200 Subject: [PATCH] =?UTF-8?q?R=C3=A9impl=C3=A9mentation=20initiale=20de=20la?= =?UTF-8?q?=20toolbar=20de=20l'=C3=A9diteur?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- include/editor.hpp | 4 +- include/toolbar.hpp | 54 +++++++++ include/widget_toolbar.hpp | 115 ------------------- src/editor.cpp | 47 ++++---- src/toolbar.cpp | 115 +++++++++++++++++++ src/widget_toolbar.cpp | 218 ------------------------------------- 6 files changed, 191 insertions(+), 362 deletions(-) create mode 100644 include/toolbar.hpp delete mode 100644 include/widget_toolbar.hpp create mode 100644 src/toolbar.cpp delete mode 100644 src/widget_toolbar.cpp diff --git a/include/editor.hpp b/include/editor.hpp index a3138a4..558c1d8 100644 --- a/include/editor.hpp +++ b/include/editor.hpp @@ -3,7 +3,7 @@ #include "level.hpp" #include "widget_timer.hpp" -#include "widget_toolbar.hpp" +#include "toolbar.hpp" #include #include @@ -26,7 +26,7 @@ private: DragMode drag_mode; WidgetTimer widget_timer; - WidgetToolbar widget_toolbar; + Toolbar toolbar; /** * Renvoie l'objet pointé à la position donnée diff --git a/include/toolbar.hpp b/include/toolbar.hpp new file mode 100644 index 0000000..e2ecd54 --- /dev/null +++ b/include/toolbar.hpp @@ -0,0 +1,54 @@ +#ifndef __SKIZZLE_TOOLBAR_HPP__ +#define __SKIZZLE_TOOLBAR_HPP__ + +#include +#include +#include +#include +#include +#include "object.hpp" +#include "level.hpp" + +class Editor; + +/** + * Barre d'outils pour l'éditeur + */ +class Toolbar { +private: + Editor& editor; + + // widgets de la barre + sfg::Window::Ptr toolbar_window; + sfg::ScrolledWindow::Ptr scrolled_zone; + sfg::Box::Ptr toolbar_box; + + // types d'objets de la barre d'outils + sfg::RadioButtonGroup::Ptr objects_group; + std::map> creators; + + void addCreator(sf::String label, std::function creator); + + Object::Ptr createBlock(); + Object::Ptr createMovableBlock(); + Object::Ptr createPlayer(); + Object::Ptr createSwitchBlock(); + Object::Ptr createFinishBlock(); + Object::Ptr createKillBlock(); + Object::Ptr createGravityBlock(GravityDirection direction); + +public: + Toolbar(Editor& editor); + + /** + * Crée un nouvel objet du type actuellement sélectionné + */ + Object::Ptr createObject(); + + /** + * Récupère la fenêtre de la barre d'outils + */ + sfg::Window::Ptr getWindow(); +}; + +#endif diff --git a/include/widget_toolbar.hpp b/include/widget_toolbar.hpp deleted file mode 100644 index 484022c..0000000 --- a/include/widget_toolbar.hpp +++ /dev/null @@ -1,115 +0,0 @@ -#ifndef __SKIZZLE_UTIL_WIDGET_TOOLBAR_HPP__ -#define __SKIZZLE_UTIL_WIDGET_TOOLBAR_HPP__ - -#include -#include -#include "object.hpp" -#include "level.hpp" - -class Manager; - -/** - * Représente un objet plaçable depuis la barre d'outils - */ -struct ToolbarObject { - typedef std::shared_ptr Ptr; - - // image représentant cet objet visuellement - sf::Sprite sprite; - - // fonction appelée pour instancier un objet de ce type - std::function create_object; -}; - -/** - * Représente une catégorie d'objets plaçables dans la barre - */ -struct ToolbarCategory { - typedef std::shared_ptr Ptr; - - // nom de la catégorie - sf::String name; - - // liste des objets dans la catégorie - std::vector objects; - - /** - * Ajoute un nouvel objet dans cette catégorie - */ - ToolbarObject::Ptr addObject( - sf::Texture& texture, - std::function create_object - ); -}; - -/** - * Affiche une barre d'outils pour l'éditeur - */ -class WidgetToolbar { -private: - Manager& manager; - - sf::RectangleShape background; - std::vector categories; - ToolbarObject::Ptr selected; - - /** - * Crée un objet de type Block - */ - Object::Ptr createBlock(); - - /** - * Crée un objet de type Block déplaçable - */ - Object::Ptr createMovableBlock(); - - /** - * Crée un objet de type Player - */ - Object::Ptr createPlayer(); - - /** - * Crée un objet de type SwitchBlock - */ - Object::Ptr createSwitchBlock(); - - /** - * Crée un objet de type FinishBlock - */ - Object::Ptr createFinishBlock(); - - /** - * Crée un objet de type KillBlock - */ - Object::Ptr createKillBlock(); - - /** - * Crée un objet de type GravityBlock - */ - Object::Ptr createGravityBlock(GravityDirection direction); - -public: - WidgetToolbar(Manager& manager); - - /** - * Ajoute une nouvelle catégorie de choix - */ - ToolbarCategory::Ptr addCategory(sf::String name); - - /** - * Génère un objet du type actuellement sélectionné et le retourne - */ - Object::Ptr createObject(); - - /** - * Traite l'événement et renvoie true si l'on s'en est servi - */ - bool processEvent(const sf::Event& event); - - /** - * Dessine le widget à la position donnée et avec la taille donnée - */ - void draw(sf::Vector2f position, sf::Vector2f size); -}; - -#endif diff --git a/src/editor.cpp b/src/editor.cpp index e76f7ed..1084a4d 100644 --- a/src/editor.cpp +++ b/src/editor.cpp @@ -34,7 +34,7 @@ inline sf::Vector2f roundVectorToGrid(sf::Vector2f input) { Editor::Editor(Manager& manager) : Level(manager), drag_control_point(nullptr), drag_mode(Editor::DragMode::NONE), widget_timer(manager, true, std::bind(&Editor::setTotalTime, this, std::placeholders::_1)), - widget_toolbar(manager) {} + toolbar(*this) {} Editor::~Editor() {} @@ -47,6 +47,9 @@ void Editor::enable() { // joue la musique de l'éditeur getResourceManager().playMusic("editor.ogg"); + + // ajout de la toolbar à la liste des widgets + getManager().getDesktop().Add(toolbar.getWindow()); } void Editor::processEvent(const sf::Event& event) { @@ -57,11 +60,6 @@ void Editor::processEvent(const sf::Event& event) { return; } - // traitement des événements du widget barre d'outils - if (widget_toolbar.processEvent(event)) { - return; - } - // lorsque l'on clique dans l'éditeur if (event.type == sf::Event::MouseButtonPressed) { sf::Vector2i mouse_position(event.mouseButton.x, event.mouseButton.y); @@ -327,11 +325,12 @@ void Editor::draw() { widget_timer.setTimeLeft(getTotalTime()); widget_timer.draw(sf::Vector2f(window_size.x / 2 - 50, 0)); - // barre d'outils - widget_toolbar.draw( - sf::Vector2f(window_size.x - 64, 0), - sf::Vector2f(64, window_size.y) - ); + // on redimensionne la toolbar pour qu'elle occupe l'espace droite + const sfg::Window::Ptr& toolbar_window = toolbar.getWindow(); + toolbar_window->SetAllocation(sf::FloatRect( + window_size.x - 200, 0, + 200, window_size.y + )); } Object::Ptr Editor::getObject(sf::Vector2f position) { @@ -359,33 +358,27 @@ sf::Vector2f* Editor::getControlPoint(sf::Vector2f position) { } Object::Ptr Editor::addObject(sf::Vector2f position) { - const std::vector& objects = getObjects(); - // on arrondit à l'unité de grille la plus proche position = roundVectorToGrid(position); - Object::Ptr object = widget_toolbar.createObject(); + Object::Ptr created_object = toolbar.createObject(); - if (object == nullptr) { + if (created_object == nullptr) { return nullptr; } - object->setPosition(position); + created_object->setPosition(position); // avant d'ajouter l'objet, on vérifie qu'il ne soit - // pas superposé à un autre - float overlaps = false; - - for (auto it = objects.begin(); it != objects.end(); it++) { - if ((*it)->getAABB().intersects(object->getAABB())) { - overlaps = true; + // pas superposé à un autre. Si c'est le cas, on annule + // la procédure + for (auto const &object : getObjects()) { + if (object->getAABB().intersects(created_object->getAABB())) { + return nullptr; } } - if (!overlaps) { - return Level::addObject(object); - } - - return nullptr; + // sinon, on ajoute l'objet + return Level::addObject(created_object); } void Editor::removeObject(Object::Ptr object) { diff --git a/src/toolbar.cpp b/src/toolbar.cpp new file mode 100644 index 0000000..f6a06a5 --- /dev/null +++ b/src/toolbar.cpp @@ -0,0 +1,115 @@ +#include "resource_manager.hpp" +#include "editor.hpp" +#include "toolbar.hpp" +#include "block.hpp" +#include "player.hpp" +#include "switch_block.hpp" +#include "gravity_block.hpp" +#include "kill_block.hpp" +#include "finish_block.hpp" + +Toolbar::Toolbar(Editor& editor) : editor(editor) { + // création de la boîte de la barre d'outils + toolbar_box = sfg::Box::Create(sfg::Box::Orientation::VERTICAL, 5.f); + objects_group = sfg::RadioButtonGroup::Create(); + + // catégorie des blocs de base + toolbar_box->PackEnd(sfg::Label::Create(L"BLOCS")); + addCreator(L"Bloc normal", std::bind(&Toolbar::createBlock, this)); + addCreator(L"Caisse", std::bind(&Toolbar::createMovableBlock, this)); + + // catégorie des blocs contrôlant les joueurs + toolbar_box->PackEnd(sfg::Label::Create(L"JOUEURS")); + addCreator(L"Joueur", std::bind(&Toolbar::createPlayer, this)); + addCreator(L"Bloc changeur", std::bind(&Toolbar::createSwitchBlock, this)); + addCreator(L"Bloc de fin", std::bind(&Toolbar::createFinishBlock, this)); + addCreator(L"Bloc tueur", std::bind(&Toolbar::createKillBlock, this)); + + // catégorie des blocs changeant la gravité + toolbar_box->PackEnd(sfg::Label::Create(L"GRAVITÉ")); + addCreator(L"Bloc de gravité nord", std::bind( + &Toolbar::createGravityBlock, this, GravityDirection::NORTH + )); + + addCreator(L"Bloc de gravité est", std::bind( + &Toolbar::createGravityBlock, this, GravityDirection::EAST + )); + + addCreator(L"Bloc de gravité sud", std::bind( + &Toolbar::createGravityBlock, this, GravityDirection::SOUTH + )); + + addCreator(L"Bloc de gravité ouest", std::bind( + &Toolbar::createGravityBlock, this, GravityDirection::WEST + )); + + // création de la fenêtre de la barre d'outils + scrolled_zone = sfg::ScrolledWindow::Create(); + scrolled_zone->SetScrollbarPolicy( + sfg::ScrolledWindow::ScrollbarPolicy::VERTICAL_AUTOMATIC | + sfg::ScrolledWindow::ScrollbarPolicy::HORIZONTAL_NEVER + ); + + scrolled_zone->AddWithViewport(toolbar_box); + + toolbar_window = sfg::Window::Create(sfg::Window::Style::BACKGROUND); + toolbar_window->Add(scrolled_zone); + toolbar_window->SetPosition(sf::Vector2f(0, 0)); +} + +void Toolbar::addCreator(sf::String label, std::function creator) { + sfg::RadioButton::Ptr radio = sfg::RadioButton::Create(label, objects_group); + creators[radio] = creator; + toolbar_box->PackEnd(radio); +} + +Object::Ptr Toolbar::createBlock() { + return Object::Ptr(new Block); +} + +Object::Ptr Toolbar::createMovableBlock() { + Object::Ptr movable = Object::Ptr(new Block); + movable->setMass(2.f); + return movable; +} + +Object::Ptr Toolbar::createPlayer() { + Object::Ptr player = Object::Ptr(new Player); + player->setMass(1.f); + return player; +} + +Object::Ptr Toolbar::createSwitchBlock() { + return Object::Ptr(new SwitchBlock); +} + +Object::Ptr Toolbar::createFinishBlock() { + return Object::Ptr(new FinishBlock); +} + +Object::Ptr Toolbar::createKillBlock() { + return Object::Ptr(new KillBlock); +} + +Object::Ptr Toolbar::createGravityBlock(GravityDirection direction) { + GravityBlock::Ptr gravity_block = GravityBlock::Ptr(new GravityBlock); + gravity_block->setGravityDirection(direction); + return std::dynamic_pointer_cast(gravity_block); +} + +Object::Ptr Toolbar::createObject() { + for (auto const &creator : creators) { + // on recherche le bouton actif actuellement, si on + // le trouve, on appelle le créateur associé + if (creator.first->IsActive()) { + return creator.second(); + } + } + + // on n'a aucun bouton actif, on renvoie nullptr + return nullptr; +} + +sfg::Window::Ptr Toolbar::getWindow() { + return toolbar_window; +} diff --git a/src/widget_toolbar.cpp b/src/widget_toolbar.cpp deleted file mode 100644 index f99c7c3..0000000 --- a/src/widget_toolbar.cpp +++ /dev/null @@ -1,218 +0,0 @@ -#include "manager.hpp" -#include "widget_toolbar.hpp" -#include "block.hpp" -#include "player.hpp" -#include "gravity_block.hpp" -#include "switch_block.hpp" -#include "finish_block.hpp" -#include "kill_block.hpp" -#include - - -/** - * Définition des variables et fonctions globales internes - * (accessibles uniquement dans ce fichier) - */ -namespace { - const int PADDING = 8; -} - -ToolbarCategory::Ptr WidgetToolbar::addCategory(sf::String name) { - auto cat = ToolbarCategory::Ptr(new ToolbarCategory); - - cat->name = name; - categories.push_back(cat); - return cat; -} - -ToolbarObject::Ptr ToolbarCategory::addObject( - sf::Texture& texture, - std::function create_object -) { - auto object = std::shared_ptr(new ToolbarObject); - - object->sprite.setTexture(texture, true); - object->create_object = create_object; - objects.push_back(object); - return object; -} - -Object::Ptr WidgetToolbar::createBlock() { - return Object::Ptr(new Block); -} - -Object::Ptr WidgetToolbar::createMovableBlock() { - Object::Ptr movable = Object::Ptr(new Block); - movable->setMass(2.f); - return movable; -} - -Object::Ptr WidgetToolbar::createPlayer() { - Object::Ptr player = Object::Ptr(new Player); - player->setMass(1.f); - return player; -} - -Object::Ptr WidgetToolbar::createSwitchBlock() { - return Object::Ptr(new SwitchBlock); -} - -Object::Ptr WidgetToolbar::createFinishBlock() { - return Object::Ptr(new FinishBlock); -} - -Object::Ptr WidgetToolbar::createKillBlock() { - return Object::Ptr(new KillBlock); -} - -Object::Ptr WidgetToolbar::createGravityBlock(GravityDirection direction) { - GravityBlock::Ptr gravity_block = GravityBlock::Ptr(new GravityBlock); - gravity_block->setGravityDirection(direction); - return std::dynamic_pointer_cast(gravity_block); -} - -Object::Ptr WidgetToolbar::createObject() { - if (selected != nullptr) { - return selected->create_object(); - } - - return nullptr; -} - -WidgetToolbar::WidgetToolbar(Manager& manager) : manager(manager), selected(nullptr) { - // catégorie des objets plaçables de base - ResourceManager& resources = manager.getResourceManager(); - ToolbarCategory::Ptr block_cat = addCategory("BLOCS"); - - selected = block_cat->addObject( - resources.getTexture("toolbar_block.tga"), - std::bind(&WidgetToolbar::createBlock, this) - ); - - block_cat->addObject( - resources.getTexture("toolbar_movable_block.tga"), - std::bind(&WidgetToolbar::createMovableBlock, this) - ); - - // catégorie des blocs contrôlant les joueurs - ToolbarCategory::Ptr player_cat = addCategory("JOUEURS"); - - player_cat->addObject( - resources.getTexture("toolbar_player.tga"), - std::bind(&WidgetToolbar::createPlayer, this) - ); - - player_cat->addObject( - resources.getTexture("toolbar_switch_block.tga"), - std::bind(&WidgetToolbar::createSwitchBlock, this) - ); - - player_cat->addObject( - resources.getTexture("toolbar_kill_block.tga"), - std::bind(&WidgetToolbar::createKillBlock, this) - ); - - player_cat->addObject( - resources.getTexture("toolbar_finish_block.tga"), - std::bind(&WidgetToolbar::createFinishBlock, this) - ); - - // catégorie des blocs changeant la gravité - ToolbarCategory::Ptr gravity_cat = addCategory(L"GRAVITÉ"); - - gravity_cat->addObject( - resources.getTexture("toolbar_gravity_block_north.tga"), - std::bind(&WidgetToolbar::createGravityBlock, this, GravityDirection::NORTH) - ); - - gravity_cat->addObject( - resources.getTexture("toolbar_gravity_block_east.tga"), - std::bind(&WidgetToolbar::createGravityBlock, this, GravityDirection::EAST) - ); - - gravity_cat->addObject( - resources.getTexture("toolbar_gravity_block_south.tga"), - std::bind(&WidgetToolbar::createGravityBlock, this, GravityDirection::SOUTH) - ); - - gravity_cat->addObject( - resources.getTexture("toolbar_gravity_block_west.tga"), - std::bind(&WidgetToolbar::createGravityBlock, this, GravityDirection::WEST) - ); -} - -bool WidgetToolbar::processEvent(const sf::Event& event) { - if (event.type == sf::Event::MouseButtonPressed) { - sf::Vector2f position(event.mouseButton.x, event.mouseButton.y); - - // clic gauche sur un item : on le sélectionne - if (event.mouseButton.button == sf::Mouse::Left) { - for (unsigned int i = 0; i < categories.size(); i++) { - for (unsigned int j = 0; j < categories[i]->objects.size(); j++) { - if (categories[i]->objects[j]->sprite.getGlobalBounds().contains(position)) { - selected = categories[i]->objects[j]; - return true; - } - } - } - - // ne pas laisser traverser les clics sur la barre d'outils - if (background.getGlobalBounds().contains(position)) { - return true; - } - } - } - - return false; -} - -void WidgetToolbar::draw(sf::Vector2f position, sf::Vector2f size) { - sf::RenderWindow& window = manager.getWindow(); - - background.setSize(size); - background.setPosition(position); - window.draw(background); - - float total_y = PADDING; - - for (unsigned int i = 0; i < categories.size(); i++) { - std::shared_ptr category = categories[i]; - - // affichage du label de la catégorie - sf::Text category_label( - category->name, - manager.getResourceManager().getFont("raleway.ttf"), 12 - ); - - category_label.setColor(sf::Color::Black); - category_label.setPosition(position + sf::Vector2f( - floor(size.x / 2 - category_label.getGlobalBounds().width / 2), - total_y - )); - - window.draw(category_label); - - for (unsigned int j = 0; j < category->objects.size(); j++) { - total_y += PADDING + 32; - - std::shared_ptr object = category->objects[j]; - sf::Vector2f sprite_position = position + sf::Vector2f( - size.x / 2 - object->sprite.getGlobalBounds().width / 2, - total_y - ); - - if (selected == object) { - sf::RectangleShape selection_rectangle(sf::Vector2f(32, 32)); - selection_rectangle.setPosition(sprite_position + sf::Vector2f(-4, -4)); - selection_rectangle.setFillColor(sf::Color(0, 0, 0, 20)); - window.draw(selection_rectangle); - } - - // affichage du sprite de l'objet - object->sprite.setPosition(sprite_position); - window.draw(object->sprite); - } - - total_y += 64; - } -}