1 | /**
|
---|
2 | * @license
|
---|
3 | * Visual Blocks Editor
|
---|
4 | *
|
---|
5 | * Copyright 2012 Google Inc.
|
---|
6 | * https://developers.google.com/blockly/
|
---|
7 | *
|
---|
8 | * Licensed under the Apache License, Version 2.0 (the "License");
|
---|
9 | * you may not use this file except in compliance with the License.
|
---|
10 | * You may obtain a copy of the License at
|
---|
11 | *
|
---|
12 | * http://www.apache.org/licenses/LICENSE-2.0
|
---|
13 | *
|
---|
14 | * Unless required by applicable law or agreed to in writing, software
|
---|
15 | * distributed under the License is distributed on an "AS IS" BASIS,
|
---|
16 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
---|
17 | * See the License for the specific language governing permissions and
|
---|
18 | * limitations under the License.
|
---|
19 | */
|
---|
20 |
|
---|
21 | /**
|
---|
22 | * @fileoverview Math blocks for Blockly.
|
---|
23 | * @author q.neutron@gmail.com (Quynh Neutron)
|
---|
24 | */
|
---|
25 | using System;
|
---|
26 | using System.Linq;
|
---|
27 | using System.Text;
|
---|
28 | using Bridge;
|
---|
29 | using Bridge.Html5;
|
---|
30 | using Bridge.jQuery2;
|
---|
31 |
|
---|
32 | namespace WebMrbc
|
---|
33 | {
|
---|
34 | public class Math
|
---|
35 | {
|
---|
36 | /**
|
---|
37 | * Common HSV hue for all blocks in this category.
|
---|
38 | */
|
---|
39 | public static int HUE = 230;
|
---|
40 | }
|
---|
41 |
|
---|
42 | public class MathNumberBlock : Block
|
---|
43 | {
|
---|
44 | public const string type_name = "math_number";
|
---|
45 |
|
---|
46 | public MathNumberBlock()
|
---|
47 | : base(type_name)
|
---|
48 | {
|
---|
49 | }
|
---|
50 |
|
---|
51 | /**
|
---|
52 | * Block for numeric value.
|
---|
53 | * @this Blockly.Block
|
---|
54 | */
|
---|
55 | public void init()
|
---|
56 | {
|
---|
57 | this.setHelpUrl(Msg.MATH_NUMBER_HELPURL);
|
---|
58 | this.setColour(Math.HUE);
|
---|
59 | this.appendDummyInput()
|
---|
60 | .appendField(new FieldNumber("0", "-Infinity", "Infinity", 0), "NUM");
|
---|
61 | this.setOutput(true, "Number");
|
---|
62 | // Assign "this" to a variable for use in the tooltip closure below.
|
---|
63 | var thisBlock = this;
|
---|
64 | // Number block is trivial. Use tooltip of parent block if it exists.
|
---|
65 | this.setTooltip(new Func<string>(() => {
|
---|
66 | var parent = thisBlock.getParent();
|
---|
67 | return (parent != null && parent.getInputsInline() && !String.IsNullOrEmpty(parent.tooltip)) ? parent.tooltip :
|
---|
68 | Msg.MATH_NUMBER_TOOLTIP;
|
---|
69 | }));
|
---|
70 | }
|
---|
71 | }
|
---|
72 |
|
---|
73 | public class MathArithmeticBlock : Block
|
---|
74 | {
|
---|
75 | public const string type_name = "math_arithmetic";
|
---|
76 |
|
---|
77 | public MathArithmeticBlock()
|
---|
78 | : base(type_name)
|
---|
79 | {
|
---|
80 | }
|
---|
81 |
|
---|
82 | /**
|
---|
83 | * Block for basic arithmetic operator.
|
---|
84 | * @this Blockly.Block
|
---|
85 | */
|
---|
86 | public void init()
|
---|
87 | {
|
---|
88 | this.jsonInit(new {
|
---|
89 | message0 = "%1 %2 %3",
|
---|
90 | args0 = new object[] {
|
---|
91 | new {
|
---|
92 | type = "input_value",
|
---|
93 | name = "A",
|
---|
94 | check = "Number"
|
---|
95 | },
|
---|
96 | new {
|
---|
97 | type = "field_dropdown",
|
---|
98 | name = "OP",
|
---|
99 | options = new [] {
|
---|
100 | new [] {Msg.MATH_ADDITION_SYMBOL, "ADD"},
|
---|
101 | new [] {Msg.MATH_SUBTRACTION_SYMBOL, "MINUS"},
|
---|
102 | new [] {Msg.MATH_MULTIPLICATION_SYMBOL, "MULTIPLY"},
|
---|
103 | new [] {Msg.MATH_DIVISION_SYMBOL, "DIVIDE"},
|
---|
104 | new [] {Msg.MATH_POWER_SYMBOL, "POWER"}
|
---|
105 | }
|
---|
106 | },
|
---|
107 | new {
|
---|
108 | type = "input_value",
|
---|
109 | name = "B",
|
---|
110 | check = "Number"
|
---|
111 | }
|
---|
112 | },
|
---|
113 | inputsInline = true,
|
---|
114 | output = "Number",
|
---|
115 | colour = Math.HUE,
|
---|
116 | helpUrl = Msg.MATH_ARITHMETIC_HELPURL
|
---|
117 | });
|
---|
118 | // Assign "this" to a variable for use in the tooltip closure below.
|
---|
119 | var thisBlock = this;
|
---|
120 | this.setTooltip(new Func<string>(() => {
|
---|
121 | switch (thisBlock.getFieldValue("OP")) {
|
---|
122 | case "ADD": return Msg.MATH_ARITHMETIC_TOOLTIP_ADD;
|
---|
123 | case "MINUS": return Msg.MATH_ARITHMETIC_TOOLTIP_MINUS;
|
---|
124 | case "MULTIPLY": return Msg.MATH_ARITHMETIC_TOOLTIP_MULTIPLY;
|
---|
125 | case "DIVIDE": return Msg.MATH_ARITHMETIC_TOOLTIP_DIVIDE;
|
---|
126 | case "POWER": return Msg.MATH_ARITHMETIC_TOOLTIP_POWER;
|
---|
127 | };
|
---|
128 | return "";
|
---|
129 | }));
|
---|
130 | }
|
---|
131 | }
|
---|
132 |
|
---|
133 | public class MathSingleBlock : Block
|
---|
134 | {
|
---|
135 | public const string type_name = "math_single";
|
---|
136 |
|
---|
137 | public MathSingleBlock()
|
---|
138 | : base(type_name)
|
---|
139 | {
|
---|
140 | }
|
---|
141 |
|
---|
142 | /**
|
---|
143 | * Block for advanced math operators with single operand.
|
---|
144 | * @this Blockly.Block
|
---|
145 | */
|
---|
146 | public void init()
|
---|
147 | {
|
---|
148 | this.jsonInit(new {
|
---|
149 | message0 = "%1 %2",
|
---|
150 | args0 = new object[] {
|
---|
151 | new {
|
---|
152 | type = "field_dropdown",
|
---|
153 | name = "OP",
|
---|
154 | options = new [] {
|
---|
155 | new [] {Msg.MATH_SINGLE_OP_ROOT, "ROOT"},
|
---|
156 | new [] {Msg.MATH_SINGLE_OP_ABSOLUTE, "ABS"},
|
---|
157 | new [] {"-", "NEG"},
|
---|
158 | new [] {"ln", "LN"},
|
---|
159 | new [] {"log10", "LOG10"},
|
---|
160 | new [] {"e^", "EXP"},
|
---|
161 | new [] {"10^", "POW10"}
|
---|
162 | }
|
---|
163 | },
|
---|
164 | new {
|
---|
165 | type = "input_value",
|
---|
166 | name = "NUM",
|
---|
167 | check = "Number"
|
---|
168 | }
|
---|
169 | },
|
---|
170 | output = "Number",
|
---|
171 | colour = Math.HUE,
|
---|
172 | helpUrl = Msg.MATH_SINGLE_HELPURL
|
---|
173 | });
|
---|
174 | // Assign "this" to a variable for use in the tooltip closure below.
|
---|
175 | var thisBlock = this;
|
---|
176 | this.setTooltip(new Func<string>(() => {
|
---|
177 | switch (thisBlock.getFieldValue("OP")) {
|
---|
178 | case "ROOT": return Msg.MATH_SINGLE_TOOLTIP_ROOT;
|
---|
179 | case "ABS": return Msg.MATH_SINGLE_TOOLTIP_ABS;
|
---|
180 | case "NEG": return Msg.MATH_SINGLE_TOOLTIP_NEG;
|
---|
181 | case "LN": return Msg.MATH_SINGLE_TOOLTIP_LN;
|
---|
182 | case "LOG10": return Msg.MATH_SINGLE_TOOLTIP_LOG10;
|
---|
183 | case "EXP": return Msg.MATH_SINGLE_TOOLTIP_EXP;
|
---|
184 | case "POW10": return Msg.MATH_SINGLE_TOOLTIP_POW10;
|
---|
185 | }
|
---|
186 | return "";
|
---|
187 | }));
|
---|
188 | }
|
---|
189 | }
|
---|
190 |
|
---|
191 | public class MathTrigBlock : Block
|
---|
192 | {
|
---|
193 | public const string type_name = "math_trig";
|
---|
194 |
|
---|
195 | public MathTrigBlock()
|
---|
196 | : base(type_name)
|
---|
197 | {
|
---|
198 | }
|
---|
199 |
|
---|
200 | /**
|
---|
201 | * Block for trigonometry operators.
|
---|
202 | * @this Blockly.Block
|
---|
203 | */
|
---|
204 | public void init()
|
---|
205 | {
|
---|
206 | this.jsonInit(new {
|
---|
207 | message0 = "%1 %2",
|
---|
208 | args0 = new object[] {
|
---|
209 | new {
|
---|
210 | type = "field_dropdown",
|
---|
211 | name = "OP",
|
---|
212 | options = new [] {
|
---|
213 | new [] { Msg.MATH_TRIG_SIN, "SIN" },
|
---|
214 | new [] { Msg.MATH_TRIG_COS, "COS" },
|
---|
215 | new [] { Msg.MATH_TRIG_TAN, "TAN" },
|
---|
216 | new [] { Msg.MATH_TRIG_ASIN, "ASIN" },
|
---|
217 | new [] { Msg.MATH_TRIG_ACOS, "ACOS" },
|
---|
218 | new [] { Msg.MATH_TRIG_ATAN, "ATAN" }
|
---|
219 | }
|
---|
220 | },
|
---|
221 | new {
|
---|
222 | type = "input_value",
|
---|
223 | name = "NUM",
|
---|
224 | check = "Number"
|
---|
225 | }
|
---|
226 | },
|
---|
227 | output = "Number",
|
---|
228 | colour = Math.HUE,
|
---|
229 | helpUrl = Msg.MATH_TRIG_HELPURL
|
---|
230 | });
|
---|
231 | // Assign "this" to a variable for use in the tooltip closure below.
|
---|
232 | var thisBlock = this;
|
---|
233 | this.setTooltip(new Func<string>(() => {
|
---|
234 | switch (thisBlock.getFieldValue("OP")) {
|
---|
235 | case "SIN": return Msg.MATH_TRIG_TOOLTIP_SIN;
|
---|
236 | case "COS": return Msg.MATH_TRIG_TOOLTIP_COS;
|
---|
237 | case "TAN": return Msg.MATH_TRIG_TOOLTIP_TAN;
|
---|
238 | case "ASIN": return Msg.MATH_TRIG_TOOLTIP_ASIN;
|
---|
239 | case "ACOS": return Msg.MATH_TRIG_TOOLTIP_ACOS;
|
---|
240 | case "ATAN": return Msg.MATH_TRIG_TOOLTIP_ATAN;
|
---|
241 | }
|
---|
242 | return "";
|
---|
243 | }));
|
---|
244 | }
|
---|
245 | }
|
---|
246 |
|
---|
247 | public class MathConstantBlock : Block
|
---|
248 | {
|
---|
249 | public const string type_name = "math_constant";
|
---|
250 |
|
---|
251 | public MathConstantBlock()
|
---|
252 | : base(type_name)
|
---|
253 | {
|
---|
254 | }
|
---|
255 |
|
---|
256 | /**
|
---|
257 | * Block for constants: PI, E, the Golden Ratio, sqrt(2), 1/sqrt(2), INFINITY.
|
---|
258 | * @this Blockly.Block
|
---|
259 | */
|
---|
260 | public void init()
|
---|
261 | {
|
---|
262 | this.jsonInit(new {
|
---|
263 | message0 = "%1",
|
---|
264 | args0 = new object[] {
|
---|
265 | new {
|
---|
266 | type = "field_dropdown",
|
---|
267 | name = "CONSTANT",
|
---|
268 | options = new [] {
|
---|
269 | new [] {"\u03c0", "PI"},
|
---|
270 | new [] {"e", "E"},
|
---|
271 | new [] {"\u03c6", "GOLDEN_RATIO"},
|
---|
272 | new [] {"sqrt(2)", "SQRT2"},
|
---|
273 | new [] {"sqrt(\u00bd)", "SQRT1_2"},
|
---|
274 | new [] {"\u221e", "INFINITY"}
|
---|
275 | }
|
---|
276 | }
|
---|
277 | },
|
---|
278 | output = "Number",
|
---|
279 | colour = Math.HUE,
|
---|
280 | tooltip = Msg.MATH_CONSTANT_TOOLTIP,
|
---|
281 | helpUrl = Msg.MATH_CONSTANT_HELPURL
|
---|
282 | });
|
---|
283 | }
|
---|
284 | }
|
---|
285 |
|
---|
286 | public class MathNumberPropertyBlock : Block
|
---|
287 | {
|
---|
288 | public const string type_name = "math_number_property";
|
---|
289 |
|
---|
290 | public MathNumberPropertyBlock()
|
---|
291 | : base(type_name)
|
---|
292 | {
|
---|
293 | }
|
---|
294 |
|
---|
295 | /**
|
---|
296 | * Block for checking if a number is even, odd, prime, whole, positive,
|
---|
297 | * negative or if it is divisible by certain number.
|
---|
298 | * @this Blockly.Block
|
---|
299 | */
|
---|
300 | public void init()
|
---|
301 | {
|
---|
302 | var PROPERTIES = new[] {
|
---|
303 | new [] {Msg.MATH_IS_EVEN, "EVEN"},
|
---|
304 | new [] {Msg.MATH_IS_ODD, "ODD"},
|
---|
305 | new [] {Msg.MATH_IS_PRIME, "PRIME"},
|
---|
306 | new [] {Msg.MATH_IS_WHOLE, "WHOLE"},
|
---|
307 | new [] {Msg.MATH_IS_POSITIVE, "POSITIVE"},
|
---|
308 | new [] {Msg.MATH_IS_NEGATIVE, "NEGATIVE"},
|
---|
309 | new [] {Msg.MATH_IS_DIVISIBLE_BY, "DIVISIBLE_BY"}
|
---|
310 | };
|
---|
311 | this.setColour(Math.HUE);
|
---|
312 | this.appendValueInput("NUMBER_TO_CHECK")
|
---|
313 | .setCheck("Number");
|
---|
314 | var dropdown = new FieldDropdown(PROPERTIES, (option) => {
|
---|
315 | var divisorInput = (option == "DIVISIBLE_BY");
|
---|
316 | this.updateShape_(divisorInput);
|
---|
317 | return Script.Undefined;
|
---|
318 | });
|
---|
319 | this.appendDummyInput()
|
---|
320 | .appendField(dropdown, "PROPERTY");
|
---|
321 | this.setInputsInline(true);
|
---|
322 | this.setOutput(true, "Boolean");
|
---|
323 | this.setTooltip(Msg.MATH_IS_TOOLTIP);
|
---|
324 | }
|
---|
325 |
|
---|
326 | /**
|
---|
327 | * Create XML to represent whether the "divisorInput" should be present.
|
---|
328 | * @return {Element} XML storage element.
|
---|
329 | * @this Blockly.Block
|
---|
330 | */
|
---|
331 | public Element mutationToDom()
|
---|
332 | {
|
---|
333 | var container = Document.CreateElement("mutation");
|
---|
334 | var divisorInput = (this.getFieldValue("PROPERTY") == "DIVISIBLE_BY");
|
---|
335 | container.SetAttribute("divisor_input", divisorInput.ToString());
|
---|
336 | return container;
|
---|
337 | }
|
---|
338 |
|
---|
339 | /**
|
---|
340 | * Parse XML to restore the "divisorInput".
|
---|
341 | * @param {!Element} xmlElement XML storage element.
|
---|
342 | * @this Blockly.Block
|
---|
343 | */
|
---|
344 | public void domToMutation(Element xmlElement)
|
---|
345 | {
|
---|
346 | var divisorInput = (xmlElement.GetAttribute("divisor_input") == "true");
|
---|
347 | this.updateShape_(divisorInput);
|
---|
348 | }
|
---|
349 |
|
---|
350 | /**
|
---|
351 | * Modify this block to have (or not have) an input for "is divisible by".
|
---|
352 | * @param {boolean} divisorInput True if this block has a divisor input.
|
---|
353 | * @private
|
---|
354 | * @this Blockly.Block
|
---|
355 | */
|
---|
356 | public void updateShape_(bool divisorInput)
|
---|
357 | {
|
---|
358 | // Add or remove a Value Input.
|
---|
359 | var inputExists = this.getInput("DIVISOR");
|
---|
360 | if (divisorInput) {
|
---|
361 | if (inputExists == null) {
|
---|
362 | this.appendValueInput("DIVISOR")
|
---|
363 | .setCheck("Number");
|
---|
364 | }
|
---|
365 | }
|
---|
366 | else if (inputExists != null) {
|
---|
367 | this.removeInput("DIVISOR");
|
---|
368 | }
|
---|
369 | }
|
---|
370 | }
|
---|
371 |
|
---|
372 | public class MathChangeBlock : Block
|
---|
373 | {
|
---|
374 | public const string type_name = "math_change";
|
---|
375 |
|
---|
376 | public MathChangeBlock()
|
---|
377 | : base(type_name)
|
---|
378 | {
|
---|
379 | }
|
---|
380 |
|
---|
381 | /**
|
---|
382 | * Block for adding to a variable in place.
|
---|
383 | * @this Blockly.Block
|
---|
384 | */
|
---|
385 | public void init()
|
---|
386 | {
|
---|
387 | this.jsonInit(new {
|
---|
388 | message0 = Msg.MATH_CHANGE_TITLE,
|
---|
389 | args0 = new object[] {
|
---|
390 | new {
|
---|
391 | type = "field_variable",
|
---|
392 | name = "VAR",
|
---|
393 | variable = Msg.MATH_CHANGE_TITLE_ITEM
|
---|
394 | },
|
---|
395 | new {
|
---|
396 | type = "input_value",
|
---|
397 | name = "DELTA",
|
---|
398 | check = "Number"
|
---|
399 | }
|
---|
400 | },
|
---|
401 | previousStatement = (Union<string, string[]>)null,
|
---|
402 | nextStatement = (Union<string, string[]>)null,
|
---|
403 | colour = Blockly.Variables.HUE,
|
---|
404 | helpUrl = Msg.MATH_CHANGE_HELPURL
|
---|
405 | });
|
---|
406 | // Assign "this" to a variable for use in the tooltip closure below.
|
---|
407 | var thisBlock = this;
|
---|
408 | this.setTooltip(new Func<string>(() => {
|
---|
409 | return Msg.MATH_CHANGE_TOOLTIP.Replace("%1", thisBlock.getFieldValue("VAR"));
|
---|
410 | }));
|
---|
411 | }
|
---|
412 | }
|
---|
413 |
|
---|
414 | public class MathRoundBlock : Block
|
---|
415 | {
|
---|
416 | public const string type_name = "math_round";
|
---|
417 |
|
---|
418 | public MathRoundBlock()
|
---|
419 | : base(type_name)
|
---|
420 | {
|
---|
421 | }
|
---|
422 |
|
---|
423 | /**
|
---|
424 | * Block for rounding functions.
|
---|
425 | * @this Blockly.Block
|
---|
426 | */
|
---|
427 | public void init()
|
---|
428 | {
|
---|
429 | this.jsonInit(new {
|
---|
430 | message0 = "%1 %2",
|
---|
431 | args0 = new object[] {
|
---|
432 | new {
|
---|
433 | type = "field_dropdown",
|
---|
434 | name = "OP",
|
---|
435 | options = new [] {
|
---|
436 | new [] {Msg.MATH_ROUND_OPERATOR_ROUND, "ROUND"},
|
---|
437 | new [] {Msg.MATH_ROUND_OPERATOR_ROUNDUP, "ROUNDUP"},
|
---|
438 | new [] {Msg.MATH_ROUND_OPERATOR_ROUNDDOWN, "ROUNDDOWN"}
|
---|
439 | }
|
---|
440 | },
|
---|
441 | new {
|
---|
442 | type = "input_value",
|
---|
443 | name = "NUM",
|
---|
444 | check = "Number"
|
---|
445 | }
|
---|
446 | },
|
---|
447 | output = "Number",
|
---|
448 | colour = Math.HUE,
|
---|
449 | tooltip = Msg.MATH_ROUND_TOOLTIP,
|
---|
450 | helpUrl = Msg.MATH_ROUND_HELPURL
|
---|
451 | });
|
---|
452 | }
|
---|
453 | }
|
---|
454 |
|
---|
455 | public class MathOnListBlock : Block
|
---|
456 | {
|
---|
457 | public const string type_name = "math_on_list";
|
---|
458 |
|
---|
459 | public MathOnListBlock()
|
---|
460 | : base(type_name)
|
---|
461 | {
|
---|
462 | }
|
---|
463 |
|
---|
464 | /**
|
---|
465 | * Block for evaluating a list of numbers to return sum, average, min, max,
|
---|
466 | * etc. Some functions also work on text (min, max, mode, median).
|
---|
467 | * @this Blockly.Block
|
---|
468 | */
|
---|
469 | public void init()
|
---|
470 | {
|
---|
471 | var OPERATORS = new[] {
|
---|
472 | new [] {Msg.MATH_ONLIST_OPERATOR_SUM, "SUM"},
|
---|
473 | new [] {Msg.MATH_ONLIST_OPERATOR_MIN, "MIN"},
|
---|
474 | new [] {Msg.MATH_ONLIST_OPERATOR_MAX, "MAX"},
|
---|
475 | new [] {Msg.MATH_ONLIST_OPERATOR_AVERAGE, "AVERAGE"},
|
---|
476 | new [] {Msg.MATH_ONLIST_OPERATOR_MEDIAN, "MEDIAN"},
|
---|
477 | new [] {Msg.MATH_ONLIST_OPERATOR_MODE, "MODE"},
|
---|
478 | new [] {Msg.MATH_ONLIST_OPERATOR_STD_DEV, "STD_DEV"},
|
---|
479 | new [] {Msg.MATH_ONLIST_OPERATOR_RANDOM, "RANDOM"}
|
---|
480 | };
|
---|
481 | // Assign "this" to a variable for use in the closures below.
|
---|
482 | var thisBlock = this;
|
---|
483 | this.setHelpUrl(Msg.MATH_ONLIST_HELPURL);
|
---|
484 | this.setColour(Math.HUE);
|
---|
485 | this.setOutput(true, "Number");
|
---|
486 | var dropdown = new FieldDropdown(OPERATORS, (newOp) => {
|
---|
487 | thisBlock.updateType_(newOp);
|
---|
488 | return Script.Undefined;
|
---|
489 | });
|
---|
490 | this.appendValueInput("LIST")
|
---|
491 | .setCheck("Array")
|
---|
492 | .appendField(dropdown, "OP");
|
---|
493 | this.setTooltip(new Func<string>(() => {
|
---|
494 | switch (thisBlock.getFieldValue("OP")) {
|
---|
495 | case "SUM": return Msg.MATH_ONLIST_TOOLTIP_SUM;
|
---|
496 | case "MIN": return Msg.MATH_ONLIST_TOOLTIP_MIN;
|
---|
497 | case "MAX": return Msg.MATH_ONLIST_TOOLTIP_MAX;
|
---|
498 | case "AVERAGE": return Msg.MATH_ONLIST_TOOLTIP_AVERAGE;
|
---|
499 | case "MEDIAN": return Msg.MATH_ONLIST_TOOLTIP_MEDIAN;
|
---|
500 | case "MODE": return Msg.MATH_ONLIST_TOOLTIP_MODE;
|
---|
501 | case "STD_DEV": return Msg.MATH_ONLIST_TOOLTIP_STD_DEV;
|
---|
502 | case "RANDOM": return Msg.MATH_ONLIST_TOOLTIP_RANDOM;
|
---|
503 | }
|
---|
504 | return "";
|
---|
505 | }));
|
---|
506 | }
|
---|
507 |
|
---|
508 | /**
|
---|
509 | * Modify this block to have the correct output type.
|
---|
510 | * @param {string} newOp Either "MODE" or some op than returns a number.
|
---|
511 | * @private
|
---|
512 | * @this Blockly.Block
|
---|
513 | */
|
---|
514 | public void updateType_(string newOp)
|
---|
515 | {
|
---|
516 | if (newOp == "MODE") {
|
---|
517 | this.outputConnection.setCheck("Array");
|
---|
518 | }
|
---|
519 | else {
|
---|
520 | this.outputConnection.setCheck("Number");
|
---|
521 | }
|
---|
522 | }
|
---|
523 |
|
---|
524 | /**
|
---|
525 | * Create XML to represent the output type.
|
---|
526 | * @return {Element} XML storage element.
|
---|
527 | * @this Blockly.Block
|
---|
528 | */
|
---|
529 | public Element mutationToDom()
|
---|
530 | {
|
---|
531 | var container = Document.CreateElement("mutation");
|
---|
532 | container.SetAttribute("op", this.getFieldValue("OP"));
|
---|
533 | return container;
|
---|
534 | }
|
---|
535 |
|
---|
536 | /**
|
---|
537 | * Parse XML to restore the output type.
|
---|
538 | * @param {!Element} xmlElement XML storage element.
|
---|
539 | * @this Blockly.Block
|
---|
540 | */
|
---|
541 | public void domToMutation(Element xmlElement)
|
---|
542 | {
|
---|
543 | this.updateType_(xmlElement.GetAttribute("op"));
|
---|
544 | }
|
---|
545 | }
|
---|
546 |
|
---|
547 | public class MathModuloBlock : Block
|
---|
548 | {
|
---|
549 | public const string type_name = "math_modulo";
|
---|
550 |
|
---|
551 | public MathModuloBlock()
|
---|
552 | : base(type_name)
|
---|
553 | {
|
---|
554 | }
|
---|
555 |
|
---|
556 | /**
|
---|
557 | * Block for remainder of a division.
|
---|
558 | * @this Blockly.Block
|
---|
559 | */
|
---|
560 | public void init()
|
---|
561 | {
|
---|
562 | this.jsonInit(new {
|
---|
563 | message0 = Msg.MATH_MODULO_TITLE,
|
---|
564 | args0 = new object[] {
|
---|
565 | new {
|
---|
566 | type = "input_value",
|
---|
567 | name = "DIVIDEND",
|
---|
568 | check = "Number"
|
---|
569 | },
|
---|
570 | new {
|
---|
571 | type = "input_value",
|
---|
572 | name = "DIVISOR",
|
---|
573 | check = "Number"
|
---|
574 | }
|
---|
575 | },
|
---|
576 | inputsInline = true,
|
---|
577 | output = "Number",
|
---|
578 | colour = Math.HUE,
|
---|
579 | tooltip = Msg.MATH_MODULO_TOOLTIP,
|
---|
580 | helpUrl = Msg.MATH_MODULO_HELPURL
|
---|
581 | });
|
---|
582 | }
|
---|
583 | }
|
---|
584 |
|
---|
585 | public class MathConstrainBlock : Block
|
---|
586 | {
|
---|
587 | public const string type_name = "math_constrain";
|
---|
588 |
|
---|
589 | public MathConstrainBlock()
|
---|
590 | : base(type_name)
|
---|
591 | {
|
---|
592 | }
|
---|
593 |
|
---|
594 | /**
|
---|
595 | * Block for constraining a number between two limits.
|
---|
596 | * @this Blockly.Block
|
---|
597 | */
|
---|
598 | public void init()
|
---|
599 | {
|
---|
600 | this.jsonInit(new {
|
---|
601 | message0 = Msg.MATH_CONSTRAIN_TITLE,
|
---|
602 | args0 = new object[] {
|
---|
603 | new {
|
---|
604 | type = "input_value",
|
---|
605 | name = "VALUE",
|
---|
606 | check = "Number"
|
---|
607 | },
|
---|
608 | new {
|
---|
609 | type = "input_value",
|
---|
610 | name = "LOW",
|
---|
611 | check = "Number"
|
---|
612 | },
|
---|
613 | new {
|
---|
614 | type = "input_value",
|
---|
615 | name = "HIGH",
|
---|
616 | check = "Number"
|
---|
617 | }
|
---|
618 | },
|
---|
619 | inputsInline = true,
|
---|
620 | output = "Number",
|
---|
621 | colour = Math.HUE,
|
---|
622 | tooltip = Msg.MATH_CONSTRAIN_TOOLTIP,
|
---|
623 | helpUrl = Msg.MATH_CONSTRAIN_HELPURL
|
---|
624 | });
|
---|
625 | }
|
---|
626 | }
|
---|
627 |
|
---|
628 | public class MathRandomIntBlock : Block
|
---|
629 | {
|
---|
630 | public const string type_name = "math_random_int";
|
---|
631 |
|
---|
632 | public MathRandomIntBlock()
|
---|
633 | : base(type_name)
|
---|
634 | {
|
---|
635 | }
|
---|
636 |
|
---|
637 | /**
|
---|
638 | * Block for random integer between [X] and [Y].
|
---|
639 | * @this Blockly.Block
|
---|
640 | */
|
---|
641 | public void init()
|
---|
642 | {
|
---|
643 | this.jsonInit(new {
|
---|
644 | message0 = Msg.MATH_RANDOM_INT_TITLE,
|
---|
645 | args0 = new object[] {
|
---|
646 | new {
|
---|
647 | type = "input_value",
|
---|
648 | name = "FROM",
|
---|
649 | check = "Number"
|
---|
650 | },
|
---|
651 | new {
|
---|
652 | type = "input_value",
|
---|
653 | name = "TO",
|
---|
654 | check = "Number"
|
---|
655 | }
|
---|
656 | },
|
---|
657 | inputsInline = true,
|
---|
658 | output = "Number",
|
---|
659 | colour = Math.HUE,
|
---|
660 | tooltip = Msg.MATH_RANDOM_INT_TOOLTIP,
|
---|
661 | helpUrl = Msg.MATH_RANDOM_INT_HELPURL
|
---|
662 | });
|
---|
663 | }
|
---|
664 | }
|
---|
665 |
|
---|
666 | public class MathRandomFloatBlock : Block
|
---|
667 | {
|
---|
668 | public const string type_name = "math_random_float";
|
---|
669 |
|
---|
670 | public MathRandomFloatBlock()
|
---|
671 | : base(type_name)
|
---|
672 | {
|
---|
673 | }
|
---|
674 |
|
---|
675 | /**
|
---|
676 | * Block for random fraction between 0 and 1.
|
---|
677 | * @this Blockly.Block
|
---|
678 | */
|
---|
679 | public void init()
|
---|
680 | {
|
---|
681 | this.jsonInit(new {
|
---|
682 | message0 = Msg.MATH_RANDOM_FLOAT_TITLE_RANDOM,
|
---|
683 | output = "Number",
|
---|
684 | colour = Math.HUE,
|
---|
685 | tooltip = Msg.MATH_RANDOM_FLOAT_TOOLTIP,
|
---|
686 | helpUrl = Msg.MATH_RANDOM_FLOAT_HELPURL
|
---|
687 | });
|
---|
688 | }
|
---|
689 | }
|
---|
690 | }
|
---|