Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/scratchcpp/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ class LIBSCRATCHCPP_EXPORT Block : public Entity

bool topLevel() const;

int x() const;
void setX(int x);

int y() const;
void setY(int y);

std::shared_ptr<Comment> comment() const;
const std::string &commentId() const;
void setComment(std::shared_ptr<Comment> comment);
Expand Down
14 changes: 14 additions & 0 deletions src/internal/scratch3reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,9 @@ bool Scratch3Reader::load()
reporterInfo->setValueId(jsonToValue(blockInfo[2]).toString());
reporterInfo->setType(static_cast<InputValue::Type>(blockInfo[0]));

block->setX(blockInfo[3]);
block->setY(blockInfo[4]);

target->addBlock(block);
continue;
}
Expand All @@ -108,6 +111,17 @@ bool Scratch3Reader::load()
if (!blockInfo["parent"].is_null())
parentId = blockInfo["parent"];
block->setParentId(parentId);
READER_STEP(step, "target -> block -> parent");
if (!blockInfo["parent"].is_null())
parentId = blockInfo["parent"];
block->setParentId(parentId);

if (block->topLevel()) {
READER_STEP(step, "target -> block -> x");
block->setX(blockInfo["x"]);
READER_STEP(step, "target -> block -> y");
block->setY(blockInfo["y"]);
}

// inputs
READER_STEP(step, "target -> block -> inputs");
Expand Down
30 changes: 30 additions & 0 deletions src/scratch/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,36 @@ bool Block::topLevel() const
return (impl->parentId == "" && !impl->parent);
}

/*! Returns the X-coordinate of the block in the code area (only for top level blocks). */
int Block::x() const
{
return impl->x;
}

/*! Sets the X-coordinate of the block in the code area (only for top level blocks). */
void Block::setX(int x)
{
if (!topLevel())
std::cout << "warning: setting X-coordinate of a block which is not a top level block" << std::endl;

impl->x = x;
}

/*! Returns the Y-coordinate of the block in the code area (only for top level blocks). */
int Block::y() const
{
return impl->y;
}

/*! Sets the Y-coordinate of the block in the code area (only for top level blocks). */
void Block::setY(int y)
{
if (!topLevel())
std::cout << "warning: setting Y-coordinate of a block which is not a top level block" << std::endl;

impl->y = y;
}

/*! Returns the comment which is attached to this block. */
std::shared_ptr<Comment> Block::comment() const
{
Expand Down
2 changes: 2 additions & 0 deletions src/scratch/block_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ struct BlockPrivate
std::vector<std::shared_ptr<Field>> fields;
std::unordered_map<int, Field *> fieldMap;
bool shadow = false;
int x = 0;
int y = 0;
std::string commentId;
std::shared_ptr<Comment> comment = nullptr;
IEngine *engine = nullptr;
Expand Down
21 changes: 20 additions & 1 deletion test/load_project/load_project_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ TEST(LoadProjectTest, LoadTestProject)
ASSERT_EQ(sprite1->name(), "Sprite1");
ASSERT_EQ(sprite1->variables().size(), 1);
ASSERT_EQ(sprite1->lists().size(), 1);
ASSERT_EQ(sprite1->blocks().size(), 18);
ASSERT_EQ(sprite1->blocks().size(), 19);
ASSERT_EQ(sprite1->costumes().size(), 2);
ASSERT_EQ(sprite1->comments().size(), 1);
ASSERT_EQ(sprite1->costumeIndex(), 1);
Expand Down Expand Up @@ -278,6 +278,8 @@ TEST(LoadProjectTest, LoadTestProject)
ASSERT_TRUE(sprite1->greenFlagBlocks()[0]);
ASSERT_FALSE(sprite1->greenFlagBlocks()[0]->isTopLevelReporter());
ASSERT_EQ(sprite1->greenFlagBlocks()[0]->opcode(), "event_whenflagclicked");
ASSERT_EQ(sprite1->greenFlagBlocks()[0]->x(), 0);
ASSERT_EQ(sprite1->greenFlagBlocks()[0]->y(), 0);
auto block = sprite1->greenFlagBlocks()[0]->next();
ASSERT_TRUE(block);
ASSERT_EQ(block->parent(), sprite1->greenFlagBlocks()[0]);
Expand Down Expand Up @@ -343,6 +345,8 @@ TEST(LoadProjectTest, LoadTestProject)
}
}
ASSERT_TRUE(defineBlock);
ASSERT_EQ(defineBlock->x(), 0);
ASSERT_EQ(defineBlock->y(), 384);
ASSERT_INPUT(defineBlock, "custom_block");
auto blockPrototype = GET_INPUT(defineBlock, "custom_block")->valueBlock();
ASSERT_TRUE(blockPrototype);
Expand Down Expand Up @@ -372,6 +376,17 @@ TEST(LoadProjectTest, LoadTestProject)
ASSERT_TRUE(argBlock);
ASSERT_EQ(argBlock->opcode(), "argument_reporter_string_number");

std::shared_ptr<Block> keyPressedBlock = nullptr;
for (auto b : blocks) {
if (b->opcode() == "event_whenkeypressed") {
keyPressedBlock = b;
break;
}
}
ASSERT_TRUE(keyPressedBlock);
ASSERT_EQ(keyPressedBlock->x(), 488);
ASSERT_EQ(keyPressedBlock->y(), 152);

// Balloon1
ASSERT_NE(engine->findTarget("Balloon1"), -1);
Sprite *sprite2 = dynamic_cast<Sprite *>(engine->targetAt(engine->findTarget("Balloon1")));
Expand Down Expand Up @@ -651,6 +666,8 @@ TEST(LoadProjectTest, LoadTopLevelReporterProject)
auto block1 = sprite1->blockAt(0);
ASSERT_TRUE(block1);
ASSERT_TRUE(block1->isTopLevelReporter());
ASSERT_EQ(block1->x(), 335);
ASSERT_EQ(block1->y(), 335);
InputValue *reporterInfo = block1->topLevelReporterInfo();
ASSERT_TRUE(reporterInfo);
ASSERT_EQ(reporterInfo->type(), InputValue::Type::Variable);
Expand All @@ -661,6 +678,8 @@ TEST(LoadProjectTest, LoadTopLevelReporterProject)
auto block2 = sprite1->blockAt(1);
ASSERT_TRUE(block2);
ASSERT_TRUE(block2->isTopLevelReporter());
ASSERT_EQ(block2->x(), 313);
ASSERT_EQ(block2->y(), 435);
reporterInfo = block2->topLevelReporterInfo();
ASSERT_TRUE(reporterInfo);
ASSERT_EQ(reporterInfo->type(), InputValue::Type::List);
Expand Down
Binary file modified test/load_test.sb3
Binary file not shown.
18 changes: 18 additions & 0 deletions test/scratch_classes/block_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,24 @@ TEST_F(BlockTest, TopLevel)
ASSERT_TRUE(block.topLevel());
}

TEST_F(BlockTest, X)
{
Block block("", "");
ASSERT_EQ(block.x(), 0);

block.setX(12);
ASSERT_EQ(block.x(), 12);
}

TEST_F(BlockTest, Y)
{
Block block("", "");
ASSERT_EQ(block.y(), 0);

block.setY(8);
ASSERT_EQ(block.y(), 8);
}

TEST_F(BlockTest, Comment)
{
Block block("", "");
Expand Down