@@ -124,6 +124,136 @@ Blockly.Blocks['operator_divide'] = {
124124 }
125125} ;
126126
127+ Blockly . Blocks [ 'operator_expandableMath' ] = {
128+ /**
129+ * pm: Block for performing multiple math operations (determined by user)
130+ * @this Blockly.Block
131+ */
132+ init : function ( ) {
133+ this . jsonInit ( {
134+ "message0" : '%1 %2' ,
135+ "args0" : [
136+ {
137+ "type" : "field_expandable_remove" ,
138+ "name" : "REMOVE"
139+ } ,
140+ {
141+ "type" : "field_expandable_add" ,
142+ "name" : "ADD"
143+ }
144+ ] ,
145+ "category" : Blockly . Categories . operators ,
146+ "extensions" : [ "colours_operators" , "output_number" ]
147+ } ) ;
148+
149+ this . inputs_ = 2 ;
150+ if ( this . isInFlyout ) {
151+ const input1 = this . appendValueInput ( "NUM1" ) ;
152+ this . fillInBlock ( input1 . connection , 0 ) ;
153+ const input2 = this . appendValueInput ( "NUM2" ) ;
154+ input2 . appendField ( this . menuGenerator ( ) ) ;
155+ this . fillInBlock ( input2 . connection , 1 ) ;
156+ }
157+ } ,
158+
159+ menuGenerator : function ( ) {
160+ const dropdown = new Blockly . FieldDropdown ( function ( ) {
161+ return [
162+ [ "+" , "+" ] , [ "-" , "-" ] ,
163+ [ "*" , "*" ] , [ "/" , "/" ] ,
164+ [ "^" , "^" ] ,
165+ ] ;
166+ } ) ;
167+ const ogSetValue = dropdown . setValue ;
168+ dropdown . setValue = function ( value , omitMutation ) {
169+ const srcBlock = this . sourceBlock_ ;
170+ let oldMutation ;
171+ if ( ! omitMutation ) oldMutation = Blockly . Xml . domToText ( srcBlock . mutationToDom ( ) ) ;
172+
173+ ogSetValue . call ( this , value ) ;
174+ if ( ! omitMutation ) {
175+ const newMutation = Blockly . Xml . domToText ( srcBlock . mutationToDom ( ) ) ;
176+ Blockly . Events . fire ( new Blockly . Events . BlockChange (
177+ srcBlock , 'mutation' , null , oldMutation , newMutation
178+ ) ) ;
179+ }
180+ }
181+ return dropdown ;
182+ } ,
183+ fillInBlock : function ( connection , index ) {
184+ if ( connection . sourceBlock_ . isInsertionMarker_ ) return ;
185+ const block = this . workspace . newBlock ( 'math_number' ) ;
186+ block . setShadow ( true ) ;
187+ block . initSvg ( ) ;
188+ block . render ( false ) ;
189+ block . outputConnection . connect ( connection ) ;
190+ } ,
191+
192+ mutationToDom : function ( ) {
193+ // on save
194+ const container = document . createElement ( "mutation" ) ;
195+ let number = Number ( this . inputs_ ) ;
196+ if ( isNaN ( number ) ) number = 1 ;
197+ container . setAttribute ( "inputcount" , String ( number ) ) ;
198+ let orderedOperations = "" ;
199+ for ( var i = 1 ; i < this . inputList . length ; i ++ ) {
200+ const input = this . inputList [ i ] ;
201+ if ( input . fieldRow [ 0 ] ) orderedOperations += input . fieldRow [ 0 ] . getValue ( ) ;
202+ }
203+ container . setAttribute ( "menuvalues" , orderedOperations ) ;
204+ return container ;
205+ } ,
206+
207+ domToMutation : function ( xmlElement ) {
208+ // on load
209+ const inputCount = Number ( xmlElement . getAttribute ( "inputcount" ) ) ;
210+ const menuValues = String ( xmlElement . getAttribute ( "menuvalues" ) ) ;
211+ this . inputs_ = isNaN ( inputCount ) ? 0 : inputCount ;
212+ for ( let i = 0 ; i < this . inputs_ ; i ++ ) {
213+ const input = this . appendValueInput ( `NUM${ i + 1 } ` ) ;
214+ if ( i > 0 ) {
215+ const menu = input . appendField ( this . menuGenerator ( ) ) ;
216+ menu . fieldRow [ 0 ] . setValue ( menuValues [ i - 1 ] ? menuValues [ i - 1 ] : "+" , true ) ;
217+ }
218+ this . fillInBlock ( input . connection , i ) ;
219+ }
220+ queueMicrotask ( ( ) => {
221+ const connections = this . getConnections_ ( ) ;
222+ for ( let i = 1 ; i < connections . length ; i ++ ) {
223+ const block = connections [ i ] . targetBlock ( ) ;
224+ if ( ! block ) continue ;
225+ if ( ! block . category_ && ! block . isShadow ( ) ) block . dispose ( ) ;
226+ }
227+ } ) ;
228+ } ,
229+
230+ onExpandableButtonClicked_ : function ( isAdding ) {
231+ // Create an event group to keep field value and mutator in sync
232+ // Return null at the end because setValue is called here already.
233+ Blockly . Events . setGroup ( true ) ;
234+ var oldMutation = Blockly . Xml . domToText ( this . mutationToDom ( ) ) ;
235+ if ( isAdding ) {
236+ this . inputs_ ++ ;
237+ const number = this . inputs_ ;
238+ const newInput = this . appendValueInput ( `NUM${ number } ` ) ;
239+ newInput . appendField ( this . menuGenerator ( ) ) ;
240+ this . fillInBlock ( newInput . connection , number - 1 ) ;
241+ } else if ( this . inputs_ > 1 ) {
242+ const number = this . inputs_ ;
243+ this . removeInput ( `NUM${ number } ` ) ;
244+ this . inputs_ -- ;
245+ }
246+ this . initSvg ( ) ;
247+ if ( this . rendered ) this . render ( ) ;
248+
249+ const newMutation = Blockly . Xml . domToText ( this . mutationToDom ( ) ) ;
250+ Blockly . Events . fire ( new Blockly . Events . BlockChange (
251+ this , 'mutation' , null , oldMutation , newMutation
252+ ) ) ;
253+ Blockly . Events . setGroup ( false ) ;
254+ }
255+ } ;
256+
127257Blockly . Blocks [ 'operator_random' ] = {
128258 /**
129259 * Block for picking a random number.
@@ -518,7 +648,6 @@ Blockly.Blocks['operator_join3'] = {
518648 }
519649} ;
520650
521-
522651Blockly . Blocks [ 'operators_expandablejoininputs' ] = {
523652 /**
524653 * pm: Block for joining strings together (determined by user)
@@ -558,7 +687,7 @@ Blockly.Blocks['operators_expandablejoininputs'] = {
558687 block . setFieldValue ( text ? text : "..." , "TEXT" ) ;
559688 block . setShadow ( true ) ;
560689 block . initSvg ( ) ;
561- block . render ( true ) ;
690+ block . render ( false ) ;
562691 block . outputConnection . connect ( connection ) ;
563692 } ,
564693
@@ -608,8 +737,9 @@ Blockly.Blocks['operators_expandablejoininputs'] = {
608737 if ( this . rendered ) this . render ( ) ;
609738
610739 var newMutation = Blockly . Xml . domToText ( this . mutationToDom ( ) ) ;
611- Blockly . Events . fire ( new Blockly . Events . BlockChange ( this ,
612- 'mutation' , null , oldMutation , newMutation ) ) ;
740+ Blockly . Events . fire ( new Blockly . Events . BlockChange (
741+ this , 'mutation' , null , oldMutation , newMutation
742+ ) ) ;
613743 Blockly . Events . setGroup ( false ) ;
614744 }
615745} ;
0 commit comments