Skip to content

Commit 8a33224

Browse files
authored
Merge pull request #565 from scratchcpp/block_pos
Load coordinates of top level blocks
2 parents 319055d + 30f7819 commit 8a33224

File tree

7 files changed

+90
-1
lines changed

7 files changed

+90
-1
lines changed

include/scratchcpp/block.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ class LIBSCRATCHCPP_EXPORT Block : public Entity
5656

5757
bool topLevel() const;
5858

59+
int x() const;
60+
void setX(int x);
61+
62+
int y() const;
63+
void setY(int y);
64+
5965
std::shared_ptr<Comment> comment() const;
6066
const std::string &commentId() const;
6167
void setComment(std::shared_ptr<Comment> comment);

src/internal/scratch3reader.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,9 @@ bool Scratch3Reader::load()
9292
reporterInfo->setValueId(jsonToValue(blockInfo[2]).toString());
9393
reporterInfo->setType(static_cast<InputValue::Type>(blockInfo[0]));
9494

95+
block->setX(blockInfo[3]);
96+
block->setY(blockInfo[4]);
97+
9598
target->addBlock(block);
9699
continue;
97100
}
@@ -108,6 +111,17 @@ bool Scratch3Reader::load()
108111
if (!blockInfo["parent"].is_null())
109112
parentId = blockInfo["parent"];
110113
block->setParentId(parentId);
114+
READER_STEP(step, "target -> block -> parent");
115+
if (!blockInfo["parent"].is_null())
116+
parentId = blockInfo["parent"];
117+
block->setParentId(parentId);
118+
119+
if (block->topLevel()) {
120+
READER_STEP(step, "target -> block -> x");
121+
block->setX(blockInfo["x"]);
122+
READER_STEP(step, "target -> block -> y");
123+
block->setY(blockInfo["y"]);
124+
}
111125

112126
// inputs
113127
READER_STEP(step, "target -> block -> inputs");

src/scratch/block.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,36 @@ bool Block::topLevel() const
313313
return (impl->parentId == "" && !impl->parent);
314314
}
315315

316+
/*! Returns the X-coordinate of the block in the code area (only for top level blocks). */
317+
int Block::x() const
318+
{
319+
return impl->x;
320+
}
321+
322+
/*! Sets the X-coordinate of the block in the code area (only for top level blocks). */
323+
void Block::setX(int x)
324+
{
325+
if (!topLevel())
326+
std::cout << "warning: setting X-coordinate of a block which is not a top level block" << std::endl;
327+
328+
impl->x = x;
329+
}
330+
331+
/*! Returns the Y-coordinate of the block in the code area (only for top level blocks). */
332+
int Block::y() const
333+
{
334+
return impl->y;
335+
}
336+
337+
/*! Sets the Y-coordinate of the block in the code area (only for top level blocks). */
338+
void Block::setY(int y)
339+
{
340+
if (!topLevel())
341+
std::cout << "warning: setting Y-coordinate of a block which is not a top level block" << std::endl;
342+
343+
impl->y = y;
344+
}
345+
316346
/*! Returns the comment which is attached to this block. */
317347
std::shared_ptr<Comment> Block::comment() const
318348
{

src/scratch/block_p.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ struct BlockPrivate
3333
std::vector<std::shared_ptr<Field>> fields;
3434
std::unordered_map<int, Field *> fieldMap;
3535
bool shadow = false;
36+
int x = 0;
37+
int y = 0;
3638
std::string commentId;
3739
std::shared_ptr<Comment> comment = nullptr;
3840
IEngine *engine = nullptr;

test/load_project/load_project_test.cpp

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ TEST(LoadProjectTest, LoadTestProject)
228228
ASSERT_EQ(sprite1->name(), "Sprite1");
229229
ASSERT_EQ(sprite1->variables().size(), 1);
230230
ASSERT_EQ(sprite1->lists().size(), 1);
231-
ASSERT_EQ(sprite1->blocks().size(), 18);
231+
ASSERT_EQ(sprite1->blocks().size(), 19);
232232
ASSERT_EQ(sprite1->costumes().size(), 2);
233233
ASSERT_EQ(sprite1->comments().size(), 1);
234234
ASSERT_EQ(sprite1->costumeIndex(), 1);
@@ -278,6 +278,8 @@ TEST(LoadProjectTest, LoadTestProject)
278278
ASSERT_TRUE(sprite1->greenFlagBlocks()[0]);
279279
ASSERT_FALSE(sprite1->greenFlagBlocks()[0]->isTopLevelReporter());
280280
ASSERT_EQ(sprite1->greenFlagBlocks()[0]->opcode(), "event_whenflagclicked");
281+
ASSERT_EQ(sprite1->greenFlagBlocks()[0]->x(), 0);
282+
ASSERT_EQ(sprite1->greenFlagBlocks()[0]->y(), 0);
281283
auto block = sprite1->greenFlagBlocks()[0]->next();
282284
ASSERT_TRUE(block);
283285
ASSERT_EQ(block->parent(), sprite1->greenFlagBlocks()[0]);
@@ -343,6 +345,8 @@ TEST(LoadProjectTest, LoadTestProject)
343345
}
344346
}
345347
ASSERT_TRUE(defineBlock);
348+
ASSERT_EQ(defineBlock->x(), 0);
349+
ASSERT_EQ(defineBlock->y(), 384);
346350
ASSERT_INPUT(defineBlock, "custom_block");
347351
auto blockPrototype = GET_INPUT(defineBlock, "custom_block")->valueBlock();
348352
ASSERT_TRUE(blockPrototype);
@@ -372,6 +376,17 @@ TEST(LoadProjectTest, LoadTestProject)
372376
ASSERT_TRUE(argBlock);
373377
ASSERT_EQ(argBlock->opcode(), "argument_reporter_string_number");
374378

