Skip to content

Commit b71250f

Browse files
authored
Merge pull request #77 from scratchcpp/basic_pen_blocks
Implement basic pen blocks
2 parents e09d28b + d53d1ef commit b71250f

16 files changed

+465
-16
lines changed

src/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,10 @@ qt_add_qml_module(scratchcpp-render
5555
penlayerpainter.cpp
5656
penlayerpainter.h
5757
penattributes.h
58+
blocks/penextension.cpp
59+
blocks/penextension.h
60+
blocks/penblocks.cpp
61+
blocks/penblocks.h
5862
)
5963

6064
list(APPEND QML_IMPORT_PATH ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})

src/blocks/penblocks.cpp

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
#include <scratchcpp/compiler.h>
4+
#include <scratchcpp/sprite.h>
5+
6+
#include "penblocks.h"
7+
#include "penlayer.h"
8+
#include "spritemodel.h"
9+
10+
using namespace scratchcpprender;
11+
using namespace libscratchcpp;
12+
13+
std::string PenBlocks::name() const
14+
{
15+
return "Pen";
16+
}
17+
18+
void PenBlocks::registerBlocks(IEngine *engine)
19+
{
20+
// Blocks
21+
engine->addCompileFunction(this, "pen_clear", &compileClear);
22+
engine->addCompileFunction(this, "pen_penDown", &compilePenDown);
23+
engine->addCompileFunction(this, "pen_penUp", &compilePenUp);
24+
}
25+
26+
void PenBlocks::compileClear(Compiler *compiler)
27+
{
28+
compiler->addFunctionCall(&clear);
29+
}
30+
31+
void PenBlocks::compilePenDown(Compiler *compiler)
32+
{
33+
compiler->addFunctionCall(&penDown);
34+
}
35+
36+
void PenBlocks::compilePenUp(Compiler *compiler)
37+
{
38+
compiler->addFunctionCall(&penUp);
39+
}
40+
41+
unsigned int PenBlocks::clear(VirtualMachine *vm)
42+
{
43+
IPenLayer *penLayer = PenLayer::getProjectPenLayer(vm->engine());
44+
45+
if (penLayer) {
46+
penLayer->clear();
47+
vm->engine()->requestRedraw();
48+
}
49+
50+
return 0;
51+
}
52+
53+
unsigned int PenBlocks::penDown(VirtualMachine *vm)
54+
{
55+
Target *target = vm->target();
56+
57+
if (!target || target->isStage())
58+
return 0;
59+
60+
Sprite *sprite = static_cast<Sprite *>(target);
61+
SpriteModel *model = static_cast<SpriteModel *>(sprite->getInterface());
62+
63+
if (model)
64+
model->setPenDown(true);
65+
66+
return 0;
67+
}
68+
69+
unsigned int PenBlocks::penUp(libscratchcpp::VirtualMachine *vm)
70+
{
71+
Target *target = vm->target();
72+
73+
if (!target || target->isStage())
74+
return 0;
75+
76+
Sprite *sprite = static_cast<Sprite *>(target);
77+
SpriteModel *model = static_cast<SpriteModel *>(sprite->getInterface());
78+
79+
if (model)
80+
model->setPenDown(false);
81+
82+
return 0;
83+
}

src/blocks/penblocks.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
#pragma once
4+
5+
#include <scratchcpp/iblocksection.h>
6+
7+
namespace scratchcpprender
8+
{
9+
10+
class PenBlocks : public libscratchcpp::IBlockSection
11+
{
12+
public:
13+
enum Inputs
14+
{
15+
};
16+
17+
std::string name() const override;
18+
19+
void registerBlocks(libscratchcpp::IEngine *engine) override;
20+
21+
static void compileClear(libscratchcpp::Compiler *compiler);
22+
static void compilePenDown(libscratchcpp::Compiler *compiler);
23+
static void compilePenUp(libscratchcpp::Compiler *compiler);
24+
25+
static unsigned int clear(libscratchcpp::VirtualMachine *vm);
26+
static unsigned int penDown(libscratchcpp::VirtualMachine *vm);
27+
static unsigned int penUp(libscratchcpp::VirtualMachine *vm);
28+
};
29+
30+
} // namespace scratchcpprender

src/blocks/penextension.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
#include <scratchcpp/iengine.h>
4+
5+
#include "penextension.h"
6+
#include "penblocks.h"
7+
8+
using namespace scratchcpprender;
9+
using namespace libscratchcpp;
10+
11+
std::string PenExtension::name() const
12+
{
13+
return "pen";
14+
}
15+
16+
std::string PenExtension::description() const
17+
{
18+
return "Pen extension";
19+
}
20+
21+
void PenExtension::registerSections(IEngine *engine)
22+
{
23+
engine->registerSection(std::make_shared<PenBlocks>());
24+
}

