Skip to content

Commit c2cd0df

Browse files
authored
Merge pull request #350 from scratchcpp/comments
Add comment API
2 parents 8f50de6 + 19283ed commit c2cd0df

File tree

21 files changed

+648
-3
lines changed

21 files changed

+648
-3
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ target_sources(scratchcpp
5252
include/scratchcpp/iimageformatfactory.h
5353
include/scratchcpp/rect.h
5454
include/scratchcpp/igraphicseffect.h
55+
include/scratchcpp/comment.h
5556
)
5657

5758
add_library(zip SHARED

include/scratchcpp/block.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class IEngine;
1212
class Target;
1313
class Input;
1414
class Field;
15+
class Comment;
1516
class InputValue;
1617
class BlockPrivate;
1718

@@ -55,6 +56,11 @@ class LIBSCRATCHCPP_EXPORT Block : public Entity
5556

5657
bool topLevel() const;
5758

59+
std::shared_ptr<Comment> comment() const;
60+
std::string commentId() const;
61+
void setComment(std::shared_ptr<Comment> comment);
62+
void setCommentId(const std::string &commentId);
63+
5864
void setEngine(IEngine *newEngine);
5965
IEngine *engine() const;
6066

include/scratchcpp/comment.h

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
#pragma once
4+
5+
#include "entity.h"
6+
7+
namespace libscratchcpp
8+
{
9+
10+
class Block;
11+
class CommentPrivate;
12+
13+
/*! \brief The Comment class represents a comment in the code area. */
14+
class LIBSCRATCHCPP_EXPORT Comment : public Entity
15+
{
16+
public:
17+
Comment(const std::string &id, double x = 0, double y = 0);
18+
Comment(const Comment &) = delete;
19+
20+
const std::string &blockId() const;
21+
void setBlockId(const std::string id);
22+
23+
std::shared_ptr<Block> block() const;
24+
void setBlock(std::shared_ptr<Block> block);
25+
26+
double x() const;
27+
void setX(double x);
28+
29+
double y() const;
30+
void setY(double y);
31+
32+
double width() const;
33+
void setWidth(double width);
34+
35+
double height() const;
36+
void setHeight(double height);
37+
38+
bool minimized() const;
39+
void setMinimized(bool minimized);
40+
41+
const std::string &text() const;
42+
void setText(const std::string &text);
43+
44+
private:
45+
spimpl::unique_impl_ptr<CommentPrivate> impl;
46+
};
47+
48+
} // namespace libscratchcpp

include/scratchcpp/target.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class IEngine;
1414
class Variable;
1515
class List;
1616
class Block;
17+
class Comment;
1718
class Costume;
1819
class Sound;
1920
class TargetPrivate;
@@ -50,6 +51,11 @@ class LIBSCRATCHCPP_EXPORT Target
5051
int findBlock(const std::string &id) const;
5152
std::vector<std::shared_ptr<Block>> greenFlagBlocks() const;
5253

54+
const std::vector<std::shared_ptr<Comment>> &comments() const;
55+
int addComment(std::shared_ptr<Comment> comment);
56+
std::shared_ptr<Comment> commentAt(int index) const;
57+
int findComment(const std::string &id) const;
58+
5359
int costumeIndex() const;
5460
void setCostumeIndex(int newCostumeIndex);
5561

@@ -75,7 +81,7 @@ class LIBSCRATCHCPP_EXPORT Target
7581
void setEngine(IEngine *engine);
7682

7783
protected:
78-
/*! Override this method to set a custom data source for blocks and assets. */
84+
/*! Override this method to set a custom data source for blocks, assets, comments, etc. */
7985
virtual Target *dataSource() const { return nullptr; }
8086

8187
private:

src/engine/internal/engine.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include <scratchcpp/block.h>
1414
#include <scratchcpp/variable.h>
1515
#include <scratchcpp/list.h>
16+
#include <scratchcpp/comment.h>
1617
#include <scratchcpp/costume.h>
1718
#include <scratchcpp/keyevent.h>
1819
#include <cassert>
@@ -84,6 +85,14 @@ void Engine::resolveIds()
8485

8586
block->updateInputMap();
8687
block->updateFieldMap();
88+
89+
auto comment = getComment(block->commentId());
90+
block->setComment(comment);
91+
92+
if (comment) {
93+
comment->setBlock(block);
94+
assert(comment->blockId() == block->id());
95+
}
8796
}
8897
}
8998
}
@@ -1078,6 +1087,21 @@ std::shared_ptr<Broadcast> Engine::getBroadcast(const std::string &id)
10781087
return nullptr;
10791088
}
10801089

