1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-18 17:40:48 +02:00

Show objects preview

This commit is contained in:
nordsoft 2022-09-03 01:04:28 +04:00
parent 8a2864b788
commit c17b1f909d
10 changed files with 384 additions and 43 deletions

View File

@ -622,6 +622,27 @@ void CMap::addNewObject(CGObjectInstance * obj)
obj->afterAddToMap(this);
}
void CMap::moveObject(CGObjectInstance * obj, const int3 & pos)
{
removeBlockVisTiles(obj);
obj->pos = pos;
addBlockVisTiles(obj);
}
void CMap::removeObject(CGObjectInstance * obj)
{
removeBlockVisTiles(obj);
instanceNames.erase(obj->instanceName);
//update indeces
auto iter = std::next(objects.begin(), obj->id.getNum());
iter = objects.erase(iter);
for(int i = obj->id.getNum(); iter != objects.end(); ++i, ++iter)
{
(*iter)->id = ObjectInstanceID(i);
}
}
void CMap::initTerrain()
{
int level = twoLevel ? 2 : 1;

View File

@ -364,6 +364,9 @@ public:
///Use only this method when creating new map object instances
void addNewObject(CGObjectInstance * obj);
void moveObject(CGObjectInstance * obj, const int3 & dst);
void removeObject(CGObjectInstance * obj);
/// Gets object of specified type on requested position
const CGObjectInstance * getObjectiveObjectFrom(int3 pos, Obj::EObj type);

View File

@ -268,6 +268,16 @@ void CMapEditManager::insertObject(CGObjectInstance * obj)
execute(make_unique<CInsertObjectOperation>(map, obj));
}
void CMapEditManager::moveObject(CGObjectInstance * obj, const int3 & pos)
{
execute(make_unique<CMoveObjectOperation>(map, obj, pos));
}
void CMapEditManager::removeObject(CGObjectInstance * obj)
{
execute(make_unique<CRemoveObjectOperation>(map, obj));
}
void CMapEditManager::execute(std::unique_ptr<CMapOperation> && operation)
{
operation->execute();
@ -1072,3 +1082,55 @@ std::string CInsertObjectOperation::getLabel() const
{
return "Insert Object";
}
CMoveObjectOperation::CMoveObjectOperation(CMap * map, CGObjectInstance * obj, const int3 & position)
: CMapOperation(map), obj(obj), pos(position)
{
}
void CMoveObjectOperation::execute()
{
map->moveObject(obj, pos);
}
void CMoveObjectOperation::undo()
{
//TODO
}
void CMoveObjectOperation::redo()
{
execute();
}
std::string CMoveObjectOperation::getLabel() const
{
return "Move Object";
}
CRemoveObjectOperation::CRemoveObjectOperation(CMap * map, CGObjectInstance * obj)
: CMapOperation(map), obj(obj)
{
}
void CRemoveObjectOperation::execute()
{
map->removeObject(obj);
}
void CRemoveObjectOperation::undo()
{
//TODO
}
void CRemoveObjectOperation::redo()
{
execute();
}
std::string CRemoveObjectOperation::getLabel() const
{
return "Remove Object";
}

View File

@ -178,6 +178,8 @@ public:
void drawRiver(const std::string & riverType, CRandomGenerator * gen = nullptr);
void insertObject(CGObjectInstance * obj);
void moveObject(CGObjectInstance * obj, const int3 & pos);
void removeObject(CGObjectInstance * obj);
CTerrainSelection & getTerrainSelection();
CObjectSelection & getObjectSelection();
@ -418,3 +420,34 @@ public:
private:
CGObjectInstance * obj;
};
/// The CMoveObjectOperation class moves object to another position
class CMoveObjectOperation : public CMapOperation
{
public:
CMoveObjectOperation(CMap * map, CGObjectInstance * obj, const int3 & position);
void execute() override;
void undo() override;
void redo() override;
std::string getLabel() const override;
private:
CGObjectInstance * obj;
int3 pos;
};
/// The CRemoveObjectOperation class removes object from the map
class CRemoveObjectOperation : public CMapOperation
{
public:
CRemoveObjectOperation(CMap * map, CGObjectInstance * obj);
void execute() override;
void undo() override;
void redo() override;
std::string getLabel() const override;
private:
CGObjectInstance * obj;
};

View File

