diff --git a/mapeditor/mainwindow.cpp b/mapeditor/mainwindow.cpp index 25250c188..4969075a6 100644 --- a/mapeditor/mainwindow.cpp +++ b/mapeditor/mainwindow.cpp @@ -120,8 +120,8 @@ MainWindow::MainWindow(QWidget *parent) : ui->mapView->setController(&controller); connect(ui->mapView, &MapView::openObjectProperties, this, &MainWindow::loadInspector); - sceneMini = new QGraphicsScene(this); - ui->minimapView->setScene(sceneMini); + ui->minimapView->setScene(controller.miniScene(0)); + ui->minimapView->setController(&controller); scenePreview = new QGraphicsScene(this); ui->objectPreview->setScene(scenePreview); @@ -176,6 +176,8 @@ void MainWindow::initializeMap(bool isNew) mapLevel = 0; ui->mapView->setScene(controller.scene(mapLevel)); + ui->minimapView->setScene(controller.miniScene(mapLevel)); + ui->minimapView->dimensions(); setStatusMessage(QString("Scene objects: %1").arg(ui->mapView->scene()->items().size())); @@ -551,6 +553,7 @@ void MainWindow::on_actionLevel_triggered() { mapLevel = mapLevel ? 0 : 1; ui->mapView->setScene(controller.scene(mapLevel)); + ui->minimapView->setScene(controller.miniScene(mapLevel)); } } diff --git a/mapeditor/mainwindow.h b/mapeditor/mainwindow.h index 242719702..fa2a13190 100644 --- a/mapeditor/mainwindow.h +++ b/mapeditor/mainwindow.h @@ -95,9 +95,7 @@ private: private: Ui::MainWindow *ui; ObjectBrowser * objectBrowser = nullptr; - QGraphicsScene * sceneMini; QGraphicsScene * scenePreview; - QPixmap minimap; QString filename; bool unsaved = false; diff --git a/mapeditor/mainwindow.ui b/mapeditor/mainwindow.ui index db084e180..62281b603 100644 --- a/mapeditor/mainwindow.ui +++ b/mapeditor/mainwindow.ui @@ -140,7 +140,7 @@ 0 - + 0 @@ -830,6 +830,11 @@ QGraphicsView
mapview.h
+ + MinimapView + QGraphicsView +
mapview.h
+
diff --git a/mapeditor/mapcontroller.cpp b/mapeditor/mapcontroller.cpp index afcb768fd..7bc20e59f 100644 --- a/mapeditor/mapcontroller.cpp +++ b/mapeditor/mapcontroller.cpp @@ -18,6 +18,8 @@ MapController::MapController(MainWindow * m): main(m) { _scenes[0].reset(new MapScene(0)); _scenes[1].reset(new MapScene(1)); + _miniscenes[0].reset(new MinimapScene(0)); + _miniscenes[1].reset(new MinimapScene(1)); } MapController::~MapController() @@ -39,11 +41,18 @@ MapScene * MapController::scene(int level) return _scenes[level].get(); } +MinimapScene * MapController::miniScene(int level) +{ + return _miniscenes[level].get(); +} + void MapController::setMap(std::unique_ptr cmap) { _map = std::move(cmap); _scenes[0].reset(new MapScene(0)); _scenes[1].reset(new MapScene(1)); + _miniscenes[0].reset(new MinimapScene(0)); + _miniscenes[1].reset(new MinimapScene(1)); resetMapHandler(); sceneForceUpdate(); } @@ -51,13 +60,18 @@ void MapController::setMap(std::unique_ptr cmap) void MapController::sceneForceUpdate() { _scenes[0]->updateViews(); + _miniscenes[0]->updateViews(); if(_map->twoLevel) + { _scenes[1]->updateViews(); + _miniscenes[1]->updateViews(); + } } void MapController::sceneForceUpdate(int level) { _scenes[level]->updateViews(); + _miniscenes[level]->updateViews(); } void MapController::resetMapHandler() @@ -65,6 +79,8 @@ void MapController::resetMapHandler() _mapHandler.reset(new MapHandler(_map.get())); _scenes[0]->initialize(*this); _scenes[1]->initialize(*this); + _miniscenes[0]->initialize(*this); + _miniscenes[1]->initialize(*this); } void MapController::commitTerrainChange(int level, const Terrain & terrain) @@ -84,6 +100,7 @@ void MapController::commitTerrainChange(int level, const Terrain & terrain) _scenes[level]->terrainView.setDirty(t); _scenes[level]->terrainView.draw(); + _miniscenes[level]->updateViews(); main->mapChanged(); } @@ -98,6 +115,7 @@ void MapController::commitObjectErase(int level) resetMapHandler(); _scenes[level]->updateViews(); + _miniscenes[level]->updateViews(); main->mapChanged(); } @@ -149,6 +167,7 @@ void MapController::commitObstacleFill(int level) resetMapHandler(); _scenes[level]->updateViews(); + _miniscenes[level]->updateViews(); main->mapChanged(); } @@ -158,6 +177,7 @@ void MapController::commitObjectChange(int level) _scenes[level]->objectsView.draw(); _scenes[level]->selectionObjectsView.draw(); + _miniscenes[level]->updateViews(); main->mapChanged(); } @@ -198,6 +218,7 @@ void MapController::commitObjectShiftOrCreate(int level) resetMapHandler(); _scenes[level]->updateViews(); + _miniscenes[level]->updateViews(); main->mapChanged(); } diff --git a/mapeditor/mapcontroller.h b/mapeditor/mapcontroller.h index a89b6b377..3f4cd6c70 100644 --- a/mapeditor/mapcontroller.h +++ b/mapeditor/mapcontroller.h @@ -20,6 +20,7 @@ public: CMap * map(); MapHandler * mapHandler(); MapScene * scene(int level); + MinimapScene * miniScene(int level); void resetMapHandler(); @@ -42,6 +43,7 @@ private: std::unique_ptr _mapHandler; MainWindow * main; mutable std::array, 2> _scenes; + mutable std::array, 2> _miniscenes; }; #endif // MAPCONTROLLER_H diff --git a/mapeditor/maphandler.cpp b/mapeditor/maphandler.cpp index 3fdee15e6..1903b29db 100644 --- a/mapeditor/maphandler.cpp +++ b/mapeditor/maphandler.cpp @@ -502,3 +502,39 @@ void MapHandler::drawObjectAt(QPainter & painter, const CGObjectInstance * obj, } } } + +QRgb MapHandler::getTileColor(int x, int y, int z) +{ + // if object at tile is owned - it will be colored as its owner + for(auto & object : getObjects(x, y, z)) + { + //heroes will be blitted later + switch (object.obj->ID) + { + case Obj::HERO: + case Obj::PRISON: + continue; + } + + PlayerColor player = object.obj->getOwner(); + if(player == PlayerColor::NEUTRAL) + return graphics->neutralColor; + else + if (player < PlayerColor::PLAYER_LIMIT) + return graphics->playerColors[player.getNum()]; + } + + // else - use terrain color (blocked version or normal) + auto & tile = map->getTile(int3(x, y, z)); + auto color = Terrain::Manager::getInfo(tile.terType).minimapUnblocked; + if (tile.blocked && (!tile.visitable)) + color = Terrain::Manager::getInfo(tile.terType).minimapBlocked; + + return qRgb(color[0], color[1], color[2]); +} + +void MapHandler::drawMinimapTile(QPainter & painter, int x, int y, int z) +{ + painter.setPen(getTileColor(x, y, z)); + painter.drawPoint(x, y); +} diff --git a/mapeditor/maphandler.h b/mapeditor/maphandler.h index 52485f9ed..521abbff0 100644 --- a/mapeditor/maphandler.h +++ b/mapeditor/maphandler.h @@ -98,7 +98,9 @@ public: std::vector & getObjects(int x, int y, int z); //void drawObject(SDL_Surface * targetSurf, std::shared_ptr source, SDL_Rect * sourceRect, bool moving) const; //void drawHeroFlag(SDL_Surface * targetSurf, std::shared_ptr source, SDL_Rect * sourceRect, SDL_Rect * destRect, bool moving) const; - + QRgb getTileColor(int x, int y, int z); + void drawMinimapTile(QPainter & painter, int x, int y, int z); + mutable std::map animationPhase; MapHandler(const CMap * Map); diff --git a/mapeditor/mapview.cpp b/mapeditor/mapview.cpp index 7ad993760..3a64e0dc0 100644 --- a/mapeditor/mapview.cpp +++ b/mapeditor/mapview.cpp @@ -4,6 +4,37 @@ #include #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::mousePressEvent(QMouseEvent *event) +{ + this->update(); + + auto * sc = static_cast(scene()); + if(!sc) + return; +} + +void MinimapView::cameraPositionChange(const QPoint & newPosition) +{ +} + MapView::MapView(QWidget * parent): QGraphicsView(parent), selectionTool(MapView::SelectionTool::None) @@ -273,15 +304,32 @@ void MapView::mouseReleaseEvent(QMouseEvent *event) } } -MapScene::MapScene(int lev): +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), - level(lev) + selectionObjectsView(this) { } @@ -298,19 +346,33 @@ std::list MapScene::getAbstractLayers() }; } -void MapScene::initialize(MapController & controller) -{ - for(auto * layer : getAbstractLayers()) - layer->initialize(controller); -} - void MapScene::updateViews() { - for(auto * layer : getAbstractLayers()) - layer->update(); + MapSceneBase::updateViews(); terrainView.show(true); objectsView.show(true); selectionTerrainView.show(true); selectionObjectsView.show(true); } + +MinimapScene::MinimapScene(int lvl): + MapSceneBase(lvl), + minimapView(this) +{ +} + +std::list MinimapScene::getAbstractLayers() +{ + //sequence is important because it defines rendering order + return { + &minimapView + }; +} + +void MinimapScene::updateViews() +{ + MapSceneBase::updateViews(); + + minimapView.show(true); +} diff --git a/mapeditor/mapview.h b/mapeditor/mapview.h index 77b79b052..288f28bbd 100644 --- a/mapeditor/mapview.h +++ b/mapeditor/mapview.h @@ -11,13 +11,39 @@ class CGObjectInstance; class MainWindow; class MapController; -class MapScene : public QGraphicsScene +class MapSceneBase : public QGraphicsScene { public: - MapScene(int lev); + MapSceneBase(int lvl); - void updateViews(); - void initialize(MapController &); + const int level; + + virtual void updateViews(); + virtual void initialize(MapController &); + +protected: + virtual std::list getAbstractLayers() = 0; +}; + +class MinimapScene : public MapSceneBase +{ +public: + MinimapScene(int lvl); + + void updateViews() override; + + MinimapLayer minimapView; + +protected: + virtual std::list getAbstractLayers(); +}; + +class MapScene : public MapSceneBase +{ +public: + MapScene(int lvl); + + void updateViews() override; GridLayer gridView; PassabilityLayer passabilityView; @@ -26,10 +52,8 @@ public: ObjectsLayer objectsView; SelectionObjectsLayer selectionObjectsView; - const int level; - -private: - std::list getAbstractLayers(); +protected: + std::list getAbstractLayers() override; }; class MapView : public QGraphicsView @@ -63,4 +87,27 @@ private: bool pressedOnSelected; }; +class MinimapView : public QGraphicsView +{ + Q_OBJECT +public: + MinimapView(QWidget * parent); + void setController(MapController *); + + void dimensions(); + +public slots: + void mousePressEvent(QMouseEvent *event) override; + void cameraPositionChange(const QPoint & newPosition); + +signals: + void cameraPositionChanged(const QPoint & newPosition); + +private: + MapController * controller = nullptr; + + int displayWidth = 192; + int displayHeight = 192; +}; + #endif // MAPVIEW_H diff --git a/mapeditor/scenelayer.cpp b/mapeditor/scenelayer.cpp index 315f1e4d2..496e8c49c 100644 --- a/mapeditor/scenelayer.cpp +++ b/mapeditor/scenelayer.cpp @@ -6,7 +6,7 @@ #include "mapview.h" #include "mapcontroller.h" -AbstractLayer::AbstractLayer(MapScene * s): scene(s) +AbstractLayer::AbstractLayer(MapSceneBase * s): scene(s) { } @@ -21,29 +21,9 @@ void AbstractLayer::show(bool show) if(isShown == show) return; - if(show) - { - if(pixmap) - { - if(item) - item->setPixmap(*pixmap); - else - item.reset(scene->addPixmap(*pixmap)); - } - else - { - if(item) - item->setPixmap(emptyPixmap); - else - item.reset(scene->addPixmap(emptyPixmap)); - } - } - else - { - item->setPixmap(emptyPixmap); - } - isShown = show; + + redraw(); } void AbstractLayer::redraw() @@ -64,7 +44,7 @@ void AbstractLayer::redraw() } } -GridLayer::GridLayer(MapScene * s): AbstractLayer(s) +GridLayer::GridLayer(MapSceneBase * s): AbstractLayer(s) { } @@ -90,7 +70,7 @@ void GridLayer::update() redraw(); } -PassabilityLayer::PassabilityLayer(MapScene * s): AbstractLayer(s) +PassabilityLayer::PassabilityLayer(MapSceneBase * s): AbstractLayer(s) { } @@ -121,7 +101,7 @@ void PassabilityLayer::update() redraw(); } -SelectionTerrainLayer::SelectionTerrainLayer(MapScene * s): AbstractLayer(s) +SelectionTerrainLayer::SelectionTerrainLayer(MapSceneBase * s): AbstractLayer(s) { } @@ -200,7 +180,7 @@ const std::set & SelectionTerrainLayer::selection() const return area; } -TerrainLayer::TerrainLayer(MapScene * s): AbstractLayer(s) +TerrainLayer::TerrainLayer(MapSceneBase * s): AbstractLayer(s) { } @@ -275,7 +255,7 @@ void TerrainLayer::draw(bool onlyDirty) redraw(); } -ObjectsLayer::ObjectsLayer(MapScene * s): AbstractLayer(s) +ObjectsLayer::ObjectsLayer(MapSceneBase * s): AbstractLayer(s) { } @@ -342,7 +322,7 @@ void ObjectsLayer::setDirty(const CGObjectInstance * object) dirty.insert(object); } -SelectionObjectsLayer::SelectionObjectsLayer(MapScene * s): AbstractLayer(s), newObject(nullptr) +SelectionObjectsLayer::SelectionObjectsLayer(MapSceneBase * s): AbstractLayer(s), newObject(nullptr) { } @@ -491,3 +471,28 @@ void SelectionObjectsLayer::clear() shift.setX(0); shift.setY(0); } + +MinimapLayer::MinimapLayer(MapSceneBase * s): AbstractLayer(s) +{ + +} + +void MinimapLayer::update() +{ + if(!map) + return; + + pixmap.reset(new QPixmap(map->width, map->height)); + + QPainter painter(pixmap.get()); + //coordinate transfomation + for(int j = 0; j < map->height; ++j) + { + for(int i = 0; i < map->width; ++i) + { + handler->drawMinimapTile(painter, i, j, scene->level); + } + } + + redraw(); +} diff --git a/mapeditor/scenelayer.h b/mapeditor/scenelayer.h index b4c239662..17b9a5ba5 100644 --- a/mapeditor/scenelayer.h +++ b/mapeditor/scenelayer.h @@ -3,7 +3,7 @@ #include "../lib/int3.h" -class MapScene; +class MapSceneBase; class CGObjectInstance; class MapController; class CMap; @@ -12,7 +12,7 @@ class MapHandler; class AbstractLayer { public: - AbstractLayer(MapScene * s); + AbstractLayer(MapSceneBase * s); virtual void update() = 0; @@ -21,7 +21,7 @@ public: void initialize(MapController & controller); protected: - MapScene * scene; + MapSceneBase * scene; CMap * map = nullptr; MapHandler * handler = nullptr; bool isShown = false; @@ -37,7 +37,7 @@ private: class GridLayer: public AbstractLayer { public: - GridLayer(MapScene * s); + GridLayer(MapSceneBase * s); void update() override; }; @@ -45,7 +45,7 @@ public: class PassabilityLayer: public AbstractLayer { public: - PassabilityLayer(MapScene * s); + PassabilityLayer(MapSceneBase * s); void update() override; }; @@ -54,7 +54,7 @@ public: class SelectionTerrainLayer: public AbstractLayer { public: - SelectionTerrainLayer(MapScene * s); + SelectionTerrainLayer(MapSceneBase * s); void update() override; @@ -73,7 +73,7 @@ private: class TerrainLayer: public AbstractLayer { public: - TerrainLayer(MapScene * s); + TerrainLayer(MapSceneBase * s); void update() override; @@ -88,7 +88,7 @@ private: class ObjectsLayer: public AbstractLayer { public: - ObjectsLayer(MapScene * s); + ObjectsLayer(MapSceneBase * s); void update() override; @@ -105,7 +105,7 @@ private: class SelectionObjectsLayer: public AbstractLayer { public: - SelectionObjectsLayer(MapScene * s); + SelectionObjectsLayer(MapSceneBase * s); void update() override; @@ -127,4 +127,12 @@ private: std::set selectedObjects; }; +class MinimapLayer: public AbstractLayer +{ +public: + MinimapLayer(MapSceneBase * s); + + void update() override; +}; + #endif // SCENELAYER_H diff --git a/mapeditor/windownewmap.cpp b/mapeditor/windownewmap.cpp index dcd3d5bef..57fbefa83 100644 --- a/mapeditor/windownewmap.cpp +++ b/mapeditor/windownewmap.cpp @@ -250,15 +250,23 @@ void WindowNewMap::on_templateCombo_activated(int index) void WindowNewMap::on_widthTxt_textChanged(const QString &arg1) { - mapGenOptions.setWidth(arg1.toInt()); - updateTemplateList(); + int sz = arg1.toInt(); + if(sz > 1) + { + mapGenOptions.setWidth(arg1.toInt()); + updateTemplateList(); + } } void WindowNewMap::on_heightTxt_textChanged(const QString &arg1) { - mapGenOptions.setHeight(arg1.toInt()); - updateTemplateList(); + int sz = arg1.toInt(); + if(sz > 1) + { + mapGenOptions.setHeight(arg1.toInt()); + updateTemplateList(); + } } void WindowNewMap::updateTemplateList()