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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ target_sources(scratchcpp
include/scratchcpp/iimageformatfactory.h
include/scratchcpp/rect.h
include/scratchcpp/igraphicseffect.h
include/scratchcpp/comment.h
)

add_library(zip SHARED
Expand Down
6 changes: 6 additions & 0 deletions include/scratchcpp/block.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class IEngine;
class Target;
class Input;
class Field;
class Comment;
class InputValue;
class BlockPrivate;

Expand Down Expand Up @@ -55,6 +56,11 @@ class LIBSCRATCHCPP_EXPORT Block : public Entity

bool topLevel() const;

std::shared_ptr<Comment> comment() const;
std::string commentId() const;
void setComment(std::shared_ptr<Comment> comment);
void setCommentId(const std::string &commentId);

void setEngine(IEngine *newEngine);
IEngine *engine() const;

Expand Down
48 changes: 48 additions & 0 deletions include/scratchcpp/comment.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// SPDX-License-Identifier: LGPL-3.0-or-later

#pragma once

#include "entity.h"

namespace libscratchcpp
{

class Block;
class CommentPrivate;

/*! \brief The Comment class represents a comment in the code area. */
class LIBSCRATCHCPP_EXPORT Comment : public Entity
{
public:
Comment(const std::string &id, double x = 0, double y = 0);
Comment(const Comment &) = delete;

const std::string &blockId() const;
void setBlockId(const std::string id);

std::shared_ptr<Block> block() const;
void setBlock(std::shared_ptr<Block> block);

double x() const;
void setX(double x);

double y() const;
void setY(double y);

double width() const;
void setWidth(double width);

double height() const;
void setHeight(double height);

bool minimized() const;
void setMinimized(bool minimized);

const std::string &text() const;
void setText(const std::string &text);

private:
spimpl::unique_impl_ptr<CommentPrivate> impl;
};

} // namespace libscratchcpp
8 changes: 7 additions & 1 deletion include/scratchcpp/target.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class IEngine;
class Variable;
class List;
class Block;
class Comment;
class Costume;
class Sound;
class TargetPrivate;
Expand Down Expand Up @@ -50,6 +51,11 @@ class LIBSCRATCHCPP_EXPORT Target
int findBlock(const std::string &id) const;
std::vector<std::shared_ptr<Block>> greenFlagBlocks() const;

const std::vector<std::shared_ptr<Comment>> &comments() const;
int addComment(std::shared_ptr<Comment> comment);
std::shared_ptr<Comment> commentAt(int index) const;
int findComment(const std::string &id) const;

int costumeIndex() const;
void setCostumeIndex(int newCostumeIndex);

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

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

private:
Expand Down
24 changes: 24 additions & 0 deletions src/engine/internal/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <scratchcpp/block.h>
#include <scratchcpp/variable.h>
#include <scratchcpp/list.h>
#include <scratchcpp/comment.h>
#include <scratchcpp/costume.h>
#include <scratchcpp/keyevent.h>
#include <cassert>
Expand Down Expand Up @@ -84,6 +85,14 @@ void Engine::resolveIds()

block->updateInputMap();
block->updateFieldMap();

auto comment = getComment(block->commentId());
block->setComment(comment);

if (comment) {
comment->setBlock(block);
assert(comment->blockId() == block->id());
}
}
}
}
Expand Down Expand Up @@ -1078,6 +1087,21 @@ std::shared_ptr<Broadcast> Engine::getBroadcast(const std::string &id)
return nullptr;
}

// Returns the comment with the given ID.
std::shared_ptr<Comment> Engine::getComment(const std::string &id)
{
if (id.empty())
return nullptr;

for (auto target : m_targets) {
int index = target->findComment(id);
if (index != -1)
return target->commentAt(index);
}

return nullptr;
}

// Returns the entity with the given ID. \see IEntity
std::shared_ptr<Entity> Engine::getEntity(const std::string &id)
{
Expand Down
1 change: 1 addition & 0 deletions src/engine/internal/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ class Engine : public IEngine
std::shared_ptr<Variable> getVariable(const std::string &id);
std::shared_ptr<List> getList(const std::string &id);
std::shared_ptr<Broadcast> getBroadcast(const std::string &id);
std::shared_ptr<Comment> getComment(const std::string &id);
std::shared_ptr<Entity> getEntity(const std::string &id);
std::shared_ptr<IBlockSection> blockSection(const std::string &opcode) const;

Expand Down
30 changes: 29 additions & 1 deletion src/internal/scratch3reader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <scratchcpp/variable.h>
#include <scratchcpp/list.h>
#include <scratchcpp/costume.h>
#include <scratchcpp/comment.h>
#include <scratchcpp/sound.h>
#include <scratchcpp/stage.h>
#include <scratchcpp/sprite.h>
Expand Down Expand Up @@ -188,10 +189,37 @@ bool Scratch3Reader::load()
READER_STEP(step, "target -> block -> shadow");
block->setShadow(blockInfo["shadow"]);

// comment
READER_STEP(step, "target -> block -> comment");
if (!blockInfo["comment"].is_null())
block->setCommentId(blockInfo["comment"]);

target->addBlock(block);
}