@ -37,7 +37,8 @@ void init()
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
ui(new Ui::MainWindow),
objPreview(128, 128)
{
ui->setupUi(this);
@ -99,6 +100,9 @@ MainWindow::MainWindow(QWidget *parent) :
sceneMini = new QGraphicsScene(this);
ui->minimapView->setScene(sceneMini);
scenePreview = new QGraphicsScene(this);
ui->objectPreview->setScene(scenePreview);
scenes[0]->addPixmap(QPixmap(QString::fromStdString(resPath.native())));
//loading objects
@ -147,6 +151,11 @@ MapHandler * MainWindow::getMapHandler()
return mapHandler.get();
}
void MainWindow::resetMapHandler()
{
mapHandler.reset(new MapHandler(map.get()));
}
void MainWindow::setMapRaw(std::unique_ptr<CMap> cmap)
{
map = std::move(cmap);
@ -285,13 +294,42 @@ void MainWindow::terrainButtonClicked(Terrain terrain)
void MainWindow::loadObjectsTree()
{
//adding terrains
for(auto & terrain : Terrain::Manager::terrains())
{
QPushButton *b = new QPushButton(QString::fromStdString(terrain));
ui->terrainLayout->addWidget(b);
connect(b, &QPushButton::clicked, this, [this, terrain]{ terrainButtonClicked(terrain); });
}
//add spacer to keep terrain button on the top
ui->terrainLayout->addItem(new QSpacerItem(20, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
//model
objectsModel.setHorizontalHeaderLabels(QStringList() << QStringLiteral("Type"));
//adding towns
auto * itemGroup = new QStandardItem("TOWNS");
for(auto secondaryID : VLC->objtypeh->knownSubObjects(Obj::TOWN))
{
auto factory = VLC->objtypeh->getHandlerFor(Obj::TOWN, secondaryID);
auto * itemType = new QStandardItem(QString::fromStdString(factory->subTypeName));
for(int templateId = 0; templateId < factory->getTemplates().size(); ++templateId)
{
auto templ = factory->getTemplates()[templateId];
auto * item = new QStandardItem(QString::fromStdString(templ.stringID));
QJsonObject data{{"id", QJsonValue(Obj::TOWN)},
{"subid", QJsonValue(secondaryID)},
{"animationEditor", QString::fromStdString(templ.editorAnimationFile)},
{"animation", QString::fromStdString(templ.animationFile)}};
item->setData(data);
itemType->appendRow(item);
}
itemGroup->appendRow(itemType);
}
objectsModel.appendRow(itemGroup);
/*
createHandler(bth, "Bonus type", pomtime);
createHandler(generaltexth, "General text", pomtime);
@ -309,16 +347,14 @@ void MainWindow::loadObjectsTree()
createHandler(battlefieldsHandler, "Battlefields", pomtime);
createHandler(obstacleHandler, "Obstacles", pomtime);*/
std::map<std::string, std::vector<std::string>> identifiers;
for(auto primaryID : VLC->objtypeh->knownObjects())
//for(auto primaryID : VLC->objtypeh->knownObjects())
{
//QList<QStandardItem*> objTypes;
for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
//for(auto secondaryID : VLC->objtypeh->knownSubObjects(primaryID))
{
//QList<QStandardItem*> objSubTypes;
auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
//auto handler = VLC->objtypeh->getHandlerFor(primaryID, secondaryID);
/*if(handler->isStaticObject())
{
@ -328,22 +364,14 @@ void MainWindow::loadObjectsTree()
}
}*/
identifiers[handler->typeName].push_back(handler->subTypeName);
//identifiers[handler->typeName].push_back(handler->subTypeName);
}
}
objectsModel.setHorizontalHeaderLabels(QStringList() << QStringLiteral("Type"));
QList<QStandardItem*> objTypes;
for(auto & el1 : identifiers)
{
auto * objTypei = new QStandardItem(QString::fromStdString(el1.first));
for(auto & el2 : el1.second)
{
objTypei->appendRow(new QStandardItem(QString::fromStdString(el2)));
}
objectsModel.appendRow(objTypei);
}
ui->treeView->setModel(&objectsModel);
ui->treeView->setSelectionBehavior(QAbstractItemView::SelectItems);
ui->treeView->setSelectionMode(QAbstractItemView::SingleSelection);
connect(ui->treeView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(treeViewSelected(const QModelIndex &, const QModelIndex &)));
}
void MainWindow::on_actionLevel_triggered()
@ -372,6 +400,8 @@ void MainWindow::on_actionGrid_triggered(bool checked)
scenes[0]->gridView.show(checked);
scenes[1]->gridView.show(checked);
}
auto idx = ui->treeView->selectionModel()->currentIndex();
}
@ -412,3 +442,50 @@ void MainWindow::on_toolArea_clicked(bool checked)
}
}
void MainWindow::on_toolErase_clicked()
{
if(map && scenes[mapLevel])
{
scenes[mapLevel]->selectionObjectsView.deleteSelection();
resetMapHandler();
scenes[mapLevel]->updateViews();
}
}
void MainWindow::treeViewSelected(const QModelIndex & index, const QModelIndex & deselected)
{
objPreview.fill(QColor(255, 255, 255));
auto * item = objectsModel.itemFromIndex(index);
if(item)
{
auto data = item->data().toJsonObject();
if(!data.empty())
{
auto animfile = data["animationEditor"];
if(animfile != QJsonValue::Undefined)
{
if(animfile.toString().isEmpty())
animfile = data["animation"];
QPainter painter(&objPreview);
Animation animation(animfile.toString().toStdString());
animation.preload();
auto picture = animation.getImage(0);
if(picture && picture->width() && picture->height())
{
qreal xscale = qreal(128) / qreal(picture->width()), yscale = qreal(128) / qreal(picture->height());
qreal scale = std::min(xscale, yscale);
painter.scale(scale, scale);
painter.drawImage(QPoint(0, 0), *picture);
}
}
}
}
scenePreview->clear();
scenePreview->addPixmap(objPreview);
}

