Skip to content

Commit eb46f7d

Browse files
committed
paste added
1 parent 7faf57e commit eb46f7d

File tree

12 files changed

+137
-9
lines changed

12 files changed

+137
-9
lines changed

src/backend/circuit/circuit.cpp

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,28 @@ bool Circuit::tryInsertParsedCircuit(const ParsedCircuit& parsedCircuit, const P
152152
return true;
153153
}
154154

155+
bool Circuit::tryInsertCopiedBlocks(const SharedCopiedBlocks& copiedBlocks, const Position& position) {
156+
Vector totalOffset = Vector(position.x, position.y) + (Position() - copiedBlocks->getMinPosition());
157+
for (const CopiedBlocks::CopiedBlockData& block : copiedBlocks->getCopiedBlocks()) {
158+
if (blockContainer.checkCollision(block.position + totalOffset, block.rotation, block.blockType)) {
159+
return false;
160+
}
161+
}
162+
DifferenceSharedPtr difference = std::make_shared<Difference>();
163+
for (const CopiedBlocks::CopiedBlockData& block : copiedBlocks->getCopiedBlocks()) {
164+
if (!blockContainer.tryInsertBlock(block.position + totalOffset, block.rotation, block.blockType, difference.get())) {
165+
logError("Failed to insert block while inserting block.");
166+
}
167+
}
168+
for (const std::pair<Position, Position>& conn : copiedBlocks->getCopiedConnections()) {
169+
if (!blockContainer.tryCreateConnection(conn.second + totalOffset, conn.first + totalOffset, difference.get())) {
170+
logError("Failed to create connection while inserting block.");
171+
}
172+
}
173+
sendDifference(difference);
174+
return true;
175+
}
176+
155177
bool Circuit::trySetBlockData(const Position& positionOfBlock, block_data_t data) {
156178
DifferenceSharedPtr difference = std::make_shared<Difference>();
157179
bool out = blockContainer.trySetBlockData(positionOfBlock, data, difference.get());

src/backend/circuit/circuit.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "backend/selection.h"
88
#include "parsedCircuit.h"
99
#include "undoSystem.h"
10+
#include "backend/container/copiedBlocks.h"
1011

1112
typedef unsigned int circuit_id_t;
1213
typedef unsigned int circuit_update_count;
@@ -59,6 +60,7 @@ class Circuit {
5960

6061
// Trys to place a parsed circuit at a position
6162
bool tryInsertParsedCircuit(const ParsedCircuit& parsedCircuit, const Position& position);
63+
bool tryInsertCopiedBlocks(const SharedCopiedBlocks& copiedBlocks, const Position& position);
6264

6365
/* ----------- block data ----------- */
6466

src/backend/circuitView/circuitView.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ class CircuitView {
4444
}
4545

4646
inline void paste() {
47-
47+
toolManager.selectTool("paste tool");
4848
}
4949

5050
// --------------- Gettters ---------------
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "pasteTool.h"
2+
#include "backend/backend.h"
3+
4+
void PasteTool::activate() {
5+
CircuitTool::activate();
6+
registerFunction("Tool Primary Activate", std::bind(&PasteTool::place, this, std::placeholders::_1));
7+
}
8+
9+
bool PasteTool::validatePlacement() const {
10+
SharedCopiedBlocks copiedBlocks = circuitView->getBackend()->getClipboard();
11+
if (!copiedBlocks) return false;
12+
13+
Vector totalOffset = Vector(lastPointerPosition.x, lastPointerPosition.y) + (Position() - copiedBlocks->getMinPosition());
14+
15+
for (const CopiedBlocks::CopiedBlockData& block : copiedBlocks->getCopiedBlocks()) {
16+
Position testPos = block.position + totalOffset;
17+
if (circuit->getBlockContainer()->checkCollision(testPos)) {
18+
return false;
19+
}
20+
}
21+
return true;
22+
}
23+
24+
bool PasteTool::place(const Event* event) {
25+
if (!validatePlacement()) { return true; }
26+
27+
SharedCopiedBlocks copiedBlocks = circuitView->getBackend()->getClipboard();
28+
circuit->tryInsertCopiedBlocks(copiedBlocks, lastPointerPosition);
29+
30+
return true;
31+
}
32+
33+
// Preview is only shown for the primary parsed circuit, not the dependencies that will be created in a different circuit
34+
void PasteTool::updateElements() {
35+
if (!elementCreator.isSetup()) return;
36+
elementCreator.clear();
37+
if (!pointerInView) return;
38+
39+
SharedCopiedBlocks copiedBlocks = circuitView->getBackend()->getClipboard();
40+
if (!copiedBlocks) return;
41+
42+
Vector totalOffset = Vector(lastPointerPosition.x, lastPointerPosition.y) + (Position() - copiedBlocks->getMinPosition());
43+
44+
for (const CopiedBlocks::CopiedBlockData& block : copiedBlocks->getCopiedBlocks()) {
45+
elementCreator.addBlockPreview(BlockPreview(block.blockType, block.position + totalOffset, block.rotation));
46+
}
47+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#ifndef pasteTool_h
2+
#define pasteTool_h
3+
4+
#include "../circuitTool.h"
5+
#include "backend/circuit/parsedCircuit.h"
6+
#include "computerAPI/circuits/circuitFileManager.h"
7+
class Backend;
8+
9+
class PasteTool : public CircuitTool {
10+
public:
11+
void activate() override final;
12+
void updateElements() override final;
13+
bool place(const Event* event);
14+
15+
private:
16+
bool validatePlacement() const;
17+
};
18+
19+
#endif /* pasteTool_h */

src/backend/circuitView/tools/other/previewPlacementTool.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
11
#include "previewPlacementTool.h"
2-
#include "backend/backend.h"
3-
#include "backend/circuitView/renderer/elementCreator.h"
42
#include <QMessageBox>
53

64
// Preview is only shown for the primary parsed circuit, not the dependencies that will be created in a different circuit
@@ -41,6 +39,7 @@ bool PreviewPlacementTool::commitPlacement(const Event* event) {
4139

4240
if (!validatePlacement()) {
4341
QMessageBox::warning(nullptr, "Collision Detected", "Cannot place circuit in occupied positions");
42+
logWarning("Collision Detected, Cannot place circuit in occupied positions", "PreviewPlacementTool");
4443
return true;
4544
}
4645
circuit->tryInsertParsedCircuit(*parsedCircuit, lastPointerPosition);

src/backend/circuitView/tools/other/previewPlacementTool.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33

44
#include "../circuitTool.h"
55
#include "backend/circuit/parsedCircuit.h"
6-
#include "computerAPI/circuits/circuitFileManager.h"
7-
class Backend;
86

97
class PreviewPlacementTool : public CircuitTool {
108
public:

src/backend/circuitView/tools/toolManager.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "placement/blockPlacementTool.h"
55
#include "connection/connectionTool.h"
66
#include "other/previewPlacementTool.h"
7+
#include "other/pasteTool.h"
78
#include "other/logicToucher.h"
89
#include "movement/moveTool.h"
910
#include "selection/selectionMakerTool.h"
@@ -52,6 +53,7 @@ void ToolManager::selectTool(std::string toolName) {
5253
else if (toolName == "placement/move") instanceNewtool<MoveTool>(toolName, 0);
5354
else if (toolName == "connection/connection") instanceNewtool<ConnectionTool>(toolName, 0);
5455
else if (toolName == "preview placement tool") instanceNewtool<PreviewPlacementTool>(toolName, 0);
56+
else if (toolName == "paste tool") instanceNewtool<PasteTool>(toolName, 0);
5557
else if (toolName == "interactive/state changer") instanceNewtool<LogicToucher>(toolName, 1);
5658
else if (toolName == "selection/selection maker") instanceNewtool<SelectionMakerTool>(toolName, 0);
5759
else logError("Unknown tool name \"{}\"", "", toolName);

src/backend/container/copiedBlocks.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,19 @@
55
CopiedBlocks::CopiedBlocks(const BlockContainer* blockContainer, SharedSelection selection) {
66
std::unordered_set<Position> positions;
77
std::unordered_set<const Block*> blocksSet;
8+
bool foundPos = false;
89
flattenSelection(selection, positions);
910
for (Position position : positions) {
1011
const Block* block = blockContainer->getBlock(position);
1112
if (!block) continue;
13+
if (foundPos) {
14+
if (minPosition.x > position.x) minPosition.x = position.x;
15+
else if (maxPosition.x > position.x) maxPosition.x = position.x;
16+
if (minPosition.y > position.y) minPosition.y = position.y;
17+
else if (maxPosition.y > position.y) maxPosition.y = position.y;
18+
} else {
19+
minPosition = maxPosition = position;
20+
}
1221
if (blocksSet.contains(block)) continue;
1322
blocksSet.insert(block);
1423
blocks.emplace_back(

src/backend/container/copiedBlocks.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,22 @@ class CopiedBlocks {
99
public:
1010
CopiedBlocks(const BlockContainer* blockContainer, SharedSelection selection);
1111

12-
private:
1312
struct CopiedBlockData {
1413
BlockType blockType;
1514
Position position;
1615
Rotation rotation;
1716
block_data_t data;
1817
};
1918

19+
const std::vector<CopiedBlockData> getCopiedBlocks() const { return blocks; }
20+
const std::vector<std::pair<Position, Position>> getCopiedConnections() const { return connections; }
21+
const Position& getMinPosition() { return minPosition; }
22+
const Position& getMaxPosition() { return maxPosition; }
23+
24+
private:
25+
26+
Position minPosition;
27+
Position maxPosition;
2028
std::vector<CopiedBlockData> blocks;
2129
std::vector<std::pair<Position, Position>> connections;
2230
};

0 commit comments

Comments
 (0)