mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-18 03:21:27 +02:00
Refactoring
This commit is contained in:
parent
28f0abd545
commit
eb501f2222
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
199
mapeditor/mapcontroller.cpp
Normal 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
47
mapeditor/mapcontroller.h
Normal 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
|
@ -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();
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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
493
mapeditor/scenelayer.cpp
Normal 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
130
mapeditor/scenelayer.h
Normal 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
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user