1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Implemented cut copy paste

This commit is contained in:
nordsoft 2022-12-05 01:32:50 +04:00
parent 2e4b4fbebf
commit aa120fa69f
9 changed files with 99 additions and 9 deletions

View File

@ -67,7 +67,8 @@ void Initializer::initialize(CGCreature * o)
if(!o) return; if(!o) return;
o->character = CGCreature::Character::HOSTILE; o->character = CGCreature::Character::HOSTILE;
o->putStack(SlotID(0), new CStackInstance(CreatureID(o->subID), 0, false)); if(!o->hasStackAtSlot(SlotID(0)))
o->putStack(SlotID(0), new CStackInstance(CreatureID(o->subID), 0, false));
} }
void Initializer::initialize(CGDwelling * o) void Initializer::initialize(CGDwelling * o)

View File

@ -1126,3 +1126,31 @@ void MainWindow::on_actionRecreate_obstacles_triggered()
} }
void MainWindow::on_actionCut_triggered()
{
if(controller.map())
{
controller.copyToClipboard(mapLevel);
controller.commitObjectErase(mapLevel);
}
}
void MainWindow::on_actionCopy_triggered()
{
if(controller.map())
{
controller.copyToClipboard(mapLevel);
}
}
void MainWindow::on_actionPaste_triggered()
{
if(controller.map())
{
controller.pasteFromClipboard(mapLevel);
}
}

View File

@ -98,6 +98,12 @@ private slots:
void switchDefaultPlayer(const PlayerColor &); void switchDefaultPlayer(const PlayerColor &);
void on_actionCut_triggered();
void on_actionCopy_triggered();
void on_actionPaste_triggered();
public slots: public slots:
void treeViewSelected(const QModelIndex &selected, const QModelIndex &deselected); void treeViewSelected(const QModelIndex &selected, const QModelIndex &deselected);

View File

@ -79,6 +79,9 @@
</property> </property>
<addaction name="actionUndo"/> <addaction name="actionUndo"/>
<addaction name="actionRedo"/> <addaction name="actionRedo"/>
<addaction name="actionCut"/>
<addaction name="actionCopy"/>
<addaction name="actionPaste"/>
<addaction name="actionErase"/> <addaction name="actionErase"/>
</widget> </widget>
<widget class="QMenu" name="menuView"> <widget class="QMenu" name="menuView">

View File

@ -20,6 +20,7 @@
#include "../lib/CSkillHandler.h" #include "../lib/CSkillHandler.h"
#include "../lib/spells/CSpellHandler.h" #include "../lib/spells/CSpellHandler.h"
#include "../lib/CHeroHandler.h" #include "../lib/CHeroHandler.h"
#include "../lib/serializer/CMemorySerializer.h"
#include "mapview.h" #include "mapview.h"
#include "scenelayer.h" #include "scenelayer.h"
#include "maphandler.h" #include "maphandler.h"
@ -323,6 +324,48 @@ void MapController::commitObjectErase(int level)
main->mapChanged(); main->mapChanged();
} }
void MapController::copyToClipboard(int level)
{
_clipboard.clear();
_clipboardShiftIndex = 0;
auto selectedObjects = _scenes[level]->selectionObjectsView.getSelection();
for(auto * obj : selectedObjects)
{
assert(obj->pos.z == level);
_clipboard.push_back(CMemorySerializer::deepCopy(*obj));
}
}
void MapController::pasteFromClipboard(int level)
{
_scenes[level]->selectionObjectsView.clear();
auto shift = int3::getDirs()[_clipboardShiftIndex++];
if(_clipboardShiftIndex == int3::getDirs().size())
_clipboardShiftIndex = 0;
for(auto & objuptr : _clipboard)
{
auto * obj = CMemorySerializer::deepCopy(*objuptr).release();
auto newpos = objuptr->pos + shift;
if(_map->isInTheMap(newpos))
obj->pos = newpos;
obj->pos.z = level;
Initializer init(obj, defaultPlayer);
_map->getEditManager()->insertObject(obj);
_scenes[level]->selectionObjectsView.selectObject(obj);
_mapHandler->invalidate(obj);
}
_scenes[level]->objectsView.draw();
_scenes[level]->passabilityView.update();
_scenes[level]->selectionObjectsView.draw();
_miniscenes[level]->updateViews();
main->mapChanged();
}
bool MapController::discardObject(int level) const bool MapController::discardObject(int level) const
{ {
_scenes[level]->selectionObjectsView.clear(); _scenes[level]->selectionObjectsView.clear();

View File

@ -49,6 +49,9 @@ public:
void commitObjectCreate(int level); void commitObjectCreate(int level);
void commitObjectChange(int level); void commitObjectChange(int level);
void copyToClipboard(int level);
void pasteFromClipboard(int level);
bool discardObject(int level) const; bool discardObject(int level) const;
void createObject(int level, CGObjectInstance * obj) const; void createObject(int level, CGObjectInstance * obj) const;
bool canPlaceObject(int level, CGObjectInstance * obj, QString & error) const; bool canPlaceObject(int level, CGObjectInstance * obj, QString & error) const;
@ -64,6 +67,8 @@ private:
MainWindow * main; MainWindow * main;
mutable std::array<std::unique_ptr<MapScene>, 2> _scenes; mutable std::array<std::unique_ptr<MapScene>, 2> _scenes;
mutable std::array<std::unique_ptr<MinimapScene>, 2> _miniscenes; mutable std::array<std::unique_ptr<MinimapScene>, 2> _miniscenes;
std::vector<std::unique_ptr<CGObjectInstance>> _clipboard;
int _clipboardShiftIndex = 0;
void connectScenes(); void connectScenes();
}; };

