2
2
3
3
#include < scratchcpp/compiler.h>
4
4
#include < scratchcpp/sprite.h>
5
+ #include < scratchcpp/input.h>
5
6
6
7
#include " penblocks.h"
7
8
#include " penlayer.h"
@@ -15,6 +16,12 @@ using namespace libscratchcpp;
15
16
static const double PEN_SIZE_MIN = 1 ;
16
17
static const double PEN_SIZE_MAX = 1200 ;
17
18
19
+ static const double COLOR_PARAM_MIN = 0 ;
20
+ static const double COLOR_PARAM_MAX = 100 ;
21
+
22
+ const std::unordered_map<std::string, PenBlocks::ColorParam>
23
+ PenBlocks::COLOR_PARAM_MAP = { { " color" , ColorParam::COLOR }, { " saturation" , ColorParam::SATURATION }, { " brightness" , ColorParam::BRIGHTNESS }, { " transparency" , ColorParam::TRANSPARENCY } };
24
+
18
25
std::string PenBlocks::name () const
19
26
{
20
27
return " Pen" ;
@@ -27,6 +34,7 @@ void PenBlocks::registerBlocks(IEngine *engine)
27
34
engine->addCompileFunction (this , " pen_penDown" , &compilePenDown);
28
35
engine->addCompileFunction (this , " pen_penUp" , &compilePenUp);
29
36
engine->addCompileFunction (this , " pen_setPenColorToColor" , &compileSetPenColorToColor);
37
+ engine->addCompileFunction (this , " pen_changePenColorParamBy" , &compileChangePenColorParamBy);
30
38
engine->addCompileFunction (this , " pen_changePenSizeBy" , &compileChangePenSizeBy);
31
39
engine->addCompileFunction (this , " pen_setPenSizeTo" , &compileSetPenSizeTo);
32
40
engine->addCompileFunction (this , " pen_changePenShadeBy" , &compileChangePenShadeBy);
@@ -36,6 +44,8 @@ void PenBlocks::registerBlocks(IEngine *engine)
36
44
37
45
// Inputs
38
46
engine->addInput (this , " COLOR" , COLOR);
47
+ engine->addInput (this , " COLOR_PARAM" , COLOR_PARAM);
48
+ engine->addInput (this , " VALUE" , VALUE);
39
49
engine->addInput (this , " SIZE" , SIZE);
40
50
engine->addInput (this , " SHADE" , SHADE);
41
51
engine->addInput (this , " HUE" , HUE);
@@ -62,6 +72,35 @@ void PenBlocks::compileSetPenColorToColor(libscratchcpp::Compiler *compiler)
62
72
compiler->addFunctionCall (&setPenColorToColor);
63
73
}
64
74
75
+ void PenBlocks::compileChangePenColorParamBy (libscratchcpp::Compiler *compiler)
76
+ {
77
+ Input *input = compiler->input (COLOR_PARAM);
78
+
79
+ if (input->type () != Input::Type::ObscuredShadow) {
80
+ assert (input->pointsToDropdownMenu ());
81
+ std::string value = input->selectedMenuItem ();
82
+ BlockFunc f = nullptr ;
83
+
84
+ if (value == " color" )
85
+ f = &changePenColorBy;
86
+ else if (value == " saturation" )
87
+ f = &changePenSaturationBy;
88
+ else if (value == " brightness" )
89
+ f = &changePenBrightnessBy;
90
+ else if (value == " transparency" )
91
+ f = &changePenTransparencyBy;
92
+
93
+ if (f) {
94
+ compiler->addInput (VALUE);
95
+ compiler->addFunctionCall (f);
96
+ }
97
+ } else {
98
+ compiler->addInput (input);
99
+ compiler->addInput (VALUE);
100
+ compiler->addFunctionCall (&changePenColorParamBy);
101
+ }
102
+ }
103
+
65
104
void PenBlocks::compileChangePenSizeBy (libscratchcpp::Compiler *compiler)
66
105
{
67
106
compiler->addInput (SIZE);
@@ -248,6 +287,62 @@ unsigned int PenBlocks::setPenColorToColor(libscratchcpp::VirtualMachine *vm)
248
287
return 1 ;
249
288
}
250
289
290
+ unsigned int PenBlocks::changePenColorParamBy (VirtualMachine *vm)
291
+ {
292
+ SpriteModel *model = getSpriteModel (vm);
293
+
294
+ if (model) {
295
+ const auto it = COLOR_PARAM_MAP.find (vm->getInput (0 , 2 )->toString ());
296
+
297
+ if (it == COLOR_PARAM_MAP.cend ())
298
+ return 2 ;
299
+
300
+ setOrChangeColorParam (it->second , vm->getInput (1 , 2 )->toDouble (), model->penState (), true );
301
+ }
302
+
303
+ return 2 ;
304
+ }
305
+
306
+ unsigned int PenBlocks::changePenColorBy (VirtualMachine *vm)
307
+ {
308
+ SpriteModel *model = getSpriteModel (vm);
309
+
310
+ if (model)
311
+ setOrChangeColorParam (ColorParam::COLOR, vm->getInput (0 , 1 )->toDouble (), model->penState (), true );
312
+
313
+ return 1 ;
314
+ }
315
+
316
+ unsigned int PenBlocks::changePenSaturationBy (VirtualMachine *vm)
317
+ {
318
+ SpriteModel *model = getSpriteModel (vm);
319
+
320
+ if (model)
321
+ setOrChangeColorParam (ColorParam::SATURATION, vm->getInput (0 , 1 )->toDouble (), model->penState (), true );
322
+
323
+ return 1 ;
324
+ }
325
+
326
+ unsigned int PenBlocks::changePenBrightnessBy (VirtualMachine *vm)
327
+ {
328
+ SpriteModel *model = getSpriteModel (vm);
329
+
330
+ if (model)
331
+ setOrChangeColorParam (ColorParam::BRIGHTNESS, vm->getInput (0 , 1 )->toDouble (), model->penState (), true );
332
+
333
+ return 1 ;
334
+ }
335
+
336
+ unsigned int PenBlocks::changePenTransparencyBy (VirtualMachine *vm)
337
+ {
338
+ SpriteModel *model = getSpriteModel (vm);
339
+
340
+ if (model)
341
+ setOrChangeColorParam (ColorParam::TRANSPARENCY, vm->getInput (0 , 1 )->toDouble (), model->penState (), true );
342
+
343
+ return 1 ;
344
+ }
345
+
251
346
SpriteModel *PenBlocks::getSpriteModel (libscratchcpp::VirtualMachine *vm)
252
347
{
253
348
Target *target = vm->target ();
@@ -266,6 +361,18 @@ void PenBlocks::setOrChangeColorParam(ColorParam param, double value, PenState &
266
361
case ColorParam::COLOR:
267
362
penState.color = wrapClamp (value + (change ? penState.color : 0 ), 0 , 100 );
268
363
break ;
364
+
365
+ case ColorParam::SATURATION:
366
+ penState.saturation = std::clamp (value + (change ? penState.saturation : 0 ), COLOR_PARAM_MIN, COLOR_PARAM_MAX);
367
+ break ;
368
+
369
+ case ColorParam::BRIGHTNESS:
370
+ penState.brightness = std::clamp (value + (change ? penState.brightness : 0 ), COLOR_PARAM_MIN, COLOR_PARAM_MAX);
371
+ break ;
372
+
373
+ case ColorParam::TRANSPARENCY:
374
+ penState.transparency = std::clamp (value + (change ? penState.transparency : 0 ), COLOR_PARAM_MIN, COLOR_PARAM_MAX);
375
+ break ;
269
376
}
270
377
271
378
penState.updateColor ();
0 commit comments