View File

@ -30,6 +30,7 @@ public:
CMap * getMap();
MapHandler * getMapHandler();
void resetMapHandler();
void loadObjectsTree();
@ -58,13 +59,21 @@ private slots:
void terrainButtonClicked(Terrain terrain);
void on_toolErase_clicked();
public slots:
void treeViewSelected(const QModelIndex &selected, const QModelIndex &deselected);
private:
Ui::MainWindow *ui;
std::unique_ptr<MapHandler> mapHandler;
std::array<MapScene *, 2> scenes;
QGraphicsScene * sceneMini;
QGraphicsScene * scenePreview;
QPixmap minimap;
QPixmap objPreview;
std::unique_ptr<CMap> map;
QString filename;

View File

@ -15,6 +15,18 @@
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>2</number>
</property>
<property name="topMargin">
<number>2</number>
</property>
<property name="rightMargin">
<number>2</number>
</property>
<property name="bottomMargin">
<number>2</number>
</property>
<item row="0" column="0">
<widget class="MapView" name="mapView">
<property name="sizePolicy">
@ -83,14 +95,14 @@
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
<width>192</width>
<height>214</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>524287</width>
<height>524287</height>
<width>192</width>
<height>214</height>
</size>
</property>
<attribute name="dockWidgetArea">
@ -104,6 +116,18 @@
</size>
</property>
<layout class="QVBoxLayout" name="verticalLayout_6">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QGraphicsView" name="minimapView">
<property name="sizePolicy">
@ -137,20 +161,20 @@
</widget>
<widget class="QDockWidget" name="dockWidget_3">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Minimum" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>292</width>
<width>192</width>
<height>183</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>524287</width>
<width>192</width>
<height>524287</height>
</size>
</property>
@ -165,6 +189,18 @@
</sizepolicy>
</property>
<layout class="QVBoxLayout" name="verticalLayout_7">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="sizePolicy">
@ -200,7 +236,14 @@
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="terrainFilterCombo"/>
<widget class="QComboBox" name="terrainFilterCombo">
<property name="sizePolicy">
<sizepolicy hsizetype="Minimum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item>
<widget class="QTreeView" name="treeView">
@ -210,6 +253,15 @@
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="editTriggers">
<set>QAbstractItemView::NoEditTriggers</set>
</property>
<property name="selectionBehavior">
<enum>QAbstractItemView::SelectItems</enum>
</property>
<property name="headerHidden">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
@ -222,15 +274,15 @@
<widget class="QStatusBar" name="statusbar"/>
<widget class="QDockWidget" name="dockWidget">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<sizepolicy hsizetype="Preferred" vsizetype="Minimum">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>118</width>
<height>372</height>
<width>128</width>
<height>496</height>
</size>
</property>
<attribute name="dockWidgetArea">
@ -251,7 +303,7 @@
</property>
<property name="maximumSize">
<size>
<width>118</width>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
@ -271,11 +323,17 @@
<item>
<widget class="QGroupBox" name="groupBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="title">
<string>Brush</string>
</property>
@ -313,6 +371,9 @@
</item>
<item row="0" column="1">
<widget class="QPushButton" name="toolBrush2">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -344,6 +405,9 @@
</item>
<item row="1" column="0">
<widget class="QPushButton" name="toolBrush4">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -406,6 +470,9 @@
</item>
<item row="2" column="0">
<widget class="QPushButton" name="toolLasso">
<property name="enabled">
<bool>false</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
@ -472,21 +539,27 @@
<item>
<widget class="QToolBox" name="toolBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>16777215</width>
<height>16777215</height>
</size>
</property>
<property name="currentIndex">
<number>1</number>
<number>0</number>
</property>
<widget class="QWidget" name="page3">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>118</width>
<height>395</height>
<width>128</width>
<height>271</height>
</rect>
</property>
<property name="sizePolicy">
@ -521,8 +594,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>118</width>
<height>395</height>
<width>128</width>
<height>271</height>
</rect>
</property>
<property name="sizePolicy">
@ -536,6 +609,14 @@
</attribute>
</widget>
<widget class="QWidget" name="riverPage">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>128</width>
<height>271</height>
</rect>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Preferred">
<horstretch>0</horstretch>
@ -548,6 +629,22 @@
</widget>
</widget>
</item>
<item>
<widget class="QGraphicsView" name="objectPreview">
<property name="minimumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>128</width>
<height>128</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</widget>