1090+
// Returns the comment with the given ID.
1091+
std::shared_ptr<Comment> Engine::getComment(const std::string &id)
1092+
{
1093+
if (id.empty())
1094+
return nullptr;
1095+
1096+
for (auto target : m_targets) {
1097+
int index = target->findComment(id);
1098+
if (index != -1)
1099+
return target->commentAt(index);
1100+
}
1101+
1102+
return nullptr;
1103+
}
1104+
10811105
// Returns the entity with the given ID. \see IEntity
10821106
std::shared_ptr<Entity> Engine::getEntity(const std::string &id)
10831107
{

src/engine/internal/engine.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ class Engine : public IEngine
143143
std::shared_ptr<Variable> getVariable(const std::string &id);
144144
std::shared_ptr<List> getList(const std::string &id);
145145
std::shared_ptr<Broadcast> getBroadcast(const std::string &id);
146+
std::shared_ptr<Comment> getComment(const std::string &id);
146147
std::shared_ptr<Entity> getEntity(const std::string &id);
147148
std::shared_ptr<IBlockSection> blockSection(const std::string &opcode) const;
148149

src/internal/scratch3reader.cpp

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <scratchcpp/variable.h>
99
#include <scratchcpp/list.h>
1010
#include <scratchcpp/costume.h>
11+
#include <scratchcpp/comment.h>
1112
#include <scratchcpp/sound.h>
1213
#include <scratchcpp/stage.h>
1314
#include <scratchcpp/sprite.h>
@@ -188,10 +189,37 @@ bool Scratch3Reader::load()
188189
READER_STEP(step, "target -> block -> shadow");
189190
block->setShadow(blockInfo["shadow"]);
190191

192+
// comment
193+
READER_STEP(step, "target -> block -> comment");
194+
if (!blockInfo["comment"].is_null())
195+
block->setCommentId(blockInfo["comment"]);
196+
191197
target->addBlock(block);
192198
}
193199

194-
// TODO: Add comments
200+
// comments
201+
READER_STEP(step, "target -> comments");
202+
auto comments = jsonTarget["comments"];
203+
for (json::iterator it = comments.begin(); it != comments.end(); ++it) {
204+
auto commentInfo = it.value();
205+
READER_STEP(step, "target -> comment -> { id, x, y }");
206+
auto comment = std::make_shared<Comment>(it.key(), jsonToValue(commentInfo["x"]).toDouble(), jsonToValue(commentInfo["y"]).toDouble());
207+
READER_STEP(step, "target -> comment -> blockId");
208+
209+
if (!commentInfo["blockId"].is_null())
210+
comment->setBlockId(commentInfo["blockId"]);
211+
212+
READER_STEP(step, "target -> comment -> width");
213+
comment->setWidth(jsonToValue(commentInfo["width"]).toDouble());
214+
READER_STEP(step, "target -> comment -> height");
215+
comment->setHeight(jsonToValue(commentInfo["height"]).toDouble());
216+
READER_STEP(step, "target -> comment -> minimized");
217+
comment->setMinimized(commentInfo["minimized"]);
218+
READER_STEP(step, "target -> comment -> text");
219+
comment->setText(commentInfo["text"]);
220+
221+
target->addComment(comment);
222+
}
195223

196224
// costumes
197225
READER_STEP(step, "target -> costumes");

src/scratch/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,7 @@ target_sources(scratchcpp
4848
keyevent.cpp
4949
keyevent_p.cpp
5050
keyevent_p.h
51+
comment.cpp
52+
comment_p.cpp
53+
comment_p.h
5154
)

src/scratch/block.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <scratchcpp/block.h>
44
#include <scratchcpp/input.h>
55
#include <scratchcpp/field.h>
6+
#include <scratchcpp/comment.h>
67

78
#include "block_p.h"
89

@@ -295,6 +296,36 @@ bool Block::topLevel() const
295296
return (impl->parentId == "" && !impl->parent);
296297
}
297298

299+
/*! Returns the comment which is attached to this block. */
300+
std::shared_ptr<Comment> Block::comment() const
301+
{
302+
return impl->comment;
303+
}
304+
305+
/*! Returns the ID of the comment which is attached to this block. */
306+
std::string Block::commentId() const
307+
{
308+
return impl->commentId;
309+
}
310+
311+
/*! Sets the comment which is attached to this block. */
312+
void Block::setComment(std::shared_ptr<Comment> comment)
313+
{
314+
impl->comment = comment;
315+
316+
if (comment)
317+
impl->commentId = comment->id();
318+
else
319+
impl->commentId = "";
320+
}
321+
322+
/*! Sets the ID of the comment which is attached to this block. */
323+
void Block::setCommentId(const std::string &commentId)
324+
{
325+
impl->commentId = commentId;
326+
impl->comment = nullptr;
327+
}
328+
298329
/*! Sets the Engine. */
299330
void Block::setEngine(IEngine *newEngine)
300331
{

src/scratch/block_p.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ class IEngine;
1414
class Target;
1515
class Input;
1616
class Field;
17+
class Comment;
1718

1819
struct BlockPrivate
1920
{
@@ -31,6 +32,8 @@ struct BlockPrivate
3132
std::vector<std::shared_ptr<Field>> fields;
3233
std::unordered_map<int, Field *> fieldMap;
3334
bool shadow = false;
35+
std::string commentId;
36+
std::shared_ptr<Comment> comment = nullptr;
3437
IEngine *engine = nullptr;
3538
Target *target = nullptr;
3639
BlockPrototype mutationPrototype;

0 commit comments

Comments
 (0)