22
33#include < scratchcpp/compiler.h>
44#include < scratchcpp/sprite.h>
5+ #include < scratchcpp/input.h>
56
67#include " penblocks.h"
78#include " penlayer.h"
@@ -15,6 +16,12 @@ using namespace libscratchcpp;
1516static const double PEN_SIZE_MIN = 1 ;
1617static const double PEN_SIZE_MAX = 1200 ;
1718
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+
1825std::string PenBlocks::name () const
1926{
2027 return " Pen" ;
@@ -27,6 +34,7 @@ void PenBlocks::registerBlocks(IEngine *engine)
2734 engine->addCompileFunction (this , " pen_penDown" , &compilePenDown);
2835 engine->addCompileFunction (this , " pen_penUp" , &compilePenUp);
2936 engine->addCompileFunction (this , " pen_setPenColorToColor" , &compileSetPenColorToColor);
37+ engine->addCompileFunction (this , " pen_changePenColorParamBy" , &compileChangePenColorParamBy);
3038 engine->addCompileFunction (this , " pen_changePenSizeBy" , &compileChangePenSizeBy);
3139 engine->addCompileFunction (this , " pen_setPenSizeTo" , &compileSetPenSizeTo);
3240 engine->addCompileFunction (this , " pen_changePenShadeBy" , &compileChangePenShadeBy);
@@ -36,6 +44,8 @@ void PenBlocks::registerBlocks(IEngine *engine)
3644
3745 // Inputs
3846 engine->addInput (this , " COLOR" , COLOR);
47+ engine->addInput (this , " COLOR_PARAM" , COLOR_PARAM);
48+ engine->addInput (this , " VALUE" , VALUE);
3949 engine->addInput (this , " SIZE" , SIZE);
4050 engine->addInput (this , " SHADE" , SHADE);
4151 engine->addInput (this , " HUE" , HUE);
@@ -62,6 +72,35 @@ void PenBlocks::compileSetPenColorToColor(libscratchcpp::Compiler *compiler)
6272 compiler->addFunctionCall (&setPenColorToColor);
6373}
6474
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+
65104void PenBlocks::compileChangePenSizeBy (libscratchcpp::Compiler *compiler)
66105{
67106 compiler->addInput (SIZE);
@@ -248,6 +287,62 @@ unsigned int PenBlocks::setPenColorToColor(libscratchcpp::VirtualMachine *vm)
248287 return 1 ;
249288}
250289
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+
251346SpriteModel *PenBlocks::getSpriteModel (libscratchcpp::VirtualMachine *vm)
252347{
253348 Target *target = vm->target ();
@@ -266,6 +361,18 @@ void PenBlocks::setOrChangeColorParam(ColorParam param, double value, PenState &
266361 case ColorParam::COLOR:
267362 penState.color = wrapClamp (value + (change ? penState.color : 0 ), 0 , 100 );
268363 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 ;
269376 }
270377
271378 penState.updateColor ();
0 commit comments