#include "EditManager.h" #include "Window.h" bool EditManager::lineOk(const Line& l) const { Line l2; if(activeRoom) { for(size_t i = 0; i+2 < activeRoom->size(); i++) { l2.setVertex1(activeRoom->at(i)); l2.setVertex2(activeRoom->at(i+1)); if(l.intersects(l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) return false; } if(activeRoom->size() > 1) { l2.setVertex1(activeRoom->at(activeRoom->size()-2)); l2.setVertex2(activeRoom->back()); if(l2.contains(l.getVertex2())) return false; } } for(Level::iterator room = window->getLevel().begin(); room != window->getLevel().end(); room++) { if(room->intersects(l)) return false; } return true; } EditManager::EditManager(Window *window) { this->window = window; activeRoom = NULL; mode = VIEW; hoveredRoom = NULL; hasHoveredVertex = false; } void EditManager::addRoom() { if(mode == VIEW) { newRoom = Room(); mode = ADD; activeRoom = &newRoom; window->update(); } } void EditManager::finishRoom() { if(mode == ADD) { mode = VIEW; if(newRoom.size() > 2 && polygonOk(newRoom)) { newRoom.setName(idManager.generate("room")); window->getLevel().push_back(newRoom); activeRoom = &window->getLevel().back(); } else { activeRoom = NULL; } window->update(); } } void EditManager::addVertex(const Vertex &v) { if(mode != ADD) return; newRoom.push_back(v); window->update(); } Vertex* EditManager::getHoveredVertex() { if(hasHoveredVertex) return &hoveredVertex; else return NULL; } void EditManager::setHoveredVertex(Vertex *v) { if(v) { hasHoveredVertex = true; hoveredVertex = *v; hoveredRoom = NULL; for(Level::iterator room = window->getLevel().begin(); room != window->getLevel().end(); room++) { if(room->contains(*v)) { hoveredRoom = &*room; break; } } } else { hasHoveredVertex = false; hoveredRoom = NULL; } window->update(); } void EditManager::buttonPress(unsigned int button) { switch(button) { case 1: if(!hasHoveredVertex) break; switch(mode) { case VIEW: activeRoom = getHoveredRoom(); break; case ADD: if(vertexOk(hoveredVertex)) addVertex(hoveredVertex); } window->update(); } } bool EditManager::vertexOk(const Vertex& v) const { Line l; for(Level::iterator room = window->getLevel().begin(); room != window->getLevel().end(); room++) { if(room->contains(v)) return false; } if(!(activeRoom && !activeRoom->empty())) return true; l.setVertex1(activeRoom->back()); l.setVertex2(v); return lineOk(l); } bool EditManager::polygonOk(const Polygon& polygon) const { Line l, l2; if(polygon.empty()) return false; for(Level::iterator room = window->getLevel().begin(); room != window->getLevel().end(); room++) { if(room->empty()) continue; if(room->contains(polygon.front())) return false; if(polygon.contains(room->front())) return false; } if(polygon.size() == 1) return true; if(!polygon.isSimple()) return false; for(Polygon::const_iterator it = polygon.begin(); it != polygon.end(); it++) { Polygon::const_iterator it2 = it+1; if(it2 == polygon.end()) it2 = polygon.begin(); l.setVertex1(*it); l.setVertex2(*it2); for(Level::iterator room = window->getLevel().begin(); room != window->getLevel().end(); room++) { if(room->intersects(l)) return false; } } return true; }