Ajout de l'interaction sélection rectangulaire dans éditeur

This commit is contained in:
Mattéo Delabre 2016-04-07 22:01:07 +02:00
parent 603c2fff65
commit b4b8aaedac
2 changed files with 146 additions and 99 deletions

View File

@ -38,8 +38,8 @@ private:
void removeObject(sf::Vector2f position); void removeObject(sf::Vector2f position);
/** /**
* Ajoute l'objet donné (par position ou par pointeur) * Ajoute l'objet/les objets donné(s) (par position, entre deux
* à la sélection * positions ou par pointeur) à la sélection
* *
* - REPLACE : remplace toute sélection précédente * - REPLACE : remplace toute sélection précédente
* - FLIP : sélectionne l'élément s'il ne l'est pas, sinon le désélectionne * - FLIP : sélectionne l'élément s'il ne l'est pas, sinon le désélectionne
@ -47,11 +47,17 @@ private:
*/ */
void select(ObjectPtr object, SelectionMode mode); void select(ObjectPtr object, SelectionMode mode);
void select(sf::Vector2f position, SelectionMode mode); void select(sf::Vector2f position, SelectionMode mode);
void select(sf::Vector2f top_left, sf::Vector2f bottom_right);
/** /**
* Lance le test du niveau * Lance le test du niveau
*/ */
void testLevel(); void test();
/**
* Traite l'événement et renvoie true si on s'en est servi
*/
bool processEvent(const sf::Event& event);
protected: protected:
/** /**

View File

@ -23,101 +23,7 @@ void Editor::frame() {
// traitement des événements // traitement des événements
for (unsigned int i = 0; i < events.size(); i++) { for (unsigned int i = 0; i < events.size(); i++) {
const sf::Event& event = events[i]; processEvent(events[i]);
// traitement des événements du widget timer
if (widget_timer.processEvent(event)) {
continue;
}
// lorsque l'on clique dans l'éditeur
if (event.type == sf::Event::MouseButtonPressed) {
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
ObjectPtr pointed_object = getObject(position);
if (event.mouseButton.button == sf::Mouse::Left) {
// clic + shift : sélection par rectangle de sélection
if (manager.isKeyPressed(sf::Keyboard::LShift)) {
drag_start = position;
drag_end = position;
drag_mode = DragMode::SELECT_RECT;
continue;
}
// clic sur un objet : démarrage de la sélection libre
if (pointed_object != nullptr) {
if (manager.isKeyPressed(sf::Keyboard::LControl)) {
drag_start = position;
drag_end = position;
drag_mode = DragMode::SELECT_BULK;
select(pointed_object, SelectionMode::ADD);
} else {
select(pointed_object, SelectionMode::FLIP);
}
}
// clic gauche dans le vide : démarrage du placement
// en drag&ndrop
else {
drag_start = position;
drag_end = position;
drag_mode = DragMode::PLACE_OBJECTS;
select(addObject(position), SelectionMode::REPLACE);
}
} else if (event.mouseButton.button == sf::Mouse::Right) {
// clic droit : on supprime l'objet pointé
removeObject(pointed_object);
}
}
// lorsqu'on déplace la souris
if (event.type == sf::Event::MouseMoved) {
sf::Vector2f position(event.mouseMove.x, event.mouseMove.y);
ObjectPtr pointed_object = getObject(position);
drag_end = position;
// mode placement d'objets
if (drag_mode == DragMode::PLACE_OBJECTS && pointed_object == nullptr) {
select(addObject(position), SelectionMode::ADD);
}
// mode sélection libre : on l'objet à la sélection
if (drag_mode == DragMode::SELECT_BULK) {
select(position, SelectionMode::ADD);
}
}
// lorsqu'on relâche un clic dans l'éditeur
if (event.type == sf::Event::MouseButtonReleased) {
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
drag_mode = DragMode::NONE;
}
// gestion des touches
if (event.type == sf::Event::KeyPressed) {
// appui sur suppr : suppression des blocs sélectionnés
if (event.key.code == sf::Keyboard::Delete) {
std::vector<ObjectPtr>& objects = getObjects();
for (unsigned int i = 0; i < selection.size(); i++) {
objects.erase(std::remove(
objects.begin(), objects.end(), selection[i]
), objects.end());
}
selection.clear();
}
// appui sur espace : test du niveau en cours d'édition
if (event.key.code == sf::Keyboard::Space) {
testLevel();
return; // important : ne pas dessiner la frame
// on risque d'avoir perdu le pointeur en changeant de vue
}
}
} }
// dessin de la frame // dessin de la frame
@ -125,6 +31,117 @@ void Editor::frame() {
sf::sleep(sf::seconds(1.f / 30)); sf::sleep(sf::seconds(1.f / 30));
} }
bool Editor::processEvent(const sf::Event& event) {
// traitement des événements du widget timer
if (widget_timer.processEvent(event)) {
return true;
}
// lorsque l'on clique dans l'éditeur
if (event.type == sf::Event::MouseButtonPressed) {
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
ObjectPtr pointed_object = getObject(position);
if (event.mouseButton.button == sf::Mouse::Left) {
// clic + shift : sélection par rectangle de sélection
if (manager.isKeyPressed(sf::Keyboard::LShift)) {
drag_start = position;
drag_end = position;
drag_mode = DragMode::SELECT_RECT;
return true;
}
// clic sur un objet : démarrage de la sélection libre
if (pointed_object != nullptr) {
if (manager.isKeyPressed(sf::Keyboard::LControl)) {
drag_start = position;
drag_end = position;
drag_mode = DragMode::SELECT_BULK;
select(pointed_object, SelectionMode::ADD);
} else {
select(pointed_object, SelectionMode::FLIP);
}
return true;
}
// clic gauche dans le vide : démarrage du placement
// en drag&ndrop
drag_start = position;
drag_end = position;
drag_mode = DragMode::PLACE_OBJECTS;
select(addObject(position), SelectionMode::REPLACE);
return true;
}
if (event.mouseButton.button == sf::Mouse::Right) {
// clic droit : on supprime l'objet pointé
removeObject(pointed_object);
return true;
}
}
// lorsqu'on déplace la souris
if (event.type == sf::Event::MouseMoved) {
sf::Vector2f position(event.mouseMove.x, event.mouseMove.y);
ObjectPtr pointed_object = getObject(position);
drag_end = position;
// mode placement d'objets
if (drag_mode == DragMode::PLACE_OBJECTS && pointed_object == nullptr) {
select(addObject(position), SelectionMode::ADD);
return true;
}
// mode sélection libre : on l'objet à la sélection
if (drag_mode == DragMode::SELECT_BULK) {
select(position, SelectionMode::ADD);
return true;
}
}
// lorsqu'on relâche un clic dans l'éditeur
if (event.type == sf::Event::MouseButtonReleased) {
sf::Vector2f position(event.mouseButton.x, event.mouseButton.y);
// mode sélection rectangulaire : on applique la sélection
if (drag_mode == DragMode::SELECT_RECT) {
select(drag_start, drag_end);
}
drag_mode = DragMode::NONE;
return true;
}
// gestion des touches
if (event.type == sf::Event::KeyPressed) {
// appui sur suppr : suppression des blocs sélectionnés
if (event.key.code == sf::Keyboard::Delete) {
std::vector<ObjectPtr>& objects = getObjects();
for (unsigned int i = 0; i < selection.size(); i++) {
objects.erase(std::remove(
objects.begin(), objects.end(), selection[i]
), objects.end());
}
selection.clear();
return true;
}
// appui sur espace : test du niveau en cours d'édition
if (event.key.code == sf::Keyboard::Space) {
test();
return true;
}
}
return false;
}
void Editor::draw() { void Editor::draw() {
Level::draw(); Level::draw();
@ -254,7 +271,31 @@ void Editor::select(sf::Vector2f position, SelectionMode mode) {
select(getObject(position), mode); select(getObject(position), mode);
} }
void Editor::testLevel() { void Editor::select(sf::Vector2f top_left, sf::Vector2f bottom_right) {
std::vector<ObjectPtr>& objects = getObjects();
sf::FloatRect selection_rect(
std::min(top_left.x, bottom_right.x),
std::min(top_left.y, bottom_right.y),
std::abs(bottom_right.x - top_left.x),
std::abs(bottom_right.y - top_left.y)
);
// réinitialisation de la sélectionne
for (unsigned int i = 0; i < selection.size(); i++) {
selection[i]->setSelected(false);
}
selection.clear();
// sélection des éléments intersectant le rectangle
for (unsigned int i = 0; i < objects.size(); i++) {
if (objects[i]->getAABB()->intersects(selection_rect)) {
select(objects[i], SelectionMode::ADD);
}
}
}
void Editor::test() {
std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(manager)); std::shared_ptr<Game> game = std::shared_ptr<Game>(new Game(manager));
// copie des propriétés // copie des propriétés