src/blocks/penextension.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// SPDX-License-Identifier: LGPL-3.0-or-later
2+
3+
#pragma once
4+
5+
#include <scratchcpp/iextension.h>
6+
7+
namespace scratchcpprender
8+
{
9+
10+
class PenExtension : public libscratchcpp::IExtension
11+
{
12+
public:
13+
std::string name() const override;
14+
std::string description() const override;
15+
16+
void registerSections(libscratchcpp::IEngine *engine) override;
17+
};
18+
19+
} // namespace scratchcpprender

src/penlayer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ void PenLayer::setEngine(libscratchcpp::IEngine *newEngine)
4747

4848
m_engine = newEngine;
4949

50-
if (m_engine) {
50+
if (m_engine && QOpenGLContext::currentContext()) {
5151
m_projectPenLayers[m_engine] = this;
5252
m_fbo = std::make_unique<QOpenGLFramebufferObject>(m_engine->stageWidth(), m_engine->stageHeight(), m_fboFormat);
5353
Q_ASSERT(m_fbo->isValid());
@@ -134,6 +134,11 @@ IPenLayer *PenLayer::getProjectPenLayer(libscratchcpp::IEngine *engine)
134134
return nullptr;
135135
}
136136

137+
void PenLayer::addPenLayer(libscratchcpp::IEngine *engine, IPenLayer *penLayer)
138+
{
139+
m_projectPenLayers[engine] = penLayer;
140+
}
141+
137142
QNanoQuickItemPainter *PenLayer::createItemPainter() const
138143
{
139144
return new PenLayerPainter;

src/penlayer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class PenLayer : public IPenLayer
3434
QOpenGLFramebufferObject *framebufferObject() const override;
3535

3636
static IPenLayer *getProjectPenLayer(libscratchcpp::IEngine *engine);
37+
static void addPenLayer(libscratchcpp::IEngine *engine, IPenLayer *penLayer); // for tests
3738

3839
signals:
3940
void engineChanged();

src/projectloader.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include <scratchcpp/iengine.h>
44
#include <scratchcpp/value.h>
55
#include <scratchcpp/monitor.h>
6+
#include <scratchcpp/scratchconfiguration.h>
67
#include <QtConcurrent/QtConcurrent>
78
#include <QApplication>
89

@@ -11,6 +12,7 @@
1112
#include "valuemonitormodel.h"
1213
#include "listmonitormodel.h"
1314
#include "renderedtarget.h"
15+
#include "blocks/penextension.h"
1416

1517
using namespace scratchcpprender;
1618
using namespace libscratchcpp;
@@ -31,6 +33,9 @@ ProjectLoader::ProjectLoader(QObject *parent) :
3133
});
3234

3335
initTimer();
36+
37+
// Register pen blocks
38+
ScratchConfiguration::registerExtension(std::make_shared<PenExtension>());
3439
}
3540

3641
ProjectLoader::~ProjectLoader()

src/spritemodel.cpp

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include <scratchcpp/costume.h>
44
#include <scratchcpp/rect.h>
5+
#include <scratchcpp/iengine.h>
56

67
#include "spritemodel.h"
78
#include "renderedtarget.h"
@@ -65,8 +66,13 @@ void SpriteModel::onYChanged(double y)
6566

6667
void SpriteModel::onMoved(double oldX, double oldY, double newX, double newY)
6768
{
68-
if (m_penDown && m_penLayer)
69+
if (m_penDown && m_penLayer) {
6970
m_penLayer->drawLine(m_penAttributes, oldX, oldY, newX, newY);
71+
libscratchcpp::IEngine *engine = m_sprite->engine();
72+
73+
if (engine)
74+
engine->requestRedraw();
75+
}
7076
}
7177

7278
void SpriteModel::onSizeChanged(double size)
@@ -151,13 +157,15 @@ bool SpriteModel::penDown() const
151157

152158
void SpriteModel::setPenDown(bool newPenDown)
153159
{
154-
if (m_penDown == newPenDown)
155-
return;
156-
157160
m_penDown = newPenDown;
158161

159-
if (m_penDown && m_penLayer && m_sprite)
162+
if (m_penDown && m_penLayer && m_sprite) {
160163
m_penLayer->drawPoint(m_penAttributes, m_sprite->x(), m_sprite->y());
164+
libscratchcpp::IEngine *engine = m_sprite->engine();
165+
166+
if (engine)
167+
engine->requestRedraw();
168+
}
161169
}
162170

163171
SpriteModel *SpriteModel::cloneRoot() const

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,4 @@ add_subdirectory(skins)
3434
add_subdirectory(penattributes)
3535
add_subdirectory(penlayer)
3636
add_subdirectory(penlayerpainter)
37+
add_subdirectory(blocks)

0 commit comments

Comments
 (0)