@@ -9,14 +9,31 @@ def initialize_blockly( blockly_id='blocklyDiv', toolbox_id='toolbox', on_change
99 print 'initialize_blockly'
1010 if len ( BlocklyBlockGenerators .keys () ):
1111 toolbox = document .getElementById ( toolbox_id )
12- cat = document .createElement ('category' )
13- cat .setAttribute ('name' , 'Callbacks' )
14- toolbox .appendChild ( cat )
12+ defaults = []
13+ cats = {}
1514 for block_name in BlocklyBlockGenerators .keys ():
1615 e = document .createElement ('block' )
1716 e .setAttribute ('type' , block_name )
18- cat .appendChild ( e )
1917
18+ b = BlocklyBlockGenerators [ block_name ]
19+ if b .category :
20+ if b .category in cats :
21+ cats [ b .category ].appendChild ( e )
22+ else :
23+ cat = document .createElement ('category' )
24+ cat .setAttribute ('name' , b .category )
25+ cat .appendChild ( e )
26+ toolbox .appendChild ( cat )
27+ cats [ b .category ] = cat
28+ else :
29+ defaults .append ( e )
30+
31+ if len (defaults ):
32+ cat = document .createElement ('category' )
33+ cat .setAttribute ('name' , 'Callbacks' )
34+ toolbox .appendChild ( cat )
35+ for e in defaults :
36+ cat .appendChild ( e )
2037
2138 with javascript :
2239 Blockly .inject (
@@ -50,15 +67,16 @@ class BlocklyBlock:
5067 . a bare block can have no inputs or output, and no previous or next statement notches.
5168
5269 '''
53- def __init__ (self , name , title = None , color = None ):
54- self .setup ( name , title = title , color = color )
70+ def __init__ (self , name , title = None , color = None , category = None ):
71+ self .setup ( name , title = title , color = color , category = None )
5572
56- def setup (self , name , title = None , color = None ):
73+ def setup (self , name , title = None , color = None , category = None ):
5774 if name in BlocklyBlockGenerators : raise TypeError
5875 BlocklyBlockGenerators [ name ] = self
5976 self .name = name
6077 self .title = title
6178 self .color = color
79+ self .category = category
6280 self .input_values = []
6381 self .input_statements = []
6482 self .output = None
@@ -70,16 +88,21 @@ def setup(self, name, title=None, color=None):
7088 self .on_click_callback = None
7189
7290 def callback (self , jsfunc ): ## decorator
91+ print '@callback' , jsfunc
7392 self .set_external_function ( jsfunc .NAME )
93+ with javascript : arr = jsfunc .args_signature
94+ print 'arr' , arr
95+ for i in range (arr .length ):
96+ self .add_input_value ( arr [i ] )
7497 return jsfunc
7598
7699 def set_on_click_callback (self , callback ):
77100 self .on_click_callback = callback
78101
79102 def set_external_function (self , func_name ):
80103 self .external_function = func_name
81- if self .title :
82- self .title = self . title + ': ' + func_name
104+ if not self .title :
105+ self .title = func_name
83106
84107 def set_output (self , output ):
85108 if self .stack_input : raise TypeError
@@ -105,13 +128,15 @@ def add_input_value(self, name=None, type=None, title=None):
105128 elif type == 'Number' : pass
106129 elif type == 'String' : pass
107130 elif type == 'Array' : pass
108- else : raise TypeError
131+ #else: raise TypeError
132+ if title is None : title = name
109133 self .input_values .append (
110134 {'name' :name , 'type' :type , 'title' :title }
111135 )
112136
113137 def add_input_statement (self , name = None , title = None ):
114138 if name is None : raise TypeError
139+ if title is None : title = name
115140 self .input_statements .append (
116141 {'name' :name , 'title' :title }
117142 )
@@ -127,9 +152,9 @@ def bind_block(self):
127152 raise TypeError
128153
129154 title = self .title
130- input_values = self .input_values
131- input_statements = self .input_statements
132155 color = self .color
156+ input_values = self .input_values .js_object
157+ input_statements = self .input_statements .js_object
133158
134159 with javascript :
135160 def init ():
@@ -144,11 +169,19 @@ def init():
144169 if stack_output :
145170 this .setNextStatement ( True )
146171
147- for input in input_values : # input[...]['name'] for a dict becomes: input.__dict__.js_object['name']
148- this .appendValueInput ( input ['name' ] ).setCheck ( input ['type' ] ).appendTitle ( input ['title' ] )
149-
150- for input in input_statements :
172+ i = 0
173+ while i < input_values .length :
174+ input = input_values [i ][...]
175+ if input ['type' ]:
176+ this .appendValueInput (input ['name' ] ).setCheck ( input ['type' ] ).appendTitle ( '<' + input ['type' ]+ '> ' + input ['title' ] ).setAlign (Blockly .ALIGN_RIGHT )
177+ else :
178+ this .appendValueInput (input ['name' ] ).appendTitle ( input ['title' ] ).setAlign (Blockly .ALIGN_RIGHT )
179+ i += 1
180+ i = 0
181+ while i < input_statements .length :
182+ input = input_statements [i ][...]
151183 this .appendStatementInput ( input ['name' ] ).appendTitle ( input ['title' ] )
184+ i += 1
152185
153186 if output == '*' :
154187 this .setOutput ( True , null ) ## allows output of any type
@@ -161,22 +194,30 @@ def init():
161194 def bind_generator (self ):
162195 block_name = self .name
163196 external_function = self .external_function
164- input_values = self .input_values
165- input_statements = self .input_statements
166197 is_statement = self .is_statement
198+ input_values = self .input_values .js_object
199+ input_statements = self .input_statements .js_object
167200
168201 with javascript :
169202 def generator (block ):
170203 code = ''
171204
172205 args = []
173- for input in input_values :
174- a = Blockly .Python .valueToCode (block , input ['name' ], Blockly .Python .ORDER_NONE )
175- args .push ( a )
176206
177- for input in input_statements :
207+ i = 0
208+ while i < input_values .length :
209+ input = input_values [i ][...]
210+ a = Blockly .Python .valueToCode (block , input ['name' ], Blockly .Python .ORDER_NONE )
211+ if a is not null : ## blockly API not correct? is says this will return null when nothing is connected.
212+ args .push ( a )
213+ i += 1
214+ i = 0
215+ while i < input_statements .length :
216+ input = input_statements [i ][...]
178217 a = Blockly .Python .statementToCode (block , input ['name' ])
179- args .push ( a )
218+ if a != '' : ## blockly API would be better not returning an empty string here, in case we wanted to set an empty string
219+ args .push ( a )
220+ i += 1
180221
181222 if external_function :
182223 code += external_function + '(' + ',' .join (args ) + ')'
@@ -198,15 +239,15 @@ class StatementBlock( BlocklyBlock ):
198239 '''
199240 A statement-block has a previous and/or next statement notch: stack_input and/or stack_output
200241 '''
201- def __init__ (self , name , title = None , stack_input = False , stack_output = False , color = 150 ):
202- self .setup ( name , title = title , color = color )
242+ def __init__ (self , name , title = None , stack_input = False , stack_output = False , color = 150 , category = None ):
243+ self .setup ( name , title = title , color = color , category = category )
203244 self .make_statement ( stack_input = stack_input , stack_output = stack_output )
204245
205246
206247class ValueBlock ( BlocklyBlock ):
207- def __init__ (self , name , title = None , output = None , color = 120 ):
248+ def __init__ (self , name , title = None , output = None , color = 120 , category = None ):
208249 if output is None : raise TypeError
209- self .setup ( name , title = title , color = color )
250+ self .setup ( name , title = title , color = color , category = category )
210251 self .set_output ( output )
211252
212253
0 commit comments