View File

@ -270,6 +270,7 @@ void MapView::mousePressEvent(QMouseEvent *event)
if(event->button() == Qt::LeftButton) if(event->button() == Qt::LeftButton)
{ {
auto * obj = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y); auto * obj = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y);
auto * obj2 = sc->selectionObjectsView.selectObjectAt(tileStart.x, tileStart.y, obj);
if(obj) if(obj)
{ {
if(sc->selectionObjectsView.isSelected(obj)) if(sc->selectionObjectsView.isSelected(obj))
@ -284,10 +285,13 @@ void MapView::mousePressEvent(QMouseEvent *event)
} }
else else
{ {
if(!(qApp->keyboardModifiers() & Qt::ControlModifier)) if(!obj2 || !sc->selectionObjectsView.isSelected(obj2))
sc->selectionObjectsView.clear(); {
if(!(qApp->keyboardModifiers() & Qt::ControlModifier))
sc->selectionObjectsView.clear();
sc->selectionObjectsView.selectObject(obj);
}
sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT; sc->selectionObjectsView.selectionMode = SelectionObjectsLayer::MOVEMENT;
sc->selectionObjectsView.selectObject(obj);
} }
} }
else else

View File

@ -399,7 +399,7 @@ void SelectionObjectsLayer::draw()
redraw(); redraw();
} }
CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y) const CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y, const CGObjectInstance * ignore) const
{ {
if(!map || !map->isInTheMap(int3(x, y, scene->level))) if(!map || !map->isInTheMap(int3(x, y, scene->level)))
return nullptr; return nullptr;
@ -409,7 +409,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y) const
//visitable is most important //visitable is most important
for(auto & object : objects) for(auto & object : objects)
{ {
if(!object.obj) if(!object.obj || object.obj == ignore)
continue; continue;
if(object.obj->visitableAt(x, y)) if(object.obj->visitableAt(x, y))
@ -421,7 +421,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y) const
//if not visitable tile - try to get blocked //if not visitable tile - try to get blocked
for(auto & object : objects) for(auto & object : objects)
{ {
if(!object.obj) if(!object.obj || object.obj == ignore)
continue; continue;
if(object.obj->blockingAt(x, y)) if(object.obj->blockingAt(x, y))
@ -433,7 +433,7 @@ CGObjectInstance * SelectionObjectsLayer::selectObjectAt(int x, int y) const
//finally, we can take any object //finally, we can take any object
for(auto & object : objects) for(auto & object : objects)
{ {
if(!object.obj) if(!object.obj || object.obj == ignore)
continue; continue;
if(object.obj->coveringAt(x, y)) if(object.obj->coveringAt(x, y))

View File

@ -138,7 +138,7 @@ public:
void draw(); void draw();
CGObjectInstance * selectObjectAt(int x, int y) const; CGObjectInstance * selectObjectAt(int x, int y, const CGObjectInstance * ignore = nullptr) const;
void selectObjects(int x1, int y1, int x2, int y2); void selectObjects(int x1, int y1, int x2, int y2);
void selectObject(CGObjectInstance *, bool inform = true); void selectObject(CGObjectInstance *, bool inform = true);
void deselectObject(CGObjectInstance *); void deselectObject(CGObjectInstance *);