1
0
mirror of https://github.com/vcmi/vcmi.git synced 2025-01-18 03:21:27 +02:00

Refactoring

This commit is contained in:
nordsoft 2022-09-05 04:19:21 +04:00
parent 28f0abd545
commit eb501f2222
12 changed files with 1004 additions and 849 deletions

View File

@ -19,6 +19,8 @@ set(editor_SRCS
mapsettings.cpp
playersettings.cpp
playerparams.cpp
scenelayer.cpp
mapcontroller.cpp
)
set(editor_HEADERS
@ -41,6 +43,8 @@ set(editor_HEADERS
mapsettings.h
playersettings.h
playerparams.h
scenelayer.h
mapcontroller.h
)
set(editor_FORMS

View File

@ -19,7 +19,6 @@
#include "../lib/mapping/CMapEditManager.h"
#include "../lib/Terrain.h"
#include "../lib/mapObjects/CObjectClassesHandler.h"
#include "../lib/rmg/ObstaclePlacer.h"
#include "CGameInfo.h"
@ -58,12 +57,11 @@ void init()
}
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
QMainWindow(parent),
ui(new Ui::MainWindow),
controller(this)
{
ui->setupUi(this);
ui->mapView->setMain(this);
ui->setupUi(this);
// Set current working dir to executable folder.
// This is important on Mac for relative paths to work inside DMG.
@ -118,9 +116,9 @@ MainWindow::MainWindow(QWidget *parent) :
//now let's try to draw
//auto resPath = *CResourceHandler::get()->getResourceName(ResourceID("DATA/new-menu/Background.png"));
scenes[0] = new MapScene(this, 0);
scenes[1] = new MapScene(this, 1);
ui->mapView->setScene(scenes[0]);
ui->mapView->setScene(controller.scene(0));
ui->mapView->setController(&controller);
connect(ui->mapView, &MapView::openObjectProperties, this, &MainWindow::loadInspector);
sceneMini = new QGraphicsScene(this);
ui->minimapView->setScene(sceneMini);
@ -143,11 +141,6 @@ MainWindow::~MainWindow()
delete ui;
}
MapView * MainWindow::getMapView()
{
return ui->mapView;
}
void MainWindow::setStatusMessage(const QString & status)
{
statusBar()->showMessage(status);
@ -159,52 +152,28 @@ void MainWindow::reloadMap(int level)
//float ratio = std::fmin(mapSizePx.width() / 192., mapSizePx.height() / 192.);*/
//minimap = mapHandler->surface;
//minimap.setDevicePixelRatio(ratio);
scenes[level]->updateViews();
controller.sceneForceUpdate(level);
//sceneMini->clear();
//sceneMini->addPixmap(minimap);
}
CMap * MainWindow::getMap()
{
return map.get();
}
MapHandler * MainWindow::getMapHandler()
{
return mapHandler.get();
}
void MainWindow::resetMapHandler()
{
mapHandler.reset(new MapHandler(map.get()));
unsaved = true;
setWindowTitle(filename + "* - VCMI Map Editor");
}
void MainWindow::setMapRaw(std::unique_ptr<CMap> cmap)
{
map = std::move(cmap);
}
void MainWindow::setMap(bool isNew)
void MainWindow::initializeMap(bool isNew)
{
unsaved = isNew;
if(isNew)
filename.clear();
setWindowTitle(filename + "* - VCMI Map Editor");
mapHandler.reset(new MapHandler(map.get()));
reloadMap();
if(map->twoLevel)
reloadMap(1);
// reloadMap();
//if(map->twoLevel)
//reloadMap(1);
mapLevel = 0;
ui->mapView->setScene(scenes[mapLevel]);
ui->mapView->setScene(controller.scene(mapLevel));
//enable settings
ui->actionMapSettings->setEnabled(true);
@ -232,19 +201,19 @@ void MainWindow::on_actionOpen_triggered()
CMapService mapService;
try
{
map = mapService.loadMap(resId);
controller.setMap(mapService.loadMap(resId));
}
catch(const std::exception & e)
{
QMessageBox::critical(this, "Failed to open map", e.what());
}
setMap(false);
initializeMap(false);
}
void MainWindow::saveMap()
{
if(!map)
if(!controller.map())
return;
if(!unsaved)
@ -253,7 +222,7 @@ void MainWindow::saveMap()
CMapService mapService;
try
{
mapService.saveMap(map, filename.toStdString());
mapService.saveMap(std::unique_ptr<CMap>(controller.map()), filename.toStdString());
}
catch(const std::exception & e)
{
@ -266,7 +235,7 @@ void MainWindow::saveMap()
void MainWindow::on_actionSave_as_triggered()
{
if(!map)
if(!controller.map())
return;
auto filenameSelect = QFileDialog::getSaveFileName(this, tr("Save map"), "", tr("VCMI maps (*.vmap)"));
@ -285,12 +254,12 @@ void MainWindow::on_actionSave_as_triggered()
void MainWindow::on_actionNew_triggered()
{
auto newMapDialog = new WindowNewMap(this);
new WindowNewMap(this);
}
void MainWindow::on_actionSave_triggered()
{
if(!map)
if(!controller.map())
return;
if(filename.isNull())
@ -308,19 +277,7 @@ void MainWindow::on_actionSave_triggered()
void MainWindow::terrainButtonClicked(Terrain terrain)
{
std::vector<int3> v(scenes[mapLevel]->selectionTerrainView.selection().begin(), scenes[mapLevel]->selectionTerrainView.selection().end());
if(v.empty())
return;
scenes[mapLevel]->selectionTerrainView.clear();
scenes[mapLevel]->selectionTerrainView.draw();
map->getEditManager()->getTerrainSelection().setSelection(v);
map->getEditManager()->drawTerrain(terrain, &CRandomGenerator::getDefault());
for(auto & t : v)
scenes[mapLevel]->terrainView.setDirty(t);
scenes[mapLevel]->terrainView.draw();
controller.commitTerrainChange(mapLevel, terrain);
}
void MainWindow::addGroupIntoCatalog(const std::string & groupName, bool staticOnly)
@ -585,29 +542,29 @@ void MainWindow::loadObjectsTree()
void MainWindow::on_actionLevel_triggered()
{
if(map && map->twoLevel)
if(controller.map() && controller.map()->twoLevel)
{
mapLevel = mapLevel ? 0 : 1;
ui->mapView->setScene(scenes[mapLevel]);
ui->mapView->setScene(controller.scene(mapLevel));
}
}
void MainWindow::on_actionPass_triggered(bool checked)
{
if(map)
if(controller.map())
{
scenes[0]->passabilityView.show(checked);
scenes[1]->passabilityView.show(checked);
controller.scene(0)->passabilityView.show(checked);
controller.scene(1)->passabilityView.show(checked);
}
}
void MainWindow::on_actionGrid_triggered(bool checked)
{
if(map)
if(controller.map())
{
scenes[0]->gridView.show(checked);
scenes[1]->gridView.show(checked);
controller.scene(0)->gridView.show(checked);
controller.scene(0)->gridView.show(checked);
}
}
@ -676,11 +633,9 @@ void MainWindow::on_toolArea_clicked(bool checked)
void MainWindow::on_toolErase_clicked()
{
if(map && scenes[mapLevel])
if(controller.map())
{
scenes[mapLevel]->selectionObjectsView.deleteSelection();
resetMapHandler();
scenes[mapLevel]->updateViews();
controller.commitObjectErase(mapLevel);
}
}
@ -702,20 +657,11 @@ void MainWindow::preparePreview(const QModelIndex &index, bool createNew)
auto objSubId = data["subid"].toInt();
auto templateId = data["template"].toInt();
scenes[mapLevel]->selectionObjectsView.clear();
if(scenes[mapLevel]->selectionObjectsView.newObject)
{
createNew = true;
delete scenes[mapLevel]->selectionObjectsView.newObject;
}
if(createNew)
if(controller.discardObject(mapLevel) || createNew)
{
auto factory = VLC->objtypeh->getHandlerFor(objId, objSubId);
auto templ = factory->getTemplates()[templateId];
scenes[mapLevel]->selectionObjectsView.newObject = factory->create(templ);
scenes[mapLevel]->selectionObjectsView.selectionMode = 2;
scenes[mapLevel]->selectionObjectsView.draw();
controller.createObject(mapLevel, factory->create(templ));
}
}
}
@ -765,33 +711,10 @@ void MainWindow::on_filter_textChanged(const QString &arg1)
void MainWindow::on_actionFill_triggered()
{
if(!map || !scenes[mapLevel])
if(!controller.map())
return;
auto selection = scenes[mapLevel]->selectionTerrainView.selection();
if(selection.empty())
return;
//split by zones
std::map<Terrain, ObstacleProxy> terrainSelected;
for(auto & t : selection)
{
auto tl = map->getTile(t);
if(tl.blocked || tl.visitable)
continue;
terrainSelected[tl.terType].blockedArea.add(t);
}
for(auto & sel : terrainSelected)
{
sel.second.collectPossibleObstacles(sel.first);
sel.second.placeObstacles(map.get(), CRandomGenerator::getDefault());
}
scenes[mapLevel]->selectionObjectsView.deleteSelection();
resetMapHandler();
scenes[mapLevel]->updateViews();
controller.commitObstacleFill(mapLevel);
}
void MainWindow::loadInspector(CGObjectInstance * obj)
@ -825,16 +748,17 @@ void MainWindow::on_inspectorWidget_itemChanged(QTableWidgetItem *item)
//set parameter
Inspector inspector(obj, tableWidget);
inspector.setProperty(param, item->text());
controller.commitObjectChange(mapLevel);
}
void MainWindow::on_actionMapSettings_triggered()
{
auto mapSettingsDialog = new MapSettings(this);
auto mapSettingsDialog = new MapSettings(controller, this);
}
void MainWindow::on_actionPlayers_settings_triggered()
{
auto mapSettingsDialog = new PlayerSettings(*map, this);
auto mapSettingsDialog = new PlayerSettings(*controller.map(), this);
}

View File

@ -4,10 +4,9 @@
#include <QMainWindow>
#include <QGraphicsScene>
#include <QStandardItemModel>
#include "mapcontroller.h"
#include "../lib/Terrain.h"
#include "maphandler.h"
#include "mapview.h"
class CMap;
class ObjectBrowser;
@ -25,24 +24,19 @@ public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
void setMapRaw(std::unique_ptr<CMap> cmap);
void setMap(bool isNew);
void initializeMap(bool isNew);
void reloadMap(int level = 0);
void saveMap();
CMap * getMap();
MapHandler * getMapHandler();
void resetMapHandler();
MapView * mapView();
void loadObjectsTree();
void setStatusMessage(const QString & status);
void loadInspector(CGObjectInstance * obj);
MapView * getMapView();
int getMapLevel() const {return mapLevel;}
MapController controller;
private slots:
void on_actionOpen_triggered();
@ -88,6 +82,7 @@ private slots:
public slots:
void treeViewSelected(const QModelIndex &selected, const QModelIndex &deselected);
void loadInspector(CGObjectInstance * obj);
private:
void preparePreview(const QModelIndex &index, bool createNew);
@ -99,13 +94,10 @@ private:
private:
Ui::MainWindow *ui;
ObjectBrowser * objectBrowser = nullptr;
std::unique_ptr<MapHandler> mapHandler;
std::array<MapScene *, 2> scenes;
QGraphicsScene * sceneMini;
QGraphicsScene * scenePreview;
QPixmap minimap;
std::unique_ptr<CMap> map;
QString filename;
bool unsaved = false;

199
mapeditor/mapcontroller.cpp Normal file
View File

@ -0,0 +1,199 @@
#include "mapcontroller.h"
#include "../lib/GameConstants.h"
#include "../lib/mapping/CMapService.h"
#include "../lib/mapping/CMap.h"
#include "../lib/mapping/CMapEditManager.h"
#include "../lib/Terrain.h"
#include "../lib/mapObjects/CObjectClassesHandler.h"
#include "../lib/rmg/ObstaclePlacer.h"
#include "mapview.h"
#include "scenelayer.h"
#include "maphandler.h"
#include "mainwindow.h"
#include "inspector.h"
MapController::MapController(MainWindow * m) : _main(m)
{
_scenes[0] = new MapScene(0);
_scenes[1] = new MapScene(1);
}
MapController::~MapController()
{
delete _scenes[0];
delete _scenes[1];
}
CMap * MapController::map()
{
return _map.get();
}
MapHandler * MapController::mapHandler()
{
return _mapHandler.get();
}
MapScene * MapController::scene(int level)
{
return _scenes[level];
}
void MapController::setMap(std::unique_ptr<CMap> cmap)
{
_map = std::move(cmap);
resetMapHandler();
sceneForceUpdate();
}
void MapController::sceneForceUpdate()
{
_scenes[0]->updateViews();
if(_map->twoLevel)
_scenes[1]->updateViews();
}
void MapController::sceneForceUpdate(int level)
{
_scenes[level]->updateViews();
}
void MapController::resetMapHandler()
{
_mapHandler.reset(new MapHandler(_map.get()));
_scenes[0]->initialize(*this);
_scenes[1]->initialize(*this);
}
void MapController::commitTerrainChange(int level, const Terrain & terrain)
{
std::vector<int3> v(_scenes[level]->selectionTerrainView.selection().begin(),
_scenes[level]->selectionTerrainView.selection().end());
if(v.empty())
return;
_scenes[level]->selectionTerrainView.clear();
_scenes[level]->selectionTerrainView.draw();
_map->getEditManager()->getTerrainSelection().setSelection(v);
_map->getEditManager()->drawTerrain(terrain, &CRandomGenerator::getDefault());
for(auto & t : v)
_scenes[level]->terrainView.setDirty(t);
_scenes[level]->terrainView.draw();
}
void MapController::commitObjectErase(int level)
{
for(auto * obj : _scenes[level]->selectionObjectsView.getSelection())
{
_map->getEditManager()->removeObject(obj);
delete obj;
}
_scenes[level]->selectionObjectsView.clear();
resetMapHandler();
_scenes[level]->updateViews();
}
bool MapController::discardObject(int level) const
{
_scenes[level]->selectionObjectsView.clear();
if(_scenes[level]->selectionObjectsView.newObject)
{
delete _scenes[level]->selectionObjectsView.newObject;
_scenes[level]->selectionObjectsView.newObject = nullptr;
_scenes[level]->selectionObjectsView.shift = QPoint(0, 0);
_scenes[level]->selectionObjectsView.selectionMode = 0;
_scenes[level]->selectionObjectsView.draw();
return true;
}
return false;
}
void MapController::createObject(int level, CGObjectInstance * obj) const
{
_scenes[level]->selectionObjectsView.newObject = obj;
_scenes[level]->selectionObjectsView.selectionMode = 2;
_scenes[level]->selectionObjectsView.draw();
}
void MapController::commitObstacleFill(int level)
{
auto selection = _scenes[level]->selectionTerrainView.selection();
if(selection.empty())
return;
//split by zones
std::map<Terrain, ObstacleProxy> terrainSelected;
for(auto & t : selection)
{
auto tl = _map->getTile(t);
if(tl.blocked || tl.visitable)
continue;
terrainSelected[tl.terType].blockedArea.add(t);
}
for(auto & sel : terrainSelected)
{
sel.second.collectPossibleObstacles(sel.first);
sel.second.placeObstacles(_map.get(), CRandomGenerator::getDefault());
}
resetMapHandler();
_scenes[level]->updateViews();
}
void MapController::commitObjectChange(int level)
{
resetMapHandler();
_scenes[level]->updateViews();
}
void MapController::commitChangeWithoutRedraw()
{
//DO NOT REDRAW
}
void MapController::commitObjectShiftOrCreate(int level)
{
auto shift = _scenes[level]->selectionObjectsView.shift;
if(shift.isNull())
return;
for(auto * obj : _scenes[level]->selectionObjectsView.getSelection())
{
int3 pos = obj->pos;
pos.z = level;
pos.x += shift.x(); pos.y += shift.y();
if(obj == _scenes[level]->selectionObjectsView.newObject)
{
_scenes[level]->selectionObjectsView.newObject->pos = pos;
commitObjectCreate(level);
}
else
{
_map->getEditManager()->moveObject(obj, pos);
}
}
_scenes[level]->selectionObjectsView.newObject = nullptr;
_scenes[level]->selectionObjectsView.shift = QPoint(0, 0);
_scenes[level]->selectionObjectsView.selectionMode = 0;
resetMapHandler();
_scenes[level]->updateViews();
}
void MapController::commitObjectCreate(int level)
{
auto * newObj = _scenes[level]->selectionObjectsView.newObject;
if(!newObj)
return;
_map->getEditManager()->insertObject(newObj);
Initializer init(newObj);
}

47
mapeditor/mapcontroller.h Normal file
View File

@ -0,0 +1,47 @@
#ifndef MAPCONTROLLER_H
#define MAPCONTROLLER_H
#include "maphandler.h"
#include "mapview.h"
#include "../lib/mapping/CMap.h"
#include "../lib/Terrain.h"
class MainWindow;
class MapController
{
public:
MapController(MainWindow *);
MapController(const MapController &) = delete;
MapController(const MapController &&) = delete;
~MapController();
void setMap(std::unique_ptr<CMap>);
CMap * map();
MapHandler * mapHandler();
MapScene * scene(int level);
void resetMapHandler();
void sceneForceUpdate();
void sceneForceUpdate(int level);
void commitTerrainChange(int level, const Terrain & terrain);
void commitObjectErase(int level);
void commitObstacleFill(int level);
void commitChangeWithoutRedraw();
void commitObjectShiftOrCreate(int level);
void commitObjectCreate(int level);
void commitObjectChange(int level);
bool discardObject(int level) const;
void createObject(int level, CGObjectInstance * obj) const;
private:
MainWindow * _main;
std::unique_ptr<CMap> _map;
std::unique_ptr<MapHandler> _mapHandler;
mutable std::array<MapScene *, 2> _scenes;
};
#endif // MAPCONTROLLER_H

View File

@ -2,18 +2,17 @@
#include "ui_mapsettings.h"
#include "mainwindow.h"
MapSettings::MapSettings(MainWindow *parent) :
QDialog(static_cast<QWidget*>(parent)),
MapSettings::MapSettings(MapController & ctrl, QWidget *parent) :
QDialog(parent),
ui(new Ui::MapSettings),
main(parent)
controller(ctrl)
{
ui->setupUi(this);
assert(main);
assert(main->getMap());
assert(controller.map());
ui->mapNameEdit->setText(QString::fromStdString(main->getMap()->name));
ui->mapDescriptionEdit->setPlainText(QString::fromStdString(main->getMap()->description));
ui->mapNameEdit->setText(QString::fromStdString(controller.map()->name));
ui->mapDescriptionEdit->setPlainText(QString::fromStdString(controller.map()->description));
show();
@ -35,7 +34,8 @@ MapSettings::~MapSettings()
void MapSettings::on_pushButton_clicked()
{
main->getMap()->name = ui->mapNameEdit->text().toStdString();
main->getMap()->description = ui->mapDescriptionEdit->toPlainText().toStdString();
controller.map()->name = ui->mapNameEdit->text().toStdString();
controller.map()->description = ui->mapDescriptionEdit->toPlainText().toStdString();
controller.commitChangeWithoutRedraw();
close();
}

View File

@ -2,18 +2,18 @@
#define MAPSETTINGS_H
#include <QDialog>
#include "mapcontroller.h"
namespace Ui {
class MapSettings;
}
class MainWindow;
class MapSettings : public QDialog
{
Q_OBJECT
public:
explicit MapSettings(MainWindow *parent = nullptr);
explicit MapSettings(MapController & controller, QWidget *parent = nullptr);
~MapSettings();
private slots:
@ -21,7 +21,7 @@ private slots:
private:
Ui::MapSettings *ui;
MainWindow * main;
MapController & controller;
};
#endif // MAPSETTINGS_H

View File

@ -1,20 +1,18 @@
#include "StdInc.h"
#include "mapview.h"
#include "mainwindow.h"
#include "inspector.h"
#include <QGraphicsSceneMouseEvent>
#include "mapcontroller.h"
#include "../lib/mapping/CMapEditManager.h"
MapView::MapView(QWidget *parent):
MapView::MapView(QWidget * parent):
QGraphicsView(parent),
selectionTool(MapView::SelectionTool::None)
{
}
void MapView::setMain(MainWindow * m)
void MapView::setController(MapController * ctrl)
{
main = m;
controller = ctrl;
}
void MapView::mouseMoveEvent(QMouseEvent *mouseEvent)
@ -205,7 +203,8 @@ void MapView::mousePressEvent(QMouseEvent *event)
if(sc->selectionObjectsView.newObject && sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject))
{
if(event->button() == Qt::RightButton)
controller->discardObject(sc->level);
}
else
{
@ -245,31 +244,18 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
this->update();
auto * sc = static_cast<MapScene*>(scene());
if(!sc)
if(!sc || !controller)
return;
if(sc->selectionObjectsView.newObject)
{
if(!sc->selectionObjectsView.isSelected(sc->selectionObjectsView.newObject) || event->button() == Qt::RightButton)
{
delete sc->selectionObjectsView.newObject;
sc->selectionObjectsView.newObject = nullptr;
}
}
switch(selectionTool)
{
case MapView::SelectionTool::None:
if(event->button() == Qt::RightButton)
break;
//switch position
if(sc->selectionObjectsView.selectionMode == 2 && sc->selectionObjectsView.applyShift())
if(sc->selectionObjectsView.selectionMode == 2 && !sc->selectionObjectsView.shift.isNull())
{
sc->selectionObjectsView.newObject = nullptr;
sc->selectionObjectsView.selectionMode = 0;
sc->selectionObjectsView.shift = QPoint(0, 0);
main->resetMapHandler();
sc->updateViews();
controller->commitObjectShiftOrCreate(sc->level);
}
else
{
@ -279,563 +265,52 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
//check if we have only one object
auto selection = sc->selectionObjectsView.getSelection();
if(selection.size() == 1)
main->loadInspector(*selection.begin());
{
emit openObjectProperties(*selection.begin());
}
}
break;
}
}
MapScene::MapScene(MainWindow *parent, int l):
QGraphicsScene(parent),
gridView(parent, this),
passabilityView(parent, this),
selectionTerrainView(parent, this),
terrainView(parent, this),
objectsView(parent, this),
selectionObjectsView(parent, this),
main(parent),
level(l)
MapScene::MapScene(int lev):
QGraphicsScene(nullptr),
gridView(this),
passabilityView(this),
selectionTerrainView(this),
terrainView(this),
objectsView(this),
selectionObjectsView(this),
level(lev)
{
}
std::list<AbstractLayer *> MapScene::getAbstractLayers()
{
//sequence is important because it defines rendering order
return {
&terrainView,
&objectsView,
&gridView,
&passabilityView,
&selectionTerrainView,
&selectionObjectsView
};
}
void MapScene::initialize(MapController & controller)
{
for(auto * layer : getAbstractLayers())
layer->initialize(controller);
}
void MapScene::updateViews()
{
//sequence is important because it defines rendering order
terrainView.update();
objectsView.update();
gridView.update();
passabilityView.update();
selectionTerrainView.update();
selectionObjectsView.update();
for(auto * layer : getAbstractLayers())
layer->update();
terrainView.show(true);
objectsView.show(true);
selectionTerrainView.show(true);
selectionObjectsView.show(true);
}
BasicView::BasicView(MainWindow * m, MapScene * s): main(m), scene(s)
{
if(main->getMap())
update();
}
void BasicView::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;
}
void BasicView::redraw()
{
if(item)
{
if(pixmap && isShown)
item->setPixmap(*pixmap);
else
item->setPixmap(emptyPixmap);
}
else
{
if(pixmap && isShown)
item.reset(scene->addPixmap(*pixmap));
else
item.reset(scene->addPixmap(emptyPixmap));
}
}
GridView::GridView(MainWindow * m, MapScene * s): BasicView(m, s)
{
}
void GridView::update()
{
auto map = main->getMap();
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
QPainter painter(pixmap.get());
painter.setPen(QColor(0, 0, 0, 190));
for(int j = 0; j < map->height; ++j)
{
painter.drawLine(0, j * 32, map->width * 32 - 1, j * 32);
}
for(int i = 0; i < map->width; ++i)
{
painter.drawLine(i * 32, 0, i * 32, map->height * 32 - 1);
}
redraw();
}
PassabilityView::PassabilityView(MainWindow * m, MapScene * s): BasicView(m, s)
{
}
void PassabilityView::update()
{
auto map = main->getMap();
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
if(scene->level == 0 || map->twoLevel)
{
QPainter painter(pixmap.get());
for(int j = 0; j < map->height; ++j)
{
for(int i = 0; i < map->width; ++i)
{
auto tl = map->getTile(int3(i, j, scene->level));
if(tl.blocked || tl.visitable)
{
painter.fillRect(i * 32, j * 32, 31, 31, tl.visitable ? QColor(200, 200, 0, 64) : QColor(255, 0, 0, 64));
}
}
}
}
redraw();
}
SelectionTerrainView::SelectionTerrainView(MainWindow * m, MapScene * s): BasicView(m, s)
{
}
void SelectionTerrainView::update()
{
auto map = main->getMap();
if(!map)
return;
area.clear();
areaAdd.clear();
areaErase.clear();
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
redraw();
}
void SelectionTerrainView::draw()
{
if(!pixmap)
return;
QPainter painter(pixmap.get());
painter.setCompositionMode(QPainter::CompositionMode_Source);
for(auto & t : areaAdd)
{
painter.fillRect(t.x * 32, t.y * 32, 31, 31, QColor(128, 128, 128, 96));
}
for(auto & t : areaErase)
{
painter.fillRect(t.x * 32, t.y * 32, 31, 31, QColor(0, 0, 0, 0));
}
areaAdd.clear();
areaErase.clear();
redraw();
}
void SelectionTerrainView::select(const int3 & tile)
{
if(!main->getMap() || !main->getMap()->isInTheMap(tile))
return;
if(!area.count(tile))
{
area.insert(tile);
areaAdd.insert(tile);
areaErase.erase(tile);
}
}
void SelectionTerrainView::erase(const int3 & tile)
{
if(!main->getMap() || !main->getMap()->isInTheMap(tile))
return;
if(area.count(tile))
{
area.erase(tile);
areaErase.insert(tile);
areaAdd.erase(tile);
}
}
void SelectionTerrainView::clear()
{
areaErase = area;
areaAdd.clear();
area.clear();
}
const std::set<int3> & SelectionTerrainView::selection() const
{
return area;
}
TerrainView::TerrainView(MainWindow * m, MapScene * s): BasicView(m, s)
{
}
void TerrainView::update()
{
auto map = main->getMap();
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
draw(false);
}
void TerrainView::setDirty(const int3 & tile)
{
dirty.insert(tile);
}
void TerrainView::draw(bool onlyDirty)
{
if(!pixmap)
return;
auto map = main->getMap();
if(!map)
return;
QPainter painter(pixmap.get());
painter.setCompositionMode(QPainter::CompositionMode_Source);
if(onlyDirty)
{
std::set<int3> forRedrawing(dirty), neighbours;
for(auto & t : dirty)
{
for(auto & tt : int3::getDirs())
{
if(map->isInTheMap(t + tt))
neighbours.insert(t + tt);
}
}
for(auto & t : neighbours)
{
for(auto & tt : int3::getDirs())
{
forRedrawing.insert(t);
if(map->isInTheMap(t + tt))
forRedrawing.insert(t + tt);
}
}
for(auto & t : forRedrawing)
{
//TODO: fix water and roads
main->getMapHandler()->drawTerrainTile(painter, t.x, t.y, scene->level);
//main->getMapHandler()->drawRiver(painter, t.x, t.y, scene->level);
//main->getMapHandler()->drawRoad(painter, t.x, t.y, scene->level);
}
}
else
{
for(int j = 0; j < map->height; ++j)
{
for(int i = 0; i < map->width; ++i)
{
//TODO: fix water and roads
main->getMapHandler()->drawTerrainTile(painter, i, j, scene->level);
//main->getMapHandler()->drawRiver(painter, i, j, scene->level);
//main->getMapHandler()->drawRoad(painter, i, j, scene->level);
}
}
}
dirty.clear();
redraw();
}
ObjectsView::ObjectsView(MainWindow * m, MapScene * s): BasicView(m, s)
{
}
void ObjectsView::update()
{
auto map = main->getMap();
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
draw(false);
}
void ObjectsView::draw(bool onlyDirty)
{
if(!pixmap)
return;
auto map = main->getMap();
if(!map)
return;
pixmap->fill(QColor(0, 0, 0, 0));
QPainter painter(pixmap.get());
//painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
std::set<const CGObjectInstance *> drawen;
for(int j = 0; j < map->height; ++j)
{
for(int i = 0; i < map->width; ++i)
{
main->getMapHandler()->drawObjects(painter, i, j, scene->level);
/*auto & objects = main->getMapHandler()->getObjects(i, j, scene->level);
for(auto & object : objects)
{
if(!object.obj || drawen.count(object.obj))
continue;
if(!onlyDirty || dirty.count(object.obj))
{
main->getMapHandler()->drawObject(painter, object);
drawen.insert(object.obj);
}
}*/
}
}
dirty.clear();
redraw();
}
void ObjectsView::setDirty(int x, int y)
{
auto & objects = main->getMapHandler()->getObjects(x, y, scene->level);
for(auto & object : objects)
{
if(object.obj)
dirty.insert(object.obj);
}
}
void ObjectsView::setDirty(const CGObjectInstance * object)
{
dirty.insert(object);
}
SelectionObjectsView::SelectionObjectsView(MainWindow * m, MapScene * s): BasicView(m, s), newObject(nullptr)
{
}
void SelectionObjectsView::update()
{
auto map = main->getMap();
if(!map)
return;
selectedObjects.clear();
shift = QPoint();
if(newObject)
delete newObject;
newObject = nullptr;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
//pixmap->fill(QColor(0, 0, 0, 0));
draw();
}
void SelectionObjectsView::draw()
{
if(!pixmap)
return;
pixmap->fill(QColor(0, 0, 0, 0));
QPainter painter(pixmap.get());
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setPen(QColor(255, 255, 255));
for(auto * obj : selectedObjects)
{
if(obj != newObject)
{
QRect bbox(obj->getPosition().x, obj->getPosition().y, 1, 1);
for(auto & t : obj->getBlockedPos())
{
QPoint topLeft(std::min(t.x, bbox.topLeft().x()), std::min(t.y, bbox.topLeft().y()));
bbox.setTopLeft(topLeft);
QPoint bottomRight(std::max(t.x, bbox.bottomRight().x()), std::max(t.y, bbox.bottomRight().y()));
bbox.setBottomRight(bottomRight);
}
painter.setOpacity(1.0);
painter.drawRect(bbox.x() * 32, bbox.y() * 32, bbox.width() * 32, bbox.height() * 32);
}
//show translation
if(selectionMode == 2 && (shift.x() || shift.y()))
{
painter.setOpacity(0.5);
auto newPos = QPoint(obj->getPosition().x, obj->getPosition().y) + shift;
main->getMapHandler()->drawObjectAt(painter, obj, newPos.x(), newPos.y());
}
}
redraw();
}
CGObjectInstance * SelectionObjectsView::selectObjectAt(int x, int y) const
{
if(!main->getMap() || !main->getMapHandler() || !main->getMap()->isInTheMap(int3(x, y, scene->level)))
return nullptr;
auto & objects = main->getMapHandler()->getObjects(x, y, scene->level);
//visitable is most important
for(auto & object : objects)
{
if(!object.obj)
continue;
if(object.obj->visitableAt(x, y))
{
return object.obj;
}
}
//if not visitable tile - try to get blocked
for(auto & object : objects)
{
if(!object.obj)
continue;
if(object.obj->blockingAt(x, y))
{
return object.obj;
}
}
//finally, we can take any object
for(auto & object : objects)
{
if(!object.obj)
continue;
if(object.obj->coveringAt(x, y))
{
return object.obj;
}
}
return nullptr;
}
bool SelectionObjectsView::applyShift()
{
if(shift.x() || shift.y())
{
for(auto * obj : selectedObjects)
{
int3 pos = obj->pos;
pos.z = main->getMapLevel();
pos.x += shift.x(); pos.y += shift.y();
if(obj == newObject)
{
newObject->pos = pos;
main->getMap()->getEditManager()->insertObject(newObject);
Initializer init(newObject);
}
else
{
main->getMap()->getEditManager()->moveObject(obj, pos);
}
}
return true;
}
return false;
}
void SelectionObjectsView::deleteSelection()
{
for(auto * obj : selectedObjects)
{
main->getMap()->getEditManager()->removeObject(obj);
delete obj;
}
clear();
}
void SelectionObjectsView::selectObjects(int x1, int y1, int x2, int y2)
{
if(!main->getMap() || !main->getMapHandler())
return;
if(x1 > x2)
std::swap(x1, x2);
if(y1 > y2)
std::swap(y1, y2);
for(int j = y1; j < y2; ++j)
{
for(int i = x1; i < x2; ++i)
{
for(auto & o : main->getMapHandler()->getObjects(i, j, scene->level))
selectObject(o.obj);
}
}
}
void SelectionObjectsView::selectObject(CGObjectInstance * obj)
{
selectedObjects.insert(obj);
}
bool SelectionObjectsView::isSelected(const CGObjectInstance * obj) const
{
return selectedObjects.count(const_cast<CGObjectInstance*>(obj));
}
std::set<CGObjectInstance*> SelectionObjectsView::getSelection() const
{
return selectedObjects;
}
void SelectionObjectsView::clear()
{
selectedObjects.clear();
shift.setX(0);
shift.setY(0);
}

View File

@ -3,37 +3,38 @@
#include <QGraphicsScene>
#include <QGraphicsView>
#include "scenelayer.h"
#include "../lib/int3.h"
class int3;
class CGObjectInstance;
class MainWindow;
class MapScene;
class MapController;
class BasicView
class MapScene : public QGraphicsScene
{
public:
BasicView(MainWindow * m, MapScene * s);
virtual void update() = 0;
void show(bool show);
void redraw();
protected:
MainWindow * main;
MapScene * scene;
bool isShown = false;
std::unique_ptr<QPixmap> pixmap;
QPixmap emptyPixmap;
MapScene(int lev);
void updateViews();
void initialize(MapController &);
GridLayer gridView;
PassabilityLayer passabilityView;
SelectionTerrainLayer selectionTerrainView;
TerrainLayer terrainView;
ObjectsLayer objectsView;
SelectionObjectsLayer selectionObjectsView;
const int level;
private:
std::unique_ptr<QGraphicsPixmapItem> item;
std::list<AbstractLayer *> getAbstractLayers();
};
class MapView : public QGraphicsView
{
Q_OBJECT
public:
enum class SelectionTool
{
@ -41,9 +42,8 @@ public:
};
public:
MapView(QWidget *parent);
void setMain(MainWindow * m);
MapView(QWidget * parent);
void setController(MapController *);
SelectionTool selectionTool;
@ -51,126 +51,16 @@ public slots:
void mouseMoveEvent(QMouseEvent * mouseEvent) override;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
signals:
void openObjectProperties(CGObjectInstance *);
private:
MainWindow * main;
MapController * controller = nullptr;
QPointF mouseStart;
int3 tileStart;
int3 tilePrev;
bool pressedOnSelected;
};
class GridView: public BasicView
{
public:
GridView(MainWindow * m, MapScene * s);
void update() override;
};
class PassabilityView: public BasicView
{
public:
PassabilityView(MainWindow * m, MapScene * s);
void update() override;
};
class SelectionTerrainView: public BasicView
{
public:
SelectionTerrainView(MainWindow * m, MapScene * s);
void update() override;
void draw();
void select(const int3 & tile);
void erase(const int3 & tile);
void clear();
const std::set<int3> & selection() const;
private:
std::set<int3> area, areaAdd, areaErase;
};
class TerrainView: public BasicView
{
public:
TerrainView(MainWindow * m, MapScene * s);
void update() override;
void draw(bool onlyDirty = true);
void setDirty(const int3 & tile);
private:
std::set<int3> dirty;
};
class ObjectsView: public BasicView
{
public:
ObjectsView(MainWindow * m, MapScene * s);
void update() override;
void draw(bool onlyDirty = true); //TODO: implement dirty
void setDirty(int x, int y);
void setDirty(const CGObjectInstance * object);
private:
std::set<const CGObjectInstance *> dirty;
};
class SelectionObjectsView: public BasicView
{
public:
SelectionObjectsView(MainWindow * m, MapScene * s);
void update() override;
void draw();
CGObjectInstance * selectObjectAt(int x, int y) const;
void selectObjects(int x1, int y1, int x2, int y2);
void selectObject(CGObjectInstance *);
bool isSelected(const CGObjectInstance *) const;
std::set<CGObjectInstance*> getSelection() const;
void moveSelection(int x, int y);
void clear();
bool applyShift();
void deleteSelection();
QPoint shift;
CGObjectInstance * newObject;
int selectionMode = 0; //0 - nothing, 1 - selection, 2 - movement
private:
std::set<CGObjectInstance *> selectedObjects;
};
class MapScene : public QGraphicsScene
{
public:
MapScene(MainWindow *parent, int l);
void updateViews();
GridView gridView;
PassabilityView passabilityView;
SelectionTerrainView selectionTerrainView;
TerrainView terrainView;
ObjectsView objectsView;
SelectionObjectsView selectionObjectsView;
const int level;
private:
MainWindow * main;
};
#endif // MAPVIEW_H

493
mapeditor/scenelayer.cpp Normal file
View File

@ -0,0 +1,493 @@
#include "StdInc.h"
#include "scenelayer.h"
#include "mainwindow.h"
#include "../lib/mapping/CMapEditManager.h"
#include "inspector.h"
#include "mapview.h"
#include "mapcontroller.h"
AbstractLayer::AbstractLayer(MapScene * s): scene(s)
{
}
void AbstractLayer::initialize(MapController & controller)
{
map = controller.map();
handler = controller.mapHandler();
}
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;
}
void AbstractLayer::redraw()
{
if(item)
{
if(pixmap && isShown)
item->setPixmap(*pixmap);
else
item->setPixmap(emptyPixmap);
}
else
{
if(pixmap && isShown)
item.reset(scene->addPixmap(*pixmap));
else
item.reset(scene->addPixmap(emptyPixmap));
}
}
GridLayer::GridLayer(MapScene * s): AbstractLayer(s)
{
}
void GridLayer::update()
{
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
QPainter painter(pixmap.get());
painter.setPen(QColor(0, 0, 0, 190));
for(int j = 0; j < map->height; ++j)
{
painter.drawLine(0, j * 32, map->width * 32 - 1, j * 32);
}
for(int i = 0; i < map->width; ++i)
{
painter.drawLine(i * 32, 0, i * 32, map->height * 32 - 1);
}
redraw();
}
PassabilityLayer::PassabilityLayer(MapScene * s): AbstractLayer(s)
{
}
void PassabilityLayer::update()
{
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
if(scene->level == 0 || map->twoLevel)
{
QPainter painter(pixmap.get());
for(int j = 0; j < map->height; ++j)
{
for(int i = 0; i < map->width; ++i)
{
auto tl = map->getTile(int3(i, j, scene->level));
if(tl.blocked || tl.visitable)
{
painter.fillRect(i * 32, j * 32, 31, 31, tl.visitable ? QColor(200, 200, 0, 64) : QColor(255, 0, 0, 64));
}
}
}
}
redraw();
}
SelectionTerrainLayer::SelectionTerrainLayer(MapScene * s): AbstractLayer(s)
{
}
void SelectionTerrainLayer::update()
{
if(!map)
return;
area.clear();
areaAdd.clear();
areaErase.clear();
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
redraw();
}
void SelectionTerrainLayer::draw()
{
if(!pixmap)
return;
QPainter painter(pixmap.get());
painter.setCompositionMode(QPainter::CompositionMode_Source);
for(auto & t : areaAdd)
{
painter.fillRect(t.x * 32, t.y * 32, 31, 31, QColor(128, 128, 128, 96));
}
for(auto & t : areaErase)
{
painter.fillRect(t.x * 32, t.y * 32, 31, 31, QColor(0, 0, 0, 0));
}
areaAdd.clear();
areaErase.clear();
redraw();
}
void SelectionTerrainLayer::select(const int3 & tile)
{
if(!map || !map->isInTheMap(tile))
return;
if(!area.count(tile))
{
area.insert(tile);
areaAdd.insert(tile);
areaErase.erase(tile);
}
}
void SelectionTerrainLayer::erase(const int3 & tile)
{
if(!map || !map->isInTheMap(tile))
return;
if(area.count(tile))
{
area.erase(tile);
areaErase.insert(tile);
areaAdd.erase(tile);
}
}
void SelectionTerrainLayer::clear()
{
areaErase = area;
areaAdd.clear();
area.clear();
}
const std::set<int3> & SelectionTerrainLayer::selection() const
{
return area;
}
TerrainLayer::TerrainLayer(MapScene * s): AbstractLayer(s)
{
}
void TerrainLayer::update()
{
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
draw(false);
}
void TerrainLayer::setDirty(const int3 & tile)
{
dirty.insert(tile);
}
void TerrainLayer::draw(bool onlyDirty)
{
if(!pixmap)
return;
if(!map)
return;
QPainter painter(pixmap.get());
painter.setCompositionMode(QPainter::CompositionMode_Source);
if(onlyDirty)
{
std::set<int3> forRedrawing(dirty), neighbours;
for(auto & t : dirty)
{
for(auto & tt : int3::getDirs())
{
if(map->isInTheMap(t + tt))
neighbours.insert(t + tt);
}
}
for(auto & t : neighbours)
{
for(auto & tt : int3::getDirs())
{
forRedrawing.insert(t);
if(map->isInTheMap(t + tt))
forRedrawing.insert(t + tt);
}
}
for(auto & t : forRedrawing)
{
//TODO: fix water and roads
handler->drawTerrainTile(painter, t.x, t.y, scene->level);
//main->getMapHandler()->drawRiver(painter, t.x, t.y, scene->level);
//main->getMapHandler()->drawRoad(painter, t.x, t.y, scene->level);
}
}
else
{
for(int j = 0; j < map->height; ++j)
{
for(int i = 0; i < map->width; ++i)
{
//TODO: fix water and roads
handler->drawTerrainTile(painter, i, j, scene->level);
//main->getMapHandler()->drawRiver(painter, i, j, scene->level);
//main->getMapHandler()->drawRoad(painter, i, j, scene->level);
}
}
}
dirty.clear();
redraw();
}
ObjectsLayer::ObjectsLayer(MapScene * s): AbstractLayer(s)
{
}
void ObjectsLayer::update()
{
if(!map)
return;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
pixmap->fill(QColor(0, 0, 0, 0));
draw(false);
}
void ObjectsLayer::draw(bool onlyDirty)
{
if(!pixmap)
return;
if(!map)
return;
pixmap->fill(QColor(0, 0, 0, 0));
QPainter painter(pixmap.get());
//painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
std::set<const CGObjectInstance *> drawen;
for(int j = 0; j < map->height; ++j)
{
for(int i = 0; i < map->width; ++i)
{
handler->drawObjects(painter, i, j, scene->level);
/*auto & objects = main->getMapHandler()->getObjects(i, j, scene->level);
for(auto & object : objects)
{
if(!object.obj || drawen.count(object.obj))
continue;
if(!onlyDirty || dirty.count(object.obj))
{
main->getMapHandler()->drawObject(painter, object);
drawen.insert(object.obj);
}
}*/
}
}
dirty.clear();
redraw();
}
void ObjectsLayer::setDirty(int x, int y)
{
/*auto & objects = main->getMapHandler()->getObjects(x, y, scene->level);
for(auto & object : objects)
{
if(object.obj)
dirty.insert(object.obj);
}*/
}
void ObjectsLayer::setDirty(const CGObjectInstance * object)
{
dirty.insert(object);
}
SelectionObjectsLayer::SelectionObjectsLayer(MapScene * s): AbstractLayer(s), newObject(nullptr)
{
}
void SelectionObjectsLayer::update()
{
if(!map)
return;
selectedObjects.clear();
shift = QPoint();
if(newObject)
delete newObject;
newObject = nullptr;
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
//pixmap->fill(QColor(0, 0, 0, 0));
draw();
}
void SelectionObjectsLayer::draw()
{
if(!pixmap)
return;
pixmap->fill(QColor(0, 0, 0, 0));
QPainter painter(pixmap.get());
painter.setCompositionMode(QPainter::CompositionMode_Source);
painter.setPen(QColor(255, 255, 255));
for(auto * obj : selectedObjects)
{
if(obj != newObject)
{
QRect bbox(obj->getPosition().x, obj->getPosition().y, 1, 1);
for(auto & t : obj->getBlockedPos())
{
QPoint topLeft(std::min(t.x, bbox.topLeft().x()), std::min(t.y, bbox.topLeft().y()));
bbox.setTopLeft(topLeft);
QPoint bottomRight(std::max(t.x, bbox.bottomRight().x()), std::max(t.y, bbox.bottomRight().y()));
bbox.setBottomRight(bottomRight);
}
painter.setOpacity(1.0);
painter.drawRect(bbox.x() * 32, bbox.y() * 32, bbox.width() * 32, bbox.height() * 32);
}
//show translation
if(selectionMode == 2 && (shift.x() || shift.y()))
{
painter.setOpacity(0.5);
auto newPos = QPoint(obj->getPosition().x, obj->getPosition().y) + shift;
handler->drawObjectAt(painter, obj, newPos.x(), newPos.y());
}
}
redraw();
}
CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y) const
{
if(!map || !map->isInTheMap(int3(x, y, scene->level)))
return nullptr;
auto & objects = handler->getObjects(x, y, scene->level);
//visitable is most important
for(auto & object : objects)
{
if(!object.obj)
continue;
if(object.obj->visitableAt(x, y))
{
return object.obj;
}
}
//if not visitable tile - try to get blocked
for(auto & object : objects)
{
if(!object.obj)
continue;
if(object.obj->blockingAt(x, y))
{
return object.obj;
}
}
//finally, we can take any object
for(auto & object : objects)
{
if(!object.obj)
continue;
if(object.obj->coveringAt(x, y))
{
return object.obj;
}
}
return nullptr;
}
void SelectionObjectsLayer::selectObjects(int x1, int y1, int x2, int y2)
{
if(!map)
return;
if(x1 > x2)
std::swap(x1, x2);
if(y1 > y2)
std::swap(y1, y2);
for(int j = y1; j < y2; ++j)
{
for(int i = x1; i < x2; ++i)
{
for(auto & o : handler->getObjects(i, j, scene->level))
selectObject(o.obj);
}
}
}
void SelectionObjectsLayer::selectObject(CGObjectInstance * obj)
{
selectedObjects.insert(obj);
}
bool SelectionObjectsLayer::isSelected(const CGObjectInstance * obj) const
{
return selectedObjects.count(const_cast<CGObjectInstance*>(obj));
}
std::set<CGObjectInstance*> SelectionObjectsLayer::getSelection() const
{
return selectedObjects;
}
void SelectionObjectsLayer::clear()
{
selectedObjects.clear();
shift.setX(0);
shift.setY(0);
}

130
mapeditor/scenelayer.h Normal file
View File

@ -0,0 +1,130 @@
#ifndef SCENELAYER_H
#define SCENELAYER_H
#include "../lib/int3.h"
class MapScene;
class CGObjectInstance;
class MapController;
class CMap;
class MapHandler;
class AbstractLayer
{
public:
AbstractLayer(MapScene * s);
virtual void update() = 0;
void show(bool show);
void redraw();
void initialize(MapController & controller);
protected:
MapScene * scene;
CMap * map = nullptr;
MapHandler * handler = nullptr;
bool isShown = false;
std::unique_ptr<QPixmap> pixmap;
QPixmap emptyPixmap;
private:
std::unique_ptr<QGraphicsPixmapItem> item;
};
class GridLayer: public AbstractLayer
{
public:
GridLayer(MapScene * s);
void update() override;
};
class PassabilityLayer: public AbstractLayer
{
public:
PassabilityLayer(MapScene * s);
void update() override;
};
class SelectionTerrainLayer: public AbstractLayer
{
public:
SelectionTerrainLayer(MapScene * s);
void update() override;
void draw();
void select(const int3 & tile);
void erase(const int3 & tile);
void clear();
const std::set<int3> & selection() const;
private:
std::set<int3> area, areaAdd, areaErase;
};
class TerrainLayer: public AbstractLayer
{
public:
TerrainLayer(MapScene * s);
void update() override;
void draw(bool onlyDirty = true);
void setDirty(const int3 & tile);
private:
std::set<int3> dirty;
};
class ObjectsLayer: public AbstractLayer
{
public:
ObjectsLayer(MapScene * s);
void update() override;
void draw(bool onlyDirty = true); //TODO: implement dirty
void setDirty(int x, int y);
void setDirty(const CGObjectInstance * object);
private:
std::set<const CGObjectInstance *> dirty;
};
class SelectionObjectsLayer: public AbstractLayer
{
public:
SelectionObjectsLayer(MapScene * s);
void update() override;
void draw();
CGObjectInstance * selectObjectAt(int x, int y) const;
void selectObjects(int x1, int y1, int x2, int y2);
void selectObject(CGObjectInstance *);
bool isSelected(const CGObjectInstance *) const;
std::set<CGObjectInstance*> getSelection() const;
void moveSelection(int x, int y);
void clear();
QPoint shift;
CGObjectInstance * newObject;
int selectionMode = 0; //0 - nothing, 1 - selection, 2 - movement
private:
std::set<CGObjectInstance *> selectedObjects;
};
#endif // SCENELAYER_H

View File

@ -44,7 +44,8 @@ void WindowNewMap::on_cancelButton_clicked()
void generateRandomMap(CMapGenerator & gen, MainWindow * window)
{
window->setMapRaw(gen.generate());
window->controller.setMap(gen.generate());
//window->setMapRaw();
}
void generateEmptyMap(CMapGenOptions & options, MainWindow * window)
@ -60,7 +61,7 @@ void generateEmptyMap(CMapGenOptions & options, MainWindow * window)
map->getEditManager()->getTerrainSelection().selectRange(MapRect(int3(0, 0, 0), options.getWidth(), options.getHeight()));
map->getEditManager()->drawTerrain(Terrain("grass"), &CRandomGenerator::getDefault());
window->setMapRaw(std::move(map));
window->controller.setMap(std::move(map));
}
void WindowNewMap::on_okButtong_clicked()
@ -107,7 +108,7 @@ void WindowNewMap::on_okButtong_clicked()
generateEmptyMap(mapGenOptions, static_cast<MainWindow*>(parent()));
}
static_cast<MainWindow*>(parent())->setMap(true);
static_cast<MainWindow*>(parent())->initializeMap(true);
close();
}