View File

@ -427,7 +427,7 @@ void MapHandler::drawObjectAt(QPainter & painter, const CGObjectInstance * obj,
auto objData = findObjectBitmap(obj, animationFrame);
if (objData.objBitmap)
{
painter.drawImage(QPoint((x - obj->getWidth()) * 32, (y - obj->getHeight()) * 32), *objData.objBitmap);
painter.drawImage(QPoint((x + 1) * 32 - objData.objBitmap->width(), (y + 1) * 32 - objData.objBitmap->height()), *objData.objBitmap);
//drawObject(targetSurf, objData.objBitmap, &srcRect, objData.isMoving);
if (objData.flagBitmap)

View File

@ -3,6 +3,8 @@
#include "mainwindow.h"
#include <QGraphicsSceneMouseEvent>
#include "../lib/mapping/CMapEditManager.h"
MapView::MapView(QWidget *parent):
QGraphicsView(parent),
selectionTool(MapView::SelectionTool::None)
@ -120,8 +122,17 @@ void MapView::mouseReleaseEvent(QMouseEvent *event)
switch(selectionTool)
{
case MapView::SelectionTool::None:
sc->selectionObjectsView.shift = QPoint(0, 0);
sc->selectionObjectsView.draw();
//switch position
if(sc->selectionObjectsView.applyShift())
{
main->resetMapHandler();
sc->updateViews();
}
else
{
sc->selectionObjectsView.shift = QPoint(0, 0);
sc->selectionObjectsView.draw();
}
break;
}
}
@ -489,6 +500,7 @@ void SelectionObjectsView::update()
return;
selectedObjects.clear();
shift = QPoint();
pixmap.reset(new QPixmap(map->width * 32, map->height * 32));
//pixmap->fill(QColor(0, 0, 0, 0));
@ -548,7 +560,7 @@ CGObjectInstance * SelectionObjectsView::selectObjectAt(int x, int y)
if(object.obj->visitableAt(x, y))
{
selectedObjects.insert(objects.back().obj);
selectedObjects.insert(object.obj);
return object.obj;
}
}
@ -561,7 +573,7 @@ CGObjectInstance * SelectionObjectsView::selectObjectAt(int x, int y)
if(object.obj->blockingAt(x, y))
{
selectedObjects.insert(objects.back().obj);
selectedObjects.insert(object.obj);
return object.obj;
}
}
@ -574,7 +586,7 @@ CGObjectInstance * SelectionObjectsView::selectObjectAt(int x, int y)
if(object.obj->coveringAt(x, y))
{
selectedObjects.insert(objects.back().obj);
selectedObjects.insert(object.obj);
return object.obj;
}
}
@ -582,6 +594,30 @@ CGObjectInstance * SelectionObjectsView::selectObjectAt(int x, int y)
return nullptr;
}
bool SelectionObjectsView::applyShift()
{
if(shift.x() || shift.y())
{
for(auto * obj : selectedObjects)
{
int3 pos = obj->pos;
pos.x += shift.x(); pos.y += shift.y();
main->getMap()->getEditManager()->moveObject(obj, pos);
}
return true;
}
return false;
}
void SelectionObjectsView::deleteSelection()
{
for(auto * obj : selectedObjects)
{
main->getMap()->getEditManager()->removeObject(obj);
}
clear();
}
std::set<CGObjectInstance *> SelectionObjectsView::selectObjects(int x1, int y1, int x2, int y2)
{
std::set<CGObjectInstance *> result;

View File

@ -139,6 +139,9 @@ public:
void moveSelection(int x, int y);
void clear();
bool applyShift();
void deleteSelection();
QPoint shift;
private: