@@ -25,6 +25,7 @@ import { Order } from 'blockly/python';
2525import { MRC_STYLE_STEPS } from '../themes/styles' ;
2626import { ExtendedPythonGenerator } from '../editor/extended_python_generator' ;
2727import { createStepFieldFlydown } from '../fields/field_flydown' ;
28+ import { BLOCK_NAME as MRC_JUMP_TO_STEP } from './mrc_jump_to_step' ;
2829import * as stepContainer from './mrc_step_container'
2930
3031export const BLOCK_NAME = 'mrc_steps' ;
@@ -76,11 +77,27 @@ const STEPS = {
7677 const stepContainerBlock = containerBlock as stepContainer . StepContainerBlock ;
7778 const stepItemBlocks : stepContainer . StepItemBlock [ ] = stepContainerBlock . getStepItemBlocks ( ) ;
7879
80+ const oldStepNames = [ ...this . mrcStepNames ] ;
7981 this . mrcStepNames = [ ] ;
8082 stepItemBlocks . forEach ( ( stepItemBlock ) => {
8183 this . mrcStepNames . push ( stepItemBlock . getName ( ) ) ;
8284 } ) ;
83- // TODO: Update any jump blocks to have the correct name
85+
86+ // Update jump blocks for any renamed steps
87+ const workspace = this . workspace ;
88+ const jumpBlocks = workspace . getBlocksByType ( MRC_JUMP_TO_STEP , false ) ;
89+ stepItemBlocks . forEach ( ( stepItemBlock , index ) => {
90+ const oldName = stepItemBlock . getOriginalName ( ) ;
91+ const newName = stepItemBlock . getName ( ) ;
92+ if ( oldName && oldName !== newName ) {
93+ jumpBlocks . forEach ( ( jumpBlock ) => {
94+ if ( jumpBlock . getFieldValue ( 'STEP_NAME' ) === oldName ) {
95+ jumpBlock . setFieldValue ( newName , 'STEP_NAME' ) ;
96+ }
97+ } ) ;
98+ }
99+ } ) ;
100+
84101 this . updateShape_ ( ) ;
85102 } ,
86103 decompose : function ( this : StepsBlock , workspace : Blockly . Workspace ) {
@@ -100,6 +117,7 @@ const STEPS = {
100117
101118 } ,
102119 mrcUpdateStepName : function ( this : StepsBlock , step : number , newName : string ) : string {
120+ const oldName = this . mrcStepNames [ step ] ;
103121 const otherNames = this . mrcStepNames . filter ( ( _name , index ) => index !== step ) ;
104122 let currentName = newName ;
105123
@@ -118,29 +136,96 @@ const STEPS = {
118136 }
119137 }
120138 this . mrcStepNames [ step ] = currentName ;
121- // TODO: Rename any jump blocks that refer to this step
122-
139+
140+ // Update all mrc_jump_to_step blocks that reference the old name
141+ if ( oldName !== currentName ) {
142+ const workspace = this . workspace ;
143+ const jumpBlocks = workspace . getBlocksByType ( MRC_JUMP_TO_STEP , false ) ;
144+ jumpBlocks . forEach ( ( jumpBlock ) => {
145+ if ( jumpBlock . getFieldValue ( 'STEP_NAME' ) === oldName ) {
146+ jumpBlock . setFieldValue ( currentName , 'STEP_NAME' ) ;
147+ }
148+ } ) ;
149+ }
123150
124151 return currentName ;
125152 } ,
126153 updateShape_ : function ( this : StepsBlock ) : void {
127- // some way of knowing what was there before and what is there now
128- let success = true ;
154+ // Build a map of step names to their current input indices
155+ const currentStepMap : { [ stepName : string ] : number } = { } ;
129156 let i = 0 ;
130- while ( success ) {
131- success = this . removeInput ( 'CONDITION_' + i , true ) ;
132- success = this . removeInput ( 'STEP_' + i , true ) ;
157+ while ( this . getInput ( 'CONDITION_' + i ) ) {
158+ const conditionInput = this . getInput ( 'CONDITION_' + i ) ;
159+ const field = conditionInput ?. fieldRow [ 0 ] ;
160+ if ( field ) {
161+ currentStepMap [ field . getValue ( ) ] = i ;
162+ }
133163 i ++ ;
134164 }
165+
166+ // For each new step position, find where it currently is (if it exists)
135167 for ( let j = 0 ; j < this . mrcStepNames . length ; j ++ ) {
136- const fieldFlydown = createStepFieldFlydown ( this . mrcStepNames [ j ] , true ) ;
137-
138- fieldFlydown . setValidator ( this . mrcUpdateStepName . bind ( this , j ) ) ;
139- this . appendValueInput ( 'CONDITION_' + j )
140- . appendField ( fieldFlydown )
141- . setCheck ( 'Boolean' )
142- . appendField ( Blockly . Msg . REPEAT_UNTIL ) ;
143- this . appendStatementInput ( 'STEP_' + j ) ;
168+ const stepName = this . mrcStepNames [ j ] ;
169+ const currentIndex = currentStepMap [ stepName ] ;
170+
171+ if ( currentIndex !== undefined && currentIndex !== j ) {
172+ // Step exists but is at wrong position - move it
173+ const conditionConnection = this . getInput ( 'CONDITION_' + currentIndex ) ?. connection ?. targetConnection ;
174+ const stepConnection = this . getInput ( 'STEP_' + currentIndex ) ?. connection ?. targetConnection ;
175+
176+ // Temporarily disconnect
177+ if ( conditionConnection ) conditionConnection . disconnect ( ) ;
178+ if ( stepConnection ) stepConnection . disconnect ( ) ;
179+
180+ // Remove old inputs
181+ this . removeInput ( 'CONDITION_' + currentIndex , false ) ;
182+ this . removeInput ( 'STEP_' + currentIndex , false ) ;
183+
184+ // Create new inputs at correct position
185+ const fieldFlydown = createStepFieldFlydown ( stepName , true ) ;
186+ fieldFlydown . setValidator ( this . mrcUpdateStepName . bind ( this , j ) ) ;
187+
188+ this . appendValueInput ( 'CONDITION_' + j )
189+ . appendField ( fieldFlydown )
190+ . setCheck ( 'Boolean' )
191+ . appendField ( Blockly . Msg . REPEAT_UNTIL ) ;
192+ this . appendStatementInput ( 'STEP_' + j ) ;
193+
194+ // Reconnect
195+ if ( conditionConnection ) {
196+ this . getInput ( 'CONDITION_' + j ) ?. connection ?. connect ( conditionConnection ) ;
197+ }
198+ if ( stepConnection ) {
199+ this . getInput ( 'STEP_' + j ) ?. connection ?. connect ( stepConnection ) ;
200+ }
201+
202+ delete currentStepMap [ stepName ] ;
203+ } else if ( currentIndex !== undefined ) {
204+ // Step is at correct position - just update the field
205+ const conditionInput = this . getInput ( 'CONDITION_' + j ) ;
206+ const field = conditionInput ?. fieldRow [ 0 ] ;
207+ if ( field && field . getValue ( ) !== stepName ) {
208+ field . setValue ( stepName ) ;
209+ }
210+ delete currentStepMap [ stepName ] ;
211+ } else {
212+ // Step doesn't exist - create it
213+ const fieldFlydown = createStepFieldFlydown ( stepName , true ) ;
214+ fieldFlydown . setValidator ( this . mrcUpdateStepName . bind ( this , j ) ) ;
215+
216+ this . appendValueInput ( 'CONDITION_' + j )
217+ . appendField ( fieldFlydown )
218+ . setCheck ( 'Boolean' )
219+ . appendField ( Blockly . Msg . REPEAT_UNTIL ) ;
220+ this . appendStatementInput ( 'STEP_' + j ) ;
221+ }
222+ }
223+
224+ // Remove any leftover inputs (steps that were deleted)
225+ for ( const stepName in currentStepMap ) {
226+ const index = currentStepMap [ stepName ] ;
227+ this . removeInput ( 'CONDITION_' + index , false ) ;
228+ this . removeInput ( 'STEP_' + index , false ) ;
144229 }
145230 } ,
146231 mrcGetStepNames : function ( this : StepsBlock ) : string [ ] {
0 commit comments