379+
std::shared_ptr<Block> keyPressedBlock = nullptr;
380+
for (auto b : blocks) {
381+
if (b->opcode() == "event_whenkeypressed") {
382+
keyPressedBlock = b;
383+
break;
384+
}
385+
}
386+
ASSERT_TRUE(keyPressedBlock);
387+
ASSERT_EQ(keyPressedBlock->x(), 488);
388+
ASSERT_EQ(keyPressedBlock->y(), 152);
389+
375390
// Balloon1
376391
ASSERT_NE(engine->findTarget("Balloon1"), -1);
377392
Sprite *sprite2 = dynamic_cast<Sprite *>(engine->targetAt(engine->findTarget("Balloon1")));
@@ -651,6 +666,8 @@ TEST(LoadProjectTest, LoadTopLevelReporterProject)
651666
auto block1 = sprite1->blockAt(0);
652667
ASSERT_TRUE(block1);
653668
ASSERT_TRUE(block1->isTopLevelReporter());
669+
ASSERT_EQ(block1->x(), 335);
670+
ASSERT_EQ(block1->y(), 335);
654671
InputValue *reporterInfo = block1->topLevelReporterInfo();
655672
ASSERT_TRUE(reporterInfo);
656673
ASSERT_EQ(reporterInfo->type(), InputValue::Type::Variable);
@@ -661,6 +678,8 @@ TEST(LoadProjectTest, LoadTopLevelReporterProject)
661678
auto block2 = sprite1->blockAt(1);
662679
ASSERT_TRUE(block2);
663680
ASSERT_TRUE(block2->isTopLevelReporter());
681+
ASSERT_EQ(block2->x(), 313);
682+
ASSERT_EQ(block2->y(), 435);
664683
reporterInfo = block2->topLevelReporterInfo();
665684
ASSERT_TRUE(reporterInfo);
666685
ASSERT_EQ(reporterInfo->type(), InputValue::Type::List);

test/load_test.sb3

111 Bytes
Binary file not shown.

test/scratch_classes/block_test.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,24 @@ TEST_F(BlockTest, TopLevel)
194194
ASSERT_TRUE(block.topLevel());
195195
}
196196

197+
TEST_F(BlockTest, X)
198+
{
199+
Block block("", "");
200+
ASSERT_EQ(block.x(), 0);
201+
202+
block.setX(12);
203+
ASSERT_EQ(block.x(), 12);
204+
}
205+
206+
TEST_F(BlockTest, Y)
207+
{
208+
Block block("", "");
209+
ASSERT_EQ(block.y(), 0);
210+
211+
block.setY(8);
212+
ASSERT_EQ(block.y(), 8);
213+
}
214+
197215
TEST_F(BlockTest, Comment)
198216
{
199217
Block block("", "");

0 commit comments

Comments
 (0)