// TODO: Add comments
// comments
READER_STEP(step, "target -> comments");
auto comments = jsonTarget["comments"];
for (json::iterator it = comments.begin(); it != comments.end(); ++it) {
auto commentInfo = it.value();
READER_STEP(step, "target -> comment -> { id, x, y }");
auto comment = std::make_shared<Comment>(it.key(), jsonToValue(commentInfo["x"]).toDouble(), jsonToValue(commentInfo["y"]).toDouble());
READER_STEP(step, "target -> comment -> blockId");

if (!commentInfo["blockId"].is_null())
comment->setBlockId(commentInfo["blockId"]);

READER_STEP(step, "target -> comment -> width");
comment->setWidth(jsonToValue(commentInfo["width"]).toDouble());
READER_STEP(step, "target -> comment -> height");
comment->setHeight(jsonToValue(commentInfo["height"]).toDouble());
READER_STEP(step, "target -> comment -> minimized");
comment->setMinimized(commentInfo["minimized"]);
READER_STEP(step, "target -> comment -> text");
comment->setText(commentInfo["text"]);

target->addComment(comment);
}

// costumes
READER_STEP(step, "target -> costumes");
Expand Down
3 changes: 3 additions & 0 deletions src/scratch/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,4 +48,7 @@ target_sources(scratchcpp
keyevent.cpp
keyevent_p.cpp
keyevent_p.h
comment.cpp
comment_p.cpp
comment_p.h
)
31 changes: 31 additions & 0 deletions src/scratch/block.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include <scratchcpp/block.h>
#include <scratchcpp/input.h>
#include <scratchcpp/field.h>
#include <scratchcpp/comment.h>

#include "block_p.h"

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

/*! Returns the comment which is attached to this block. */
std::shared_ptr<Comment> Block::comment() const
{
return impl->comment;
}

/*! Returns the ID of the comment which is attached to this block. */
std::string Block::commentId() const
{
return impl->commentId;
}

/*! Sets the comment which is attached to this block. */
void Block::setComment(std::shared_ptr<Comment> comment)
{
impl->comment = comment;

if (comment)
impl->commentId = comment->id();
else
impl->commentId = "";
}

/*! Sets the ID of the comment which is attached to this block. */
void Block::setCommentId(const std::string &commentId)
{
impl->commentId = commentId;
impl->comment = nullptr;
}

/*! Sets the Engine. */
void Block::setEngine(IEngine *newEngine)
{
Expand Down
3 changes: 3 additions & 0 deletions src/scratch/block_p.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class IEngine;
class Target;
class Input;
class Field;
class Comment;

struct BlockPrivate
{
Expand All @@ -31,6 +32,8 @@ struct BlockPrivate
std::vector<std::shared_ptr<Field>> fields;
std::unordered_map<int, Field *> fieldMap;
bool shadow = false;
std::string commentId;
std::shared_ptr<Comment> comment = nullptr;
IEngine *engine = nullptr;
Target *target = nullptr;
BlockPrototype mutationPrototype;
Expand Down
117 changes: 117 additions & 0 deletions src/scratch/comment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// SPDX-License-Identifier: LGPL-3.0-or-later

#include <scratchcpp/comment.h>
#include <scratchcpp/block.h>

#include "comment_p.h"

using namespace libscratchcpp;

/*! Constructs Comment at the given position in the code area. */
Comment::Comment(const std::string &id, double x, double y) :
Entity(id),
impl(spimpl::make_unique_impl<CommentPrivate>(x, y))
{
}

/*! Returns the ID of the block the comment is attached to. */
const std::string &Comment::blockId() const
{
return impl->blockId;
}

/*! Sets the ID of the block the comment is attached to. */
void Comment::setBlockId(const std::string id)
{
impl->blockId = id;
impl->block = nullptr;
}

/*! Returns the block the comment is attached to. */
std::shared_ptr<Block> Comment::block() const
{
return impl->block;
}

/*! Sets the block the comment is attached to. */
void Comment::setBlock(std::shared_ptr<Block> block)
{
impl->block = block;

if (block)
impl->blockId = block->id();
else
impl->blockId = "";
}

/*! Returns the x-coordinate of the comment in the code area. */
double Comment::x() const
{
return impl->x;
}

/*! Sets the x-coordinate of the comment in the code area. */
void Comment::setX(double x)
{
impl->x = x;
}

/*! Returns the y-coordinate of the comment in the code area. */
double Comment::y() const
{
return impl->y;
}

/*! Sets the x-coordinate of the comment in the code area. */
void Comment::setY(double y)
{
impl->y = y;
}

/*! Returns the width. */
double Comment::width() const
{
return impl->width;
}

/*! Sets the width. */
void Comment::setWidth(double width)
{
impl->width = width;
}

/*! Returns the height. */
double Comment::height() const
{
return impl->height;
}

/*! Sets the height. */
void Comment::setHeight(double height)
{
impl->height = height;
}

/*! Returns true if the comment is collapsed and false otherwise. */
bool Comment::minimized() const
{
return impl->minimized;
}

/*! Sets whether the comment is collapsed. */
void Comment::setMinimized(bool minimized)
{
impl->minimized = minimized;
}

/*! Returns the text. */
const std::string &Comment::text() const
{
return impl->text;
}

/*! Sets the text. */
void Comment::setText(const std::string &text)
{
impl->text = text;
}
Loading