| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449 |
- #include "StdInc.h"
- #include "mapview.h"
- #include "mainwindow.h"
- #include <QGraphicsSceneMouseEvent>
- #include "mapcontroller.h"
- MinimapView::MinimapView(QWidget * parent):
- QGraphicsView(parent)
- {
- // Disable scrollbars
- setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
- }
- void MinimapView::dimensions()
- {
- fitInView(0, 0, controller->map()->width, controller->map()->height, Qt::KeepAspectRatio);
- }
- void MinimapView::setController(MapController * ctrl)
- {
- controller = ctrl;
- }
- void MinimapView::mouseMoveEvent(QMouseEvent *mouseEvent)
- {
- this->update();
-
- auto * sc = static_cast<MinimapScene*>(scene());
- if(!sc)
- return;
-
- int w = sc->viewport.viewportWidth();
- int h = sc->viewport.viewportHeight();
- auto pos = mapToScene(mouseEvent->pos());
- pos.setX(pos.x() - w / 2);
- pos.setY(pos.y() - h / 2);
-
- QPointF point = pos * 32;
-
- emit cameraPositionChanged(point);
- }
- void MinimapView::mousePressEvent(QMouseEvent* event)
- {
- mouseMoveEvent(event);
- }
- MapView::MapView(QWidget * parent):
- QGraphicsView(parent),
- selectionTool(MapView::SelectionTool::None)
- {
- }
- void MapView::cameraChanged(const QPointF & pos)
- {
- //ui->mapView->translate(pos.x(), pos.y());
- horizontalScrollBar()->setValue(pos.x());
- verticalScrollBar()->setValue(pos.y());
- }
- void MapView::setController(MapController * ctrl)
- {
- controller = ctrl;
- }
- void MapView::mouseMoveEvent(QMouseEvent *mouseEvent)
- {
- this->update();
- auto * sc = static_cast<MapScene*>(scene());
- if(!sc || !controller->map())
- return;
- auto pos = mapToScene(mouseEvent->pos()); //TODO: do we need to check size?
- int3 tile(pos.x() / 32, pos.y() / 32, sc->level);
- if(tile == tilePrev) //do not redraw
- return;
- tilePrev = tile;
- //TODO: cast parent->parent to MainWindow in order to show coordinates or another way to do it?
- //main->setStatusMessage(QString("x: %1 y: %2").arg(tile.x, tile.y));
- switch(selectionTool)
- {
- case MapView::SelectionTool::Brush:
- if(mouseEvent->buttons() & Qt::RightButton)
- sc->selectionTerrainView.erase(tile);
- else if(mouseEvent->buttons() == Qt::LeftButton)
- sc->selectionTerrainView.select(tile);
- sc->selectionTerrainView.draw();
- break;
- case MapView::SelectionTool::Brush2:
- {
- std::array<int3, 4> extra{ int3{0, 0, 0}, int3{1, 0, 0}, int3{0, 1, 0}, int3{1, 1, 0} };
- for(auto & e : extra)
- {
- if(mouseEvent->buttons() & Qt::RightButton)
- sc->selectionTerrainView.erase(tile + e);
- else if(mouseEvent->buttons() == Qt::LeftButton)
- sc->selectionTerrainView.select(tile + e);
- }
- }
- sc->selectionTerrainView.draw();
- break;
- case MapView::SelectionTool::Brush4:
- {
- std::array<int3, 16> extra{
- int3{-1, -1, 0}, int3{0, -1, 0}, int3{1, -1, 0}, int3{2, -1, 0},
- int3{-1, 0, 0}, int3{0, 0, 0}, int3{1, 0, 0}, int3{2, 0, 0},
- int3{-1, 1, 0}, int3{0, 1, 0}, int3{1, 1, 0}, int3{2, 1, 0},
- int3{-1, 2, 0}, int3{0, 2, 0}, int3{1, 2, 0}, int3{2, 2, 0}
- };
- for(auto & e : extra)
- {
- if(mouseEvent->buttons() & Qt::RightButton)
- sc->selectionTerrainView.erase(tile + e);
- else if(mouseEvent->buttons() == Qt::LeftButton)
- sc->selectionTerrainView.select(tile + e);
- }
- }
- sc->selectionTerrainView.draw();
- break;
- case MapView::SelectionTool::Area:
- if(mouseEvent->buttons() & Qt::RightButton || !(mouseEvent->buttons() & Qt::LeftButton))
- break;
- sc->selectionTerrainView.clear();
- for(int j = std::min(tile.y, tileStart.y); j < std::max(tile.y, tileStart.y); ++j)
- {
- for(int i = std::min(tile.x, tileStart.x); i < std::max(tile.x, tileStart.x); ++i)
- {
- sc->selectionTerrainView.select(int3(i, j, sc->level));
- }
- }
- sc->selectionTerrainView.draw();
- break;
- case MapView::SelectionTool::None:
- if(mouseEvent->buttons() & Qt::RightButton)
- break;
- auto sh = tile - tileStart;
- sc->selectionObjectsView.shift = QPoint(sh.x, sh.y);
- if(sh.x || sh.y)
- {
- if(sc->selectionObjectsView.newObject)
- {
- sc->selectionObjectsView.shift = QPoint(tile.x, tile.y);
- sc->selectionObjectsView.selectObject(sc->selectionObjectsView.newObject);
- sc->selectionObjectsView.selectionMode = 2;
- }
- else if(mouseEvent->buttons() & Qt::LeftButton)
- {
- if(sc->selectionObjectsView.selectionMode == 1)
- {
- sc->selectionObjectsView.clear();
- sc->selectionObjectsView.selectObjects(tileStart.x, tileStart.y, tile.x, tile.y);
- }
- }
- }
- sc->selectionObjectsView.draw();
- break;
- }
- }
- void MapView::mousePressEvent(QMouseEvent *event)
- {
- this->update();
- auto * sc = static_cast<MapScene*>(scene());
- if(!sc || !controller->map())
- return;
- mouseStart = mapToScene(event->pos());
- tileStart = tilePrev = int3(mouseStart.x() / 32, mouseStart.y() / 32, sc->level);
- if(sc->selectionTerrainView.selection().count(tileStart))
- pressedOnSelected = true;
- else
- pressedOnSelected = false;
- switch(selectionTool)
- {
- case MapView::SelectionTool::Brush:
- sc->selectionObjectsView.clear();
- sc->selectionObjectsView.draw();
- if(event->button() == Qt::RightButton)
- sc->selectionTerrainView.erase(tileStart);
- else if(event->button() == Qt::LeftButton)
- sc->selectionTerrainView.select(tileStart);
- sc->selectionTerrainView.draw();
- break;
- case MapView::SelectionTool::Brush2:
- sc->selectionObjectsView.clear();
- sc->selectionObjectsView.draw();
- {
- std::array<int3, 4> extra{ int3{0, 0, 0}, int3{1, 0, 0}, int3{0, 1, 0}, int3{1, 1, 0} };
- for(auto & e : extra)
- {
- if(event->button() == Qt::RightButton)
- sc->selectionTerrainView.erase(tileStart + e);
- else if(event->button() == Qt::LeftButton)
- sc->selectionTerrainView.select(tileStart + e);
- }
- }
- sc->selectionTerrainView.draw();
- break;
- case MapView::SelectionTool::Brush4:
- sc->selectionObjectsView.clear();
- sc->selectionObjectsView.draw();
- {
- std::array<int3, 16> extra{
- int3{-1, -1, 0}, int3{0, -1, 0}, int3{1, -1, 0}, int3{2, -1, 0},
- int3{-1, 0, 0}, int3{0, 0, 0}, int3{1, 0, 0}, int3{2, 0, 0},
- int3{-1, 1, 0}, int3{0, 1, 0}, int3{1, 1, 0}, int3{2, 1, 0},
- int3{-1, 2, 0}, int3{0, 2, 0}, int3{1, 2, 0}, int3{2, 2, 0}
- };
- for(auto & e : extra)
- {
- if(event->button() == Qt::RightButton)
- sc->selectionTerrainView.erase(tileStart + e);
- else if(event->button() == Qt::LeftButton)
- sc->selectionTerrainView.select(tileStart + e);
- }
- }
- sc->selectionTerrainView.draw();
- break;
- case MapView::SelectionTool::Area:
- if(event->button() == Qt::RightButton)
- break;
- sc->selectionTerrainView.clear();
- sc->selectionTerrainView.draw();
- sc->selectionObjectsView.clear();
- sc->selectionObjectsView.draw();
- break;
- case MapView::SelectionTool::None:
- sc->selectionTerrainView.clear();
- sc->selectionTerrainView.draw();
- if(sc->selectionObjectsView.newObject && sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject))
- {
- if(event->button() == Qt::RightButton)
- controller->discardObject(sc->level);
- }
- else
- {
- if(event->button() == Qt::LeftButton)
- {
- auto * obj = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y);
- if(obj)
- {
- if(sc->selectionObjectsView.isSelected(obj))
- {
- if(qApp->keyboardModifiers() & Qt::ControlModifier)
- {
- sc->selectionObjectsView.deselectObject(obj);
- sc->selectionObjectsView.selectionMode = 1;
- }
- else
- sc->selectionObjectsView.selectionMode = 2;
- }
- else
- {
- if(!(qApp->keyboardModifiers() & Qt::ControlModifier))
- sc->selectionObjectsView.clear();
- sc->selectionObjectsView.selectionMode = 2;
- sc->selectionObjectsView.selectObject(obj);
- }
- }
- else
- {
- sc->selectionObjectsView.clear();
- sc->selectionObjectsView.selectionMode = 1;
- }
- }
- sc->selectionObjectsView.shift = QPoint(0, 0);
- sc->selectionObjectsView.draw();
- }
- break;
- }
- //main->setStatusMessage(QString("x: %1 y: %2").arg(QString::number(event->pos().x()), QString::number(event->pos().y())));
- }
- void MapView::mouseReleaseEvent(QMouseEvent *event)
- {
- this->update();
- auto * sc = static_cast<MapScene*>(scene());
- if(!sc || !controller->map())
- return;
- switch(selectionTool)
- {
- case MapView::SelectionTool::None:
- if(event->button() == Qt::RightButton)
- break;
- //switch position
- bool tab = false;
- if(sc->selectionObjectsView.selectionMode == 2)
- {
- if(sc->selectionObjectsView.newObject)
- {
- QString errorMsg;
- if(controller->canPlaceObject(sc->level, sc->selectionObjectsView.newObject, errorMsg))
- controller->commitObjectCreate(sc->level);
- else
- {
- QMessageBox::information(this, "Can't place object", errorMsg);
- break;
- }
- }
- else
- controller->commitObjectShift(sc->level);
- }
- else
- {
- sc->selectionObjectsView.selectionMode = 0;
- sc->selectionObjectsView.shift = QPoint(0, 0);
- sc->selectionObjectsView.draw();
- tab = true;
- //check if we have only one object
- }
- auto selection = sc->selectionObjectsView.getSelection();
- if(selection.size() == 1)
- {
- emit openObjectProperties(*selection.begin(), tab);
- }
- break;
- }
- }
- bool MapView::viewportEvent(QEvent *event)
- {
- if(auto * sc = static_cast<MapScene*>(scene()))
- {
- //auto rect = sceneRect();
- auto rect = mapToScene(viewport()->geometry()).boundingRect();
- controller->miniScene(sc->level)->viewport.setViewport(rect.x() / 32, rect.y() / 32, rect.width() / 32, rect.height() / 32);
- }
- return QGraphicsView::viewportEvent(event);
- }
- MapSceneBase::MapSceneBase(int lvl):
- QGraphicsScene(nullptr),
- level(lvl)
- {
- }
- void MapSceneBase::initialize(MapController & controller)
- {
- for(auto * layer : getAbstractLayers())
- layer->initialize(controller);
- }
- void MapSceneBase::updateViews()
- {
- for(auto * layer : getAbstractLayers())
- layer->update();
- }
- MapScene::MapScene(int lvl):
- MapSceneBase(lvl),
- gridView(this),
- passabilityView(this),
- selectionTerrainView(this),
- terrainView(this),
- objectsView(this),
- selectionObjectsView(this),
- isTerrainSelected(false),
- isObjectSelected(false)
- {
- connect(&selectionTerrainView, &SelectionTerrainLayer::selectionMade, this, &MapScene::terrainSelected);
- connect(&selectionObjectsView, &SelectionObjectsLayer::selectionMade, this, &MapScene::objectSelected);
- }
- std::list<AbstractLayer *> MapScene::getAbstractLayers()
- {
- //sequence is important because it defines rendering order
- return {
- &terrainView,
- &objectsView,
- &gridView,
- &passabilityView,
- &selectionTerrainView,
- &selectionObjectsView
- };
- }
- void MapScene::updateViews()
- {
- MapSceneBase::updateViews();
- terrainView.show(true);
- objectsView.show(true);
- selectionTerrainView.show(true);
- selectionObjectsView.show(true);
- }
- void MapScene::terrainSelected(bool anythingSelected)
- {
- isTerrainSelected = anythingSelected;
- emit selected(isTerrainSelected || isObjectSelected);
- }
- void MapScene::objectSelected(bool anythingSelected)
- {
- isObjectSelected = anythingSelected;
- emit selected(isTerrainSelected || isObjectSelected);
- }
- MinimapScene::MinimapScene(int lvl):
- MapSceneBase(lvl),
- minimapView(this),
- viewport(this)
- {
- }
- std::list<AbstractLayer *> MinimapScene::getAbstractLayers()
- {
- //sequence is important because it defines rendering order
- return {
- &minimapView,
- &viewport
- };
- }
- void MinimapScene::updateViews()
- {
- MapSceneBase::updateViews();
-
- minimapView.show(true);
- viewport.show(true);
- }
|