@@ -27,12 +27,17 @@ import { Order } from 'blockly/python';
27
27
import { ExtendedPythonGenerator } from '../editor/extended_python_generator' ;
28
28
import * as commonStorage from '../storage/common_storage' ;
29
29
import { renameMethodCallers , mutateMethodCallers } from './mrc_call_python_function'
30
+ import * as toolboxItems from '../toolbox/items' ;
31
+ import { getClassData } from './utils/python' ;
32
+ import { FunctionData } from './utils/python_json_types' ;
30
33
import { findConnectedBlocksOfType } from './utils/find_connected_blocks' ;
31
34
import { BLOCK_NAME as MRC_GET_PARAMETER_BLOCK_NAME } from './mrc_get_parameter' ;
32
35
import { MUTATOR_BLOCK_NAME , PARAM_CONTAINER_BLOCK_NAME , MethodMutatorArgBlock } from './mrc_param_container'
33
36
34
37
export const BLOCK_NAME = 'mrc_class_method_def' ;
35
38
39
+ const FIELD_METHOD_NAME = 'NAME' ;
40
+
36
41
export type Parameter = {
37
42
name : string ,
38
43
type ?: string ,
@@ -88,7 +93,7 @@ const CLASS_METHOD_DEF = {
88
93
*/
89
94
init : function ( this : ClassMethodDefBlock ) : void {
90
95
this . appendDummyInput ( "TITLE" )
91
- . appendField ( '' , 'NAME' ) ;
96
+ . appendField ( '' , FIELD_METHOD_NAME ) ;
92
97
this . setOutput ( false ) ;
93
98
this . setStyle ( MRC_STYLE_FUNCTIONS ) ;
94
99
this . appendStatementInput ( 'STACK' ) . appendField ( '' ) ;
@@ -143,27 +148,27 @@ const CLASS_METHOD_DEF = {
143
148
} ) ;
144
149
} ) ;
145
150
this . updateBlock_ ( ) ;
146
- mutateMethodCallers ( this . workspace , this . getFieldValue ( 'NAME' ) , this . saveExtraState ( ) ) ;
151
+ mutateMethodCallers ( this . workspace , this . getFieldValue ( FIELD_METHOD_NAME ) , this . saveExtraState ( ) ) ;
147
152
} ,
148
153
/**
149
154
* Update the block to reflect the newly loaded extra state.
150
155
*/
151
156
updateBlock_ : function ( this : ClassMethodDefBlock ) : void {
152
- const name = this . getFieldValue ( 'NAME' ) ;
157
+ const name = this . getFieldValue ( FIELD_METHOD_NAME ) ;
153
158
const input = this . getInput ( 'TITLE' ) ;
154
159
if ( ! input ) {
155
160
return ;
156
161
}
157
- input . removeField ( 'NAME' ) ;
162
+ input . removeField ( FIELD_METHOD_NAME ) ;
158
163
159
164
if ( this . mrcCanChangeSignature ) {
160
165
const nameField = new Blockly . FieldTextInput ( name ) ;
161
- input . insertFieldAt ( 0 , nameField , 'NAME' ) ;
166
+ input . insertFieldAt ( 0 , nameField , FIELD_METHOD_NAME ) ;
162
167
this . setMutator ( new Blockly . icons . MutatorIcon ( [ MUTATOR_BLOCK_NAME ] , this ) ) ;
163
168
nameField . setValidator ( this . mrcNameFieldValidator . bind ( this , nameField ) ) ;
164
169
}
165
170
else {
166
- input . insertFieldAt ( 0 , createFieldNonEditableText ( name ) , 'NAME' ) ;
171
+ input . insertFieldAt ( 0 , createFieldNonEditableText ( name ) , FIELD_METHOD_NAME ) ;
167
172
//Case because a current bug in blockly where it won't allow passing null to Blockly.Block.setMutator makes it necessary.
168
173
( this as Blockly . BlockSvg ) . setMutator ( null ) ;
169
174
}
@@ -189,7 +194,7 @@ const CLASS_METHOD_DEF = {
189
194
paramBlock . nextConnection && paramBlock . nextConnection . targetBlock ( ) ;
190
195
}
191
196
this . mrcUpdateParams ( ) ;
192
- mutateMethodCallers ( this . workspace , this . getFieldValue ( 'NAME' ) , this . saveExtraState ( ) ) ;
197
+ mutateMethodCallers ( this . workspace , this . getFieldValue ( FIELD_METHOD_NAME ) , this . saveExtraState ( ) ) ;
193
198
} ,
194
199
decompose : function ( this : ClassMethodDefBlock , workspace : Blockly . Workspace ) {
195
200
// This is a special sub-block that only gets created in the mutator UI.
@@ -268,7 +273,7 @@ const CLASS_METHOD_DEF = {
268
273
return this . mrcCanChangeSignature ;
269
274
} ,
270
275
getMethodName : function ( this : ClassMethodDefBlock ) : string {
271
- return this . getFieldValue ( 'NAME' ) ;
276
+ return this . getFieldValue ( FIELD_METHOD_NAME ) ;
272
277
} ,
273
278
} ;
274
279
@@ -315,7 +320,7 @@ function isMethodNameUsed(
315
320
if ( block === opt_exclude ) {
316
321
continue ;
317
322
}
318
- if ( nameLowerCase === block . getFieldValue ( 'NAME' ) . toLowerCase ( ) ) {
323
+ if ( nameLowerCase === block . getFieldValue ( FIELD_METHOD_NAME ) . toLowerCase ( ) ) {
319
324
return true ;
320
325
}
321
326
const classMethodDefBlock = block as ClassMethodDefBlock ;
@@ -335,7 +340,7 @@ export const pythonFromBlock = function (
335
340
block : ClassMethodDefBlock ,
336
341
generator : ExtendedPythonGenerator ,
337
342
) {
338
- const blocklyName = block . mrcPythonMethodName ? block . mrcPythonMethodName : block . getFieldValue ( 'NAME' ) ;
343
+ const blocklyName = block . mrcPythonMethodName ? block . mrcPythonMethodName : block . getFieldValue ( FIELD_METHOD_NAME ) ;
339
344
340
345
const funcName = generator . getProcedureName ( blocklyName ) ;
341
346
@@ -415,7 +420,7 @@ export const pythonFromBlock = function (
415
420
// Update the mrcMethod.
416
421
block . mrcMethod = {
417
422
blockId : block . id ,
418
- visibleName : block . getFieldValue ( 'NAME' ) ,
423
+ visibleName : block . getFieldValue ( FIELD_METHOD_NAME ) ,
419
424
pythonName : funcName ,
420
425
returnType : block . mrcReturnType ,
421
426
args : [ {
@@ -433,3 +438,58 @@ export const pythonFromBlock = function (
433
438
434
439
return '' ;
435
440
}
441
+
442
+ // Functions used for creating blocks for the toolbox.
443
+
444
+ export function createCustomMethodBlock ( ) : toolboxItems . Block {
445
+ const extraState : ClassMethodDefExtraState = {
446
+ canChangeSignature : true ,
447
+ canBeCalledWithinClass : true ,
448
+ canBeCalledOutsideClass : true ,
449
+ returnType : 'None' ,
450
+ params : [ ] ,
451
+ } ;
452
+ const fields : { [ key : string ] : any } = { } ;
453
+ fields [ FIELD_METHOD_NAME ] = 'my_method' ;
454
+ return new toolboxItems . Block ( BLOCK_NAME , extraState , fields , null ) ;
455
+ }
456
+
457
+ export function getBaseClassBlocks (
458
+ baseClassName : string ) : toolboxItems . Block [ ] {
459
+ const blocks : toolboxItems . Block [ ] = [ ] ;
460
+ const classData = getClassData ( baseClassName ) ;
461
+ if ( classData ) {
462
+ classData . instanceMethods . forEach ( functionData => {
463
+ blocks . push ( createClassMethodDefBlock (
464
+ functionData ,
465
+ /* canChangeSignature */ false ,
466
+ /* canBeCalledWithinClass */ false ,
467
+ /* canBeCalledOutsideClass */ false ,
468
+ ) ) ;
469
+ } ) ;
470
+ }
471
+ return blocks ;
472
+ }
473
+
474
+ function createClassMethodDefBlock (
475
+ functionData : FunctionData ,
476
+ canChangeSignature : boolean ,
477
+ canBeCalledWithinClass : boolean ,
478
+ canBeCalledOutsideClass : boolean ) : toolboxItems . Block {
479
+ const extraState : ClassMethodDefExtraState = {
480
+ canChangeSignature,
481
+ canBeCalledWithinClass,
482
+ canBeCalledOutsideClass,
483
+ returnType : functionData . returnType ,
484
+ params : [ ] ,
485
+ } ;
486
+ for ( let i = 1 ; i < functionData . args . length ; i ++ ) {
487
+ extraState . params . push ( {
488
+ 'name' : functionData . args [ i ] . name ,
489
+ 'type' : functionData . args [ i ] . type ,
490
+ } ) ;
491
+ }
492
+ const fields : { [ key : string ] : any } = { } ;
493
+ fields [ FIELD_METHOD_NAME ] = functionData . functionName ;
494
+ return new toolboxItems . Block ( BLOCK_NAME , extraState , fields , null ) ;
495
+ }
0 commit comments