@@ -24,13 +24,21 @@ import {Order} from 'blockly/python';
2424
2525import { MRC_STYLE_STEPS } from '../themes/styles' ;
2626import { ExtendedPythonGenerator } from '../editor/extended_python_generator' ;
27- import { createStepFieldFlydown } from '../fields/field_flydown' ;
27+ import { createStepFieldFlydown , FieldFlydown } from '../fields/field_flydown' ;
2828import * as stepContainer from './mrc_step_container'
2929
3030export const BLOCK_NAME = 'mrc_steps' ;
3131// const MUTATOR_BLOCK_NAME = 'steps_mutatorarg';
3232
3333
34+ /** Extra state for serialising call_python_* blocks. */
35+ type StepsExtraState = {
36+ /**
37+ * The steps
38+ */
39+ stepNames : string [ ] ,
40+ } ;
41+
3442export type StepsBlock = Blockly . Block & StepsMixin & Blockly . BlockSvg ;
3543interface StepsMixin extends StepsMixinType {
3644 mrcStepNames : string [ ] ;
@@ -50,6 +58,17 @@ const STEPS = {
5058 this . setMutator ( stepContainer . getMutatorIcon ( this ) ) ;
5159 this . updateShape_ ( ) ;
5260 } ,
61+ saveExtraState : function ( this : StepsBlock ) : StepsExtraState {
62+ return {
63+ stepNames : this . mrcStepNames ,
64+ } ;
65+ } ,
66+ loadExtraState : function ( this : StepsBlock , state : StepsExtraState ) : void {
67+ if ( state && state . stepNames ) {
68+ this . mrcStepNames = state . stepNames ;
69+ this . updateShape_ ( ) ;
70+ }
71+ } ,
5372 compose : function ( this : StepsBlock , containerBlock : Blockly . Block ) {
5473 if ( containerBlock . type !== stepContainer . STEP_CONTAINER_BLOCK_NAME ) {
5574 throw new Error ( 'compose: containerBlock.type should be ' + stepContainer . STEP_CONTAINER_BLOCK_NAME ) ;
@@ -80,6 +99,30 @@ const STEPS = {
8099 } ,
81100 mrcOnChange : function ( this : StepsBlock ) : void {
82101
102+ } ,
103+ mrcUpdateStepName : function ( this : StepsBlock , step : number , newName : string ) : string {
104+ const otherNames = this . mrcStepNames . filter ( ( _name , index ) => index !== step ) ;
105+ let currentName = newName ;
106+
107+ // Make name unique if it conflicts
108+ while ( otherNames . includes ( currentName ) ) {
109+ // Check if currentName ends with a number
110+ const match = currentName . match ( / ^ ( .* ?) ( \d + ) $ / ) ;
111+ if ( match ) {
112+ // If it ends with a number, increment it
113+ const baseName = match [ 1 ] ;
114+ const number = parseInt ( match [ 2 ] , 10 ) ;
115+ currentName = baseName + ( number + 1 ) ;
116+ } else {
117+ // If it doesn't end with a number, append 2
118+ currentName = currentName + '2' ;
119+ }
120+ }
121+ this . mrcStepNames [ step ] = currentName ;
122+ // TODO: Rename any jump blocks that refer to this step
123+
124+
125+ return currentName ;
83126 } ,
84127 updateShape_ : function ( this : StepsBlock ) : void {
85128 // some way of knowing what was there before and what is there now
@@ -91,13 +134,19 @@ const STEPS = {
91134 i ++ ;
92135 }
93136 for ( let j = 0 ; j < this . mrcStepNames . length ; j ++ ) {
137+ const fieldFlydown = createStepFieldFlydown ( this . mrcStepNames [ j ] , true ) ;
138+
139+ fieldFlydown . setValidator ( this . mrcUpdateStepName . bind ( this , j ) ) ;
94140 this . appendValueInput ( 'CONDITION_' + j )
95- . appendField ( createStepFieldFlydown ( this . mrcStepNames [ j ] , true ) )
141+ . appendField ( fieldFlydown )
96142 . setCheck ( 'Boolean' )
97143 . appendField ( Blockly . Msg . REPEAT_UNTIL ) ;
98144 this . appendStatementInput ( 'STEP_' + j ) ;
99145 }
100146 } ,
147+ mrcGetStepNames : function ( this : StepsBlock ) : string [ ] {
148+ return this . mrcStepNames ;
149+ }
101150} ;
102151
103152export const setup = function ( ) {
0 commit comments