source: EcnlProtoTool/trunk/webapp/webmrbc/Blocks/Loops.cs@ 270

Last change on this file since 270 was 270, checked in by coas-nagasima, 7 years ago

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csharp
File size: 9.8 KB
Line 
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 Loop blocks for Blockly.
23 * @author fraser@google.com (Neil Fraser)
24 */
25using System;
26using System.Linq;
27using System.Text;
28using Bridge;
29using Bridge.Html5;
30using Bridge.jQuery2;
31
32namespace WebMrbc
33{
34 public class Loops
35 {
36 /**
37 * Common HSV hue for all blocks in this category.
38 */
39 public static int HUE = 120;
40 }
41
42 public class ControlsRepeatExtBlock : Block
43 {
44 public const string type_name = "controls_repeat_ext";
45
46 public ControlsRepeatExtBlock()
47 : base(type_name)
48 {
49 }
50
51 /**
52 * Block for repeat n times (external number).
53 * @this Blockly.Block
54 */
55 public void init()
56 {
57 this.jsonInit(new {
58 message0 = Msg.CONTROLS_REPEAT_TITLE,
59 args0 = new object[] {
60 new {
61 type = "input_value",
62 name = "TIMES",
63 check = "Number"
64 }
65 },
66 previousStatement = (Union<string, string[]>)null,
67 nextStatement = (Union<string, string[]>)null,
68 colour = Loops.HUE,
69 tooltip = Msg.CONTROLS_REPEAT_TOOLTIP,
70 helpUrl = Msg.CONTROLS_REPEAT_HELPURL
71 });
72 this.appendStatementInput("DO")
73 .appendField(Msg.CONTROLS_REPEAT_INPUT_DO);
74 }
75 }
76
77 public class ControlsRepeatBlock : Block
78 {
79 public const string type_name = "controls_repeat";
80
81 public ControlsRepeatBlock()
82 : base(type_name)
83 {
84 }
85
86 /**
87 * Block for repeat n times (internal number).
88 * The "controls_repeat_ext" block is preferred as it is more flexible.
89 * @this Blockly.Block
90 */
91 public void init()
92 {
93 this.jsonInit(new {
94 message0 = Msg.CONTROLS_REPEAT_TITLE,
95 args0 = new object[] {
96 new {
97 type = "field_number",
98 name = "TIMES",
99 value = 10,
100 min = 0,
101 precision = 1
102 }
103 },
104 previousStatement = (Union<string, string[]>)null,
105 nextStatement = (Union<string, string[]>)null,
106 colour = Loops.HUE,
107 tooltip = Msg.CONTROLS_REPEAT_TOOLTIP,
108 helpUrl = Msg.CONTROLS_REPEAT_HELPURL
109 });
110 this.appendStatementInput("DO")
111 .appendField(Msg.CONTROLS_REPEAT_INPUT_DO);
112 }
113 }
114
115 public class ControlsWhileUntilBlock : Block
116 {
117 public const string type_name = "controls_whileUntil";
118
119 public ControlsWhileUntilBlock()
120 : base(type_name)
121 {
122 }
123
124 /**
125 * Block for "do while/until" loop.
126 * @this Blockly.Block
127 */
128 public void init()
129 {
130 var OPERATORS = new[] {
131 new [] {Msg.CONTROLS_WHILEUNTIL_OPERATOR_WHILE, "WHILE"},
132 new [] {Msg.CONTROLS_WHILEUNTIL_OPERATOR_UNTIL, "UNTIL"}
133 };
134 this.setHelpUrl(Msg.CONTROLS_WHILEUNTIL_HELPURL);
135 this.setColour(Loops.HUE);
136 this.appendValueInput("BOOL")
137 .setCheck("Boolean")
138 .appendField(new FieldDropdown(OPERATORS), "MODE");
139 this.appendStatementInput("DO")
140 .appendField(Msg.CONTROLS_WHILEUNTIL_INPUT_DO);
141 this.setPreviousStatement(true);
142 this.setNextStatement(true);
143 // Assign "this" to a variable for use in the tooltip closure below.
144 var thisBlock = this;
145 this.setTooltip(new Func<string>(() => {
146 switch (thisBlock.getFieldValue("MODE")) {
147 case "WHILE": return Msg.CONTROLS_WHILEUNTIL_TOOLTIP_WHILE;
148 case "UNTIL": return Msg.CONTROLS_WHILEUNTIL_TOOLTIP_UNTIL;
149 }
150 return "";
151 }));
152 }
153 }
154
155 public class ControlsForBlock : Block
156 {
157 public const string type_name = "controls_for";
158
159 public ControlsForBlock()
160 : base(type_name)
161 {
162 }
163
164 /**
165 * Block for "for" loop.
166 * @this Blockly.Block
167 */
168 public void init()
169 {
170 this.jsonInit(new {
171 message0 = Msg.CONTROLS_FOR_TITLE,
172 args0 = new object[] {
173 new {
174 type = "field_variable",
175 name = "VAR",
176 variable = (string)null
177 },
178 new {
179 type = "input_value",
180 name = "FROM",
181 check = "Number",
182 align = "RIGHT"
183 },
184 new {
185 type = "input_value",
186 name = "TO",
187 check = "Number",
188 align = "RIGHT"
189 },
190 new {
191 type = "input_value",
192 name = "BY",
193 check = "Number",
194 align = "RIGHT"
195 }
196 },
197 inputsInline = true,
198 previousStatement = (Union<string, string[]>)null,
199 nextStatement = (Union<string, string[]>)null,
200 colour = Loops.HUE,
201 helpUrl = Msg.CONTROLS_FOR_HELPURL
202 });
203 this.appendStatementInput("DO")
204 .appendField(Msg.CONTROLS_FOR_INPUT_DO);
205 // Assign "this" to a variable for use in the tooltip closure below.
206 var thisBlock = this;
207 this.setTooltip(new Func<string>(() => {
208 return Msg.CONTROLS_FOR_TOOLTIP.Replace("%1", thisBlock.getFieldValue("VAR"));
209 }));
210 }
211
212 /**
213 * Add menu option to create getter block for loop variable.
214 * @param {!Array} options List of menu options to add to.
215 * @this Blockly.Block
216 */
217 public void customContextMenu(object[] options)
218 {
219 if (!this.isCollapsed()) {
220 var option = new ContextMenuOption() { enabled = true };
221 var name = this.getFieldValue("VAR");
222 option.text = Msg.VARIABLES_SET_CREATE_GET.Replace("%1", name);
223 var xmlField = goog.dom.createDom("field", null, name);
224 xmlField.SetAttribute("name", "VAR");
225 var xmlBlock = goog.dom.createDom("block", null, xmlField);
226 xmlBlock.SetAttribute("type", VariablesGetBlock.type_name);
227 option.callback = ContextMenu.callbackFactory(this, xmlBlock);
228 options.Push(option);
229 }
230 }
231 }
232
233 public class ControlsForEachBlock : Block
234 {
235 public const string type_name = "controls_forEach";
236
237 public ControlsForEachBlock()
238 : base(type_name)
239 {
240 }
241
242 /**
243 * Block for "for each" loop.
244 * @this Blockly.Block
245 */
246 public void init()
247 {
248 this.jsonInit(new {
249 message0 = Msg.CONTROLS_FOREACH_TITLE,
250 args0 = new object[] {
251 new {
252 type = "field_variable",
253 name = "VAR",
254 variable = (string)null
255 },
256 new {
257 type = "input_value",
258 name = "LIST",
259 check = "Array"
260 }
261 },
262 previousStatement = (Union<string, string[]>)null,
263 nextStatement = (Union<string, string[]>)null,
264 colour = Loops.HUE,
265 helpUrl = Msg.CONTROLS_FOREACH_HELPURL
266 });
267 this.appendStatementInput("DO")
268 .appendField(Msg.CONTROLS_FOREACH_INPUT_DO);
269 // Assign "this" to a variable for use in the tooltip closure below.
270 var thisBlock = this;
271 this.setTooltip(new Func<string>(() => {
272 return Msg.CONTROLS_FOREACH_TOOLTIP.Replace("%1", thisBlock.getFieldValue("VAR"));
273 }));
274 }
275
276 /**
277 * Add menu option to create getter block for loop variable.
278 * @param {!Array} options List of menu options to add to.
279 * @this Blockly.Block
280 */
281 public void customContextMenu(object[] options)
282 {
283 if (!this.isCollapsed()) {
284 var option = new ContextMenuOption() { enabled = true };
285 var name = this.getFieldValue("VAR");
286 option.text = Msg.VARIABLES_SET_CREATE_GET.Replace("%1", name);
287 var xmlField = goog.dom.createDom("field", null, name);
288 xmlField.SetAttribute("name", "VAR");
289 var xmlBlock = goog.dom.createDom("block", null, xmlField);
290 xmlBlock.SetAttribute("type", VariablesGetBlock.type_name);
291 option.callback = ContextMenu.callbackFactory(this, xmlBlock);
292 options.Push(option);
293 }
294 }
295 }
296
297 public class ControlsFlowStatementsBlock : Block
298 {
299 public const string type_name = "controls_flow_statements";
300
301 public ControlsFlowStatementsBlock()
302 : base(type_name)
303 {
304 }
305
306 /**
307 * Block for flow statements: continue, break.
308 * @this Blockly.Block
309 */
310 public void init()
311 {
312 var OPERATORS = new[] {
313 new [] {Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_BREAK, "BREAK"},
314 new [] {Msg.CONTROLS_FLOW_STATEMENTS_OPERATOR_CONTINUE, "CONTINUE"}
315 };
316 this.setHelpUrl(Msg.CONTROLS_FLOW_STATEMENTS_HELPURL);
317 this.setColour(Loops.HUE);
318 this.appendDummyInput()
319 .appendField(new FieldDropdown(OPERATORS), "FLOW");
320 this.setPreviousStatement(true);
321 // Assign "this" to a variable for use in the tooltip closure below.
322 var thisBlock = this;
323 this.setTooltip(new Func<string>(() => {
324 switch (thisBlock.getFieldValue("FLOW")) {
325 case "BREAK": return Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_BREAK;
326 case "CONTINUE": return Msg.CONTROLS_FLOW_STATEMENTS_TOOLTIP_CONTINUE;
327 }
328 return "";
329 }));
330 }
331
332 /**
333 * Called whenever anything on the workspace changes.
334 * Add warning if this flow block is not nested inside a loop.
335 * @param {!Abstract} e Change event.
336 * @this Blockly.Block
337 */
338 public void onchange(Abstract e)
339 {
340 if (((WorkspaceSvg)this.workspace).isDragging()) {
341 return; // Don't change state at the start of a drag.
342 }
343 var legal = false;
344 // Is the block nested in a loop?
345 var block = (Block)this;
346 do {
347 if (this.LOOP_TYPES.IndexOf(block.type) != -1) {
348 legal = true;
349 break;
350 }
351 block = block.getSurroundParent();
352 } while (block != null);
353 if (legal) {
354 this.setWarningText(null);
355 if (!this.isInFlyout) {
356 this.setDisabled(false);
357 }
358 }
359 else {
360 this.setWarningText(Msg.CONTROLS_FLOW_STATEMENTS_WARNING);
361 if (!this.isInFlyout && !this.getInheritedDisabled()) {
362 this.setDisabled(true);
363 }
364 }
365 }
366 /**
367 * List of block types that are loops and thus do not need warnings.
368 * To add a new loop type add this to your code:
369 * Blockly.Blocks["controls_flow_statements"].LOOP_TYPES.push("custom_loop");
370 */
371 string[] LOOP_TYPES = new[] {
372 ControlsRepeatBlock .type_name,
373 ControlsRepeatExtBlock.type_name,
374 ControlsForEachBlock.type_name,
375 ControlsForBlock.type_name,
376 ControlsWhileUntilBlock.type_name
377 };
378 }
379}
Note: See TracBrowser for help on using the repository browser.