source: EcnlProtoTool/trunk/webapp/webmrbc/SwitchCaseBlock.cs

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

文字コードを設定

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csharp;charset=UTF-8
File size: 26.7 KB
Line 
1/*
2 * TOPPERS/ECNL Prototyping tool
3 *
4 * Copyright (C) 2017 Cores Co., Ltd. Japan
5 *
6 * 上記著作権者は,以下の(1)~(4)の条件を満たす場合に限り,本ソフトウェ
7 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
8 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
9 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
10 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
11 * スコード中に含まれていること.
12 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
13 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
14 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
15 * の無保証規定を掲載すること.
16 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
17 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
18 * と.
19 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
20 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
21 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
22 * 報告すること.
23 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
24 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
25 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
26 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
27 * 免責すること.
28 *
29 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
30 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
31 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
32 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
33 * の責任を負わない.
34 *
35 * @(#) $Id$
36 */
37using System;
38using Bridge;
39using Bridge.Html5;
40
41namespace WebMrbc
42{
43 public class SwitchCaseNumberBlock : Block
44 {
45 public const string type_name = "switch_case_number";
46
47 internal Tuple<string, string>[] cases_;
48 internal int defaultCount_;
49
50 public SwitchCaseNumberBlock()
51 : base(type_name)
52 {
53 }
54
55 /// <summary>
56 /// Block for swicth/case/default condition.
57 /// </summary>
58 public void init()
59 {
60 setHelpUrl("http://www.example.com/");
61 setColour(210);
62 appendValueInput("SWITCH")
63 .appendField("右の値が");
64 setPreviousStatement(true);
65 setNextStatement(true);
66 setMutator(new Mutator(new[] {
67 SwitchCaseNumberConstBlock.type_name,
68 SwitchCaseNumberRangeBlock.type_name,
69 SwitchCaseNumberDefaultBlock.type_name }));
70 setTooltip(new Func<string>(() => {
71 if ((cases_.Length == 0) && (defaultCount_ == 0)) {
72 return "条件に合うブロックを実行";
73 }
74 else if ((cases_.Length == 0) && (defaultCount_ != 0)) {
75 return "条件に合うブロックを実行、合うものがなければ最後のブロックを実行";
76 }
77 else if ((cases_.Length != 0) && (defaultCount_ == 0)) {
78 return "条件に合うブロックを実行";
79 }
80 else if ((cases_.Length != 0) && (defaultCount_ != 0)) {
81 return "条件に合うブロックを実行、合うものがなければ最後のブロックを実行";
82 }
83 return "";
84 }));
85 cases_ = new Tuple<string, string>[] { new Tuple<string, string>("0", null) };
86 defaultCount_ = 0;
87 updateShape_();
88 }
89
90 /// <summary>
91 /// Create XML to represent the number of else-if and else inputs.
92 /// </summary>
93 /// <returns>XML storage element.</returns>
94 public Element mutationToDom(bool opt_caseIds)
95 {
96 if ((cases_.Length == 0) && (defaultCount_ == 0)) {
97 return null;
98 }
99 var container = Document.CreateElement("mutation");
100 for (var i = 0; i < cases_.Length; i++) {
101 Element caseInfo;
102 var value = getFieldValue("CONST" + i);
103 if (value != null) {
104 caseInfo = Document.CreateElement("case");
105 caseInfo.SetAttribute("value", value);
106 }
107 else {
108 var min = getFieldValue("RANGE_MIN" + i);
109 var max = getFieldValue("RANGE_MAX" + i);
110 if (min != null && max != null) {
111 caseInfo = Document.CreateElement("case");
112 caseInfo.SetAttribute("value", min + ".." + max);
113 }
114 else
115 continue;
116 }
117 container.AppendChild(caseInfo);
118 }
119 container.SetAttribute("default", defaultCount_.ToString());
120 return container;
121 }
122
123 /// <summary>
124 /// Parse XML to restore the else-if and else inputs.
125 /// </summary>
126 /// <param name="xmlElement">XML storage element.</param>
127 public void domToMutation(Element xmlElement)
128 {
129 cases_ = new Tuple<string, string>[0];
130 Element childNode;
131 for (var i = 0; (childNode = (dynamic)xmlElement.ChildNodes[i]) != null; i++) {
132 if (childNode.NodeName.ToLower() == "case") {
133 var value = childNode.GetAttribute("value");
134 if (value != null)
135 cases_.Push(new Tuple<string, string>(value, null));
136 else {
137 var min = childNode.GetAttribute("minimum");
138 var max = childNode.GetAttribute("maximum");
139 if ((min != null) && (max != null)) {
140 cases_.Push(new Tuple<string, string>(min, max));
141 }
142 }
143 }
144 }
145 var count = xmlElement.GetAttribute("default");
146 defaultCount_ = count == null ? 0 : Bridge.Script.ParseInt(count, 10);
147 updateShape_();
148 }
149
150 /// <summary>
151 /// Populate the mutator's dialog with this block's components.
152 /// </summary>
153 /// <param name="workspace">Mutator's workspace.</param>
154 /// <returns>Root block in mutator.</returns>
155 public Block decompose(Workspace workspace)
156 {
157 var containerBlock = workspace.newBlock(SwitchCaseNumberContainerBlock.type_name);
158 containerBlock.initSvg();
159 var connection = containerBlock.getInput("STACK").connection;
160 for (var i = 0; i < cases_.Length; i++) {
161 Block caseBlock;
162 var value = getFieldValue("CONST" + i);
163 if (value != null) {
164 caseBlock = workspace.newBlock(SwitchCaseNumberConstBlock.type_name);
165 caseBlock.setFieldValue(value, "CONST");
166 }
167 else {
168 var min = getFieldValue("RANGE_MIN" + i);
169 var max = getFieldValue("RANGE_MAX" + i);
170 if ((min != null) && (max != null)) {
171 caseBlock = workspace.newBlock(SwitchCaseNumberRangeBlock.type_name);
172 caseBlock.setFieldValue(min, "RANGE_MIN");
173 caseBlock.setFieldValue(max, "RANGE_MAX");
174 }
175 else
176 continue;
177 }
178 caseBlock.initSvg();
179 connection.connect(caseBlock.previousConnection);
180 connection = caseBlock.nextConnection;
181 }
182 if (defaultCount_ != 0) {
183 var defaultBlock = workspace.newBlock(SwitchCaseNumberDefaultBlock.type_name);
184 defaultBlock.initSvg();
185 connection.connect(defaultBlock.previousConnection);
186 }
187 return containerBlock;
188 }
189
190 /// <summary>
191 /// Reconfigure this block based on the mutator dialog's components.
192 /// </summary>
193 /// <param name="containerBlock">Root block in mutator.</param>
194 public void compose(Block containerBlock)
195 {
196 var clauseBlock = containerBlock.getInputTargetBlock("STACK");
197 // Count number of inputs.
198 cases_ = new Tuple<string, string>[0];
199 defaultCount_ = 0;
200 var statementConnections = new Connection[0];
201 Connection defaultStatementConnection = null;
202 while (clauseBlock != null) {
203 switch (clauseBlock.type) {
204 case SwitchCaseNumberConstBlock.type_name: {
205 var value = clauseBlock.getFieldValue("CONST");
206 cases_.Push(new Tuple<string, string>(value, null));
207 statementConnections.Push(((SwitchCaseNumberConstBlock)clauseBlock).statementConnection_);
208 }
209 break;
210 case SwitchCaseNumberRangeBlock.type_name: {
211 var range_min = clauseBlock.getFieldValue("RANGE_MIN");
212 var range_max = clauseBlock.getFieldValue("RANGE_MAX");
213 cases_.Push(new Tuple<string, string>(range_min, range_max));
214 statementConnections.Push(((SwitchCaseNumberRangeBlock)clauseBlock).statementConnection_);
215 }
216 break;
217 case SwitchCaseNumberDefaultBlock.type_name: {
218 defaultCount_++;
219 defaultStatementConnection = ((SwitchCaseNumberDefaultBlock)clauseBlock).statementConnection_;
220 }
221 break;
222 default:
223 throw new Exception("Unknown block type.");
224 }
225 clauseBlock = (clauseBlock.nextConnection != null) ?
226 clauseBlock.nextConnection.targetBlock() : null;
227 }
228 updateShape_();
229 // Reconnect any child blocks.
230 for (var i = 0; i < cases_.Length; i++) {
231 Mutator.reconnect(statementConnections[i], this, "DO" + i);
232 }
233 Mutator.reconnect(defaultStatementConnection, this, "DEFAULT_DO");
234 }
235
236 /// <summary>
237 /// Store pointers to any connected child blocks.
238 /// </summary>
239 /// <param name="containerBlock">Root block in mutator.</param>
240 public void saveConnections(Block containerBlock)
241 {
242 var clauseBlock = containerBlock.getInputTargetBlock("STACK");
243 var i = 0;
244 while (clauseBlock != null) {
245 switch (clauseBlock.type) {
246 case SwitchCaseNumberConstBlock.type_name: {
247 var inputDo = getInput("DO" + i);
248 ((SwitchCaseNumberConstBlock)clauseBlock).statementConnection_ =
249 (inputDo != null) ? inputDo.connection.targetConnection : null;
250 i++;
251 }
252 break;
253 case SwitchCaseNumberRangeBlock.type_name: {
254 var inputDo = getInput("DO" + i);
255 ((SwitchCaseNumberRangeBlock)clauseBlock).statementConnection_ =
256 (inputDo != null) ? inputDo.connection.targetConnection : null;
257 i++;
258 }
259 break;
260 case SwitchCaseNumberDefaultBlock.type_name: {
261 var inputDo = getInput("DEFAULT_DO");
262 ((SwitchCaseNumberDefaultBlock)clauseBlock).statementConnection_ =
263 (inputDo != null) ? inputDo.connection.targetConnection : null;
264 }
265 break;
266 default:
267 throw new Exception("Unknown block type.");
268 }
269
270 clauseBlock = (clauseBlock.nextConnection != null) ?
271 clauseBlock.nextConnection.targetBlock() : null;
272 }
273 }
274
275 /// <summary>
276 /// Modify this block to have the correct number of inputs.
277 /// </summary>
278 private void updateShape_()
279 {
280 // Delete everything.
281 if (getInput("DEFAULT") != null) {
282 removeInput("DEFAULT");
283 removeInput("DEFAULT_DO");
284 }
285 var i = 0;
286 while (getInput("CASE" + i) != null) {
287 removeInput("CASE" + i);
288 removeInput("DO" + i);
289 i++;
290 }
291 // Rebuild block.
292 i = 0;
293 foreach (var c in cases_) {
294 if (c.Item2 == null) {
295 appendDummyInput("CASE" + i)
296 .appendField(new FieldNumber(c.Item1, "-Infinity", "Infinity", 0), "CONST" + i)
297 .appendField("の");
298 }
299 else {
300 appendDummyInput("CASE" + i)
301 .appendField(new FieldNumber(c.Item1, "-Infinity", "Infinity", 0), "RANGE_MIN" + i)
302 .appendField("から")
303 .appendField(new FieldNumber(c.Item2, "-Infinity", "Infinity", 0), "RANGE_MAX" + i)
304 .appendField("の");
305 }
306 appendStatementInput("DO" + i)
307 .appendField("とき");
308 i++;
309 }
310 if (defaultCount_ != 0) {
311 appendDummyInput("DEFAULT")
312 .appendField("その他の");
313 appendStatementInput("DEFAULT_DO")
314 .appendField("とき");
315 }
316 }
317 }
318
319 public class SwitchCaseNumberContainerBlock : Block
320 {
321 public const string type_name = "switch_case_number_container";
322
323 public SwitchCaseNumberContainerBlock()
324 : base(type_name)
325 {
326 }
327
328 public void init()
329 {
330 appendDummyInput()
331 .appendField("条件");
332 appendStatementInput("STACK");
333 setColour(210);
334 setTooltip("");
335 contextMenu = false;
336 }
337 }
338
339 public class SwitchCaseNumberConstBlock : Block
340 {
341 public const string type_name = "switch_case_number_const";
342 public Connection statementConnection_;
343
344 public SwitchCaseNumberConstBlock()
345 : base(type_name)
346 {
347 }
348
349 /// <summary>
350 /// Block for swicth/case/default condition.
351 /// </summary>
352 public void init()
353 {
354 setColour(210);
355 appendDummyInput()
356 .appendField("固定値")
357 .appendField("0", "CONST");
358 setPreviousStatement(true);
359 setNextStatement(true);
360 setTooltip("固定値の条件");
361 contextMenu = false;
362 }
363 }
364
365 public class SwitchCaseNumberRangeBlock : Block
366 {
367 public const string type_name = "switch_case_number_range";
368 public Connection statementConnection_;
369
370 public SwitchCaseNumberRangeBlock()
371 : base(type_name)
372 {
373 }
374
375 /// <summary>
376 /// Block for swicth/case/default condition.
377 /// </summary>
378 public void init()
379 {
380 setColour(210);
381 appendDummyInput()
382 .appendField("範囲")
383 .appendField("1", "RANGE_MIN")
384 .appendField("から")
385 .appendField("2", "RANGE_MAX");
386 setPreviousStatement(true);
387 setNextStatement(true);
388 setTooltip("範囲の条件");
389 contextMenu = false;
390 }
391 }
392
393 public class SwitchCaseNumberDefaultBlock : Block
394 {
395 public const string type_name = "switch_case_number_default";
396 public Connection statementConnection_;
397
398 public SwitchCaseNumberDefaultBlock()
399 : base(type_name)
400 {
401 }
402
403 /// <summary>
404 /// Block for swicth/case/default condition.
405 /// </summary>
406 public void init()
407 {
408 setColour(210);
409 appendDummyInput()
410 .appendField("その他");
411 setPreviousStatement(true);
412 setTooltip("条件に当てはまらなかった場合");
413 contextMenu = false;
414 }
415 }
416
417 public class SwitchCaseTextBlock : Block
418 {
419 public const string type_name = "switch_case_text";
420
421 internal Tuple<string, string>[] cases_;
422 internal int defaultCount_;
423
424 public SwitchCaseTextBlock()
425 : base(type_name)
426 {
427 }
428
429 /// <summary>
430 /// Block for swicth/case/default condition.
431 /// </summary>
432 public void init()
433 {
434 setHelpUrl("http://www.example.com/");
435 setColour(210);
436 appendValueInput("SWITCH")
437 .appendField("右の値が");
438 setPreviousStatement(true);
439 setNextStatement(true);
440 setMutator(new Mutator(new[] {
441 SwitchCaseTextConstBlock.type_name,
442 SwitchCaseTextRangeBlock.type_name,
443 SwitchCaseTextDefaultBlock.type_name }));
444 setTooltip(new Func<string>(() => {
445 if ((cases_.Length == 0) && (defaultCount_ == 0)) {
446 return "条件に合うブロックを実行";
447 }
448 else if ((cases_.Length == 0) && (defaultCount_ != 0)) {
449 return "条件に合うブロックを実行、合うものがなければ最後のブロックを実行";
450 }
451 else if ((cases_.Length != 0) && (defaultCount_ == 0)) {
452 return "条件に合うブロックを実行";
453 }
454 else if ((cases_.Length != 0) && (defaultCount_ != 0)) {
455 return "条件に合うブロックを実行、合うものがなければ最後のブロックを実行";
456 }
457 return "";
458 }));
459 cases_ = new Tuple<string, string>[] { new Tuple<string, string>("0", null) };
460 defaultCount_ = 0;
461 updateShape_();
462 }
463
464 /// <summary>
465 /// Create XML to represent the text of else-if and else inputs.
466 /// </summary>
467 /// <returns>XML storage element.</returns>
468 public Element mutationToDom(bool opt_caseIds)
469 {
470 if ((cases_.Length == 0) && (defaultCount_ == 0)) {
471 return null;
472 }
473 var container = Document.CreateElement("mutation");
474 for (var i = 0; i < cases_.Length; i++) {
475 Element caseInfo;
476 var value = getFieldValue("CONST" + i);
477 if (value != null) {
478 caseInfo = Document.CreateElement("case");
479 caseInfo.SetAttribute("value", value);
480 }
481 else {
482 var min = getFieldValue("RANGE_MIN" + i);
483 var max = getFieldValue("RANGE_MAX" + i);
484 if (min != null && max != null) {
485 caseInfo = Document.CreateElement("case");
486 caseInfo.SetAttribute("value", min + ".." + max);
487 }
488 else
489 continue;
490 }
491 container.AppendChild(caseInfo);
492 }
493 container.SetAttribute("default", defaultCount_.ToString());
494 return container;
495 }
496
497 /// <summary>
498 /// Parse XML to restore the else-if and else inputs.
499 /// </summary>
500 /// <param name="xmlElement">XML storage element.</param>
501 public void domToMutation(Element xmlElement)
502 {
503 cases_ = new Tuple<string, string>[0];
504 Element childNode;
505 for (var i = 0; (childNode = (dynamic)xmlElement.ChildNodes[i]) != null; i++) {
506 if (childNode.NodeName.ToLower() == "case") {
507 var value = childNode.GetAttribute("value");
508 if (value != null)
509 cases_.Push(new Tuple<string, string>(value, null));
510 else {
511 var min = childNode.GetAttribute("minimum");
512 var max = childNode.GetAttribute("maximum");
513 if ((min != null) && (max != null))
514 cases_.Push(new Tuple<string, string>(min, max));
515 }
516 }
517 }
518 var count = xmlElement.GetAttribute("default");
519 defaultCount_ = count == null ? 0 : Bridge.Script.ParseInt(count, 10);
520 updateShape_();
521 }
522
523 /// <summary>
524 /// Populate the mutator's dialog with this block's components.
525 /// </summary>
526 /// <param name="workspace">Mutator's workspace.</param>
527 /// <returns>Root block in mutator.</returns>
528 public Block decompose(Workspace workspace)
529 {
530 var containerBlock = workspace.newBlock(SwitchCaseTextContainerBlock.type_name);
531 containerBlock.initSvg();
532 var connection = containerBlock.getInput("STACK").connection;
533 for (var i = 0; i < cases_.Length; i++) {
534 Block caseBlock;
535 var value = getFieldValue("CONST" + i);
536 if (value != null) {
537 caseBlock = workspace.newBlock(SwitchCaseTextConstBlock.type_name);
538 caseBlock.setFieldValue(value, "CONST");
539 }
540 else {
541 var min = getFieldValue("RANGE_MIN" + i);
542 var max = getFieldValue("RANGE_MAX" + i);
543 if ((min != null) && (max != null)) {
544 caseBlock = workspace.newBlock(SwitchCaseTextRangeBlock.type_name);
545 caseBlock.setFieldValue(min, "RANGE_MIN");
546 caseBlock.setFieldValue(max, "RANGE_MAX");
547 }
548 else
549 continue;
550 }
551 caseBlock.initSvg();
552 connection.connect(caseBlock.previousConnection);
553 connection = caseBlock.nextConnection;
554 }
555 if (defaultCount_ != 0) {
556 var defaultBlock = workspace.newBlock(SwitchCaseTextDefaultBlock.type_name);
557 defaultBlock.initSvg();
558 connection.connect(defaultBlock.previousConnection);
559 }
560 return containerBlock;
561 }
562
563 /// <summary>
564 /// Reconfigure this block based on the mutator dialog's components.
565 /// </summary>
566 /// <param name="containerBlock">Root block in mutator.</param>
567 public void compose(Block containerBlock)
568 {
569 var clauseBlock = containerBlock.getInputTargetBlock("STACK");
570 // Count text of inputs.
571 cases_ = new Tuple<string, string>[0];
572 defaultCount_ = 0;
573 var statementConnections = new Connection[0];
574 Connection defaultStatementConnection = null;
575 while (clauseBlock != null) {
576 switch (clauseBlock.type) {
577 case SwitchCaseTextConstBlock.type_name: {
578 var value = clauseBlock.getFieldValue("CONST");
579 cases_.Push(new Tuple<string, string>(value, null));
580 statementConnections.Push(((SwitchCaseTextConstBlock)clauseBlock).statementConnection_);
581 }
582 break;
583 case SwitchCaseTextRangeBlock.type_name: {
584 var range_min = clauseBlock.getFieldValue("RANGE_MIN");
585 var range_max = clauseBlock.getFieldValue("RANGE_MAX");
586 cases_.Push(new Tuple<string, string>(range_min, range_max));
587 statementConnections.Push(((SwitchCaseTextRangeBlock)clauseBlock).statementConnection_);
588 }
589 break;
590 case SwitchCaseTextDefaultBlock.type_name: {
591 defaultCount_++;
592 defaultStatementConnection = ((SwitchCaseTextDefaultBlock)clauseBlock).statementConnection_;
593 }
594 break;
595 default:
596 throw new Exception("Unknown block type.");
597 }
598 clauseBlock = (clauseBlock.nextConnection != null) ?
599 clauseBlock.nextConnection.targetBlock() : null;
600 }
601 updateShape_();
602 // Reconnect any child blocks.
603 for (var i = 0; i <= cases_.Length; i++) {
604 Mutator.reconnect(statementConnections[i], this, "DO" + i);
605 }
606 Mutator.reconnect(defaultStatementConnection, this, "DEFAULT_DO");
607 }
608
609 /// <summary>
610 /// Store pointers to any connected child blocks.
611 /// </summary>
612 /// <param name="containerBlock">Root block in mutator.</param>
613 public void saveConnections(Block containerBlock)
614 {
615 var clauseBlock = containerBlock.getInputTargetBlock("STACK");
616 var i = 0;
617 while (clauseBlock != null) {
618 switch (clauseBlock.type) {
619 case SwitchCaseTextConstBlock.type_name: {
620 var inputDo = getInput("DO" + i);
621 ((SwitchCaseTextConstBlock)clauseBlock).statementConnection_ =
622 (inputDo != null) ? inputDo.connection.targetConnection : null;
623 i++;
624 }
625 break;
626 case SwitchCaseTextRangeBlock.type_name: {
627 var inputDo = getInput("DO" + i);
628 ((SwitchCaseTextRangeBlock)clauseBlock).statementConnection_ =
629 (inputDo != null) ? inputDo.connection.targetConnection : null;
630 i++;
631 }
632 break;
633 case SwitchCaseTextDefaultBlock.type_name: {
634 var inputDo = getInput("DEFAULT_DO");
635 ((SwitchCaseTextDefaultBlock)clauseBlock).statementConnection_ =
636 (inputDo != null) ? inputDo.connection.targetConnection : null;
637 }
638 break;
639 default:
640 throw new Exception("Unknown block type.");
641 }
642
643 clauseBlock = (clauseBlock.nextConnection != null) ?
644 clauseBlock.nextConnection.targetBlock() : null;
645 }
646 }
647
648 /// <summary>
649 /// Modify this block to have the correct text of inputs.
650 /// </summary>
651 private void updateShape_()
652 {
653 // Delete everything.
654 if (getInput("DEFAULT") != null) {
655 removeInput("DEFAULT");
656 removeInput("DEFAULT_DO");
657 }
658 var i = 0;
659 while (getInput("CASE" + i) != null) {
660 removeInput("CASE" + i);
661 removeInput("DO" + i);
662 i++;
663 }
664 // Rebuild block.
665 i = 0;
666 foreach (var c in cases_) {
667 if (c.Item2 == null) {
668 appendDummyInput("CASE" + i)
669 .appendField(new FieldTextInput(c.Item1), "CONST" + i)
670 .appendField("の");
671 }
672 else {
673 appendDummyInput("CASE" + i)
674 .appendField(new FieldTextInput(c.Item1), "RANGE_MIN" + i)
675 .appendField("から")
676 .appendField(new FieldTextInput(c.Item2), "RANGE_MAX" + i)
677 .appendField("の");
678 }
679 appendStatementInput("DO" + i)
680 .appendField("とき");
681 i++;
682 }
683 if (defaultCount_ != 0) {
684 appendDummyInput("DEFAULT")
685 .appendField("その他の");
686 appendStatementInput("DEFAULT_DO")
687 .appendField("とき");
688 }
689 }
690 }
691
692 public class SwitchCaseTextContainerBlock : Block
693 {
694 public const string type_name = "switch_case_text_container";
695
696 public SwitchCaseTextContainerBlock()
697 : base(type_name)
698 {
699 }
700
701 public void init()
702 {
703 appendDummyInput()
704 .appendField("条件");
705 appendStatementInput("STACK");
706 setColour(210);
707 setTooltip("");
708 contextMenu = false;
709 }
710 }
711
712 public class SwitchCaseTextConstBlock : Block
713 {
714 public const string type_name = "switch_case_text_const";
715 public Connection statementConnection_;
716
717 public SwitchCaseTextConstBlock()
718 : base(type_name)
719 {
720 }
721
722 /// <summary>
723 /// Block for swicth/case/default condition.
724 /// </summary>
725 public void init()
726 {
727 setColour(210);
728 appendDummyInput()
729 .appendField("固定値")
730 .appendField("0", "CONST");
731 setPreviousStatement(true);
732 setNextStatement(true);
733 setTooltip("固定値の条件");
734 contextMenu = false;
735 }
736 }
737
738 public class SwitchCaseTextRangeBlock : Block
739 {
740 public const string type_name = "switch_case_text_range";
741 public Connection statementConnection_;
742
743 public SwitchCaseTextRangeBlock()
744 : base(type_name)
745 {
746 }
747
748 /// <summary>
749 /// Block for swicth/case/default condition.
750 /// </summary>
751 public void init()
752 {
753 setColour(210);
754 appendDummyInput()
755 .appendField("範囲")
756 .appendField("a", "RANGE_MIN")
757 .appendField("から")
758 .appendField("b", "RANGE_MAX");
759 setPreviousStatement(true);
760 setNextStatement(true);
761 setTooltip("範囲の条件");
762 contextMenu = false;
763 }
764 }
765
766 public class SwitchCaseTextDefaultBlock : Block
767 {
768 public const string type_name = "switch_case_text_default";
769 public Connection statementConnection_;
770
771 public SwitchCaseTextDefaultBlock()
772 : base(type_name)
773 {
774 }
775
776 /// <summary>
777 /// Block for swicth/case/default condition.
778 /// </summary>
779 public void init()
780 {
781 setColour(210);
782 appendDummyInput()
783 .appendField("その他");
784 setPreviousStatement(true);
785 setTooltip("条件に当てはまらなかった場合");
786 contextMenu = false;
787 }
788 }
789
790 partial class Ruby
791 {
792 public node switch_case_number(SwitchCaseNumberBlock block)
793 {
794 // case/when/else condition.
795 var argument0 = valueToCode(block, "SWITCH");
796 if (argument0 == null) argument0 = new int_node(this, -1);
797 case_node.when_t[] code = new case_node.when_t[0];
798 for (int n = 0; n <= block.cases_.Length; n++) {
799 var branch = statementToCode(block, "DO" + n);
800 var argument1 = block.getFieldValue("CONST" + n);
801 if (argument1 != null) {
802 var when = new case_node.when_t() { body = branch };
803 when.value.Push(new int_node(this, argument1 == null ? 0 : Bridge.Script.ParseInt(argument1, 10)));
804 code.Push(when);
805 }
806 else {
807 var min = block.getFieldValue("RANGE_MIN" + n);
808 var max = block.getFieldValue("RANGE_MAX" + n);
809 if ((min != null) && (max != null)) {
810 var when = new case_node.when_t() { body = branch };
811 when.value.Push(new dot2_node(this,
812 new int_node(this, min == null ? 0 : Bridge.Script.ParseInt(min, 10)),
813 new int_node(this, max == null ? 0 : Bridge.Script.ParseInt(max, 10))));
814 code.Push(when);
815 }
816 }
817 }
818 if (block.defaultCount_ != 0) {
819 var branch = statementToCode(block, "DEFAULT_DO");
820 if (branch != null) {
821 var when = new case_node.when_t() { body = branch };
822 code.Push(when);
823 }
824 }
825 return new case_node(this, argument0, code);
826 }
827
828 public node switch_case_text(SwitchCaseTextBlock block)
829 {
830 // case/when/else condition.
831 var argument0 = valueToCode(block, "SWITCH");
832 if (argument0 == null) argument0 = new str_node(this, "");
833 case_node.when_t[] code = new case_node.when_t[0];
834 for (int n = 0; n <= block.cases_.Length; n++) {
835 var branch = statementToCode(block, "DO" + n);
836 var argument1 = block.getFieldValue("CONST" + n);
837 if (argument1 != null) {
838 var when = new case_node.when_t() { body = branch };
839 when.value.Push(new str_node(this, argument1));
840 code.Push(when);
841 }
842 else {
843 var min = block.getFieldValue("RANGE_MIN" + n);
844 var max = block.getFieldValue("RANGE_MAX" + n);
845 if ((min != null) && (max != null)) {
846 var when = new case_node.when_t() { body = branch };
847 when.value.Push(new dot2_node(this, new str_node(this, min), new str_node(this, max)));
848 code.Push(when);
849 }
850 }
851 }
852 if (block.defaultCount_ != 0) {
853 var branch = statementToCode(block, "DEFAULT_DO");
854 if (branch != null) {
855 var when = new case_node.when_t() { body = branch };
856 code.Push(when);
857 }
858 }
859 return new case_node(this, argument0, code);
860 }
861 }
862}
Note: See TracBrowser for help on using the repository browser.