Hacking around with Google Blockly and Blender. Blockly inside of Blender could be useful for game play scripting and other things. At the moment this is just a proof of concept how to get WebKit and Blockly to load inside of Blender and have simple two-way communication.
This hack is standalone, and already includes Blender2.63 compiled by natewiebe13 from Graphicall.org. To get this running, all you need to do is: "sudo apt-get install libwebkitgtk-3.0-dev" download hereHello World Source Code
import bpy def myprocedure(): ''' user defined function, in blockly just define an empty function, and give it the name "myprocedure" ''' bpy.ops.mesh.primitive_monkey_add() ############################################### import os, sys, time, ctypes sys.path.append( os.path.abspath('.') ) import webkitgtk as webkit import Blender # brett's ctypes wrapper to libblender gtk = glib = webkit # webkit links to gtk and glib gtk.init() def get_html(): dom = view.get_dom_document() html = webkit.dom_html_element_get_inner_html( dom ) return html def call_javascript( script ): ''' this won't work because it kills newlines! view.execute_script('document.title=%s;' %script) ''' view.execute_script( "document.getElementsByTagName('text_hack')[0].setAttribute('x',%s);"%script ) result = get_html() result = result.split('text_hack x="')[-1] result = result.split('"')[0] return result def hack_code( script ): ''' need to hack the script a bit, blockly generates python2, and blender needs python3! ''' a = [] for line in script.splitlines(): if "print '" in line: line = line.replace("print '", "print('") + ')' if line == 'null': continue # blockly bug? elif line.strip() == 'passnull': # check for an undefined function and remove it a.pop() continue a.append(line) script = '\n'.join(a) print('----------- python code -------------') print(script) return script def execute_python( script ): script = hack_code( script ) print('----------- exec python code -------------') exec( script ) ################### WebKitGTK #################### view = webkit.webkit_web_view_new() print(view) settings = webkit.web_settings_new() for prop in 'enable-webaudio enable-file-access-from-file-uris enable-universal-access-from-file-uris enable-developer-extras enable-accelerated-compositing enable-webgl'.split(): gval = glib.GValue(True) glib.g_object_set_property( settings, prop, gval ) view.set_settings( settings ) view.load_uri( 'file://%s/test-blockly.html'%os.path.abspath('.')) win = gtk.Window() root = gtk.VBox() win.add( root ) header = gtk.HBox() root.pack_start( header, expand=False ) button = gtk.Button('print html') button.connect('clicked', lambda b: get_html() ) header.pack_start( button, expand=False ) header.pack_start( gtk.Label() ) button = gtk.Button('print python') button.connect('clicked', lambda b: hack_code(call_javascript("Blockly.Generator.workspaceToCode('Python')")) ) header.pack_start( button, expand=False ) button = gtk.Button('run python') button.connect('clicked', lambda b: execute_python(call_javascript("Blockly.Generator.workspaceToCode('Python')")) ) header.pack_start( button, expand=False ) root.pack_start( view, expand=True ) win.set_default_size( 800, 600 ) win.show_all() class BlenderHack(object): def update_gtk(self, region): while gtk.gtk_events_pending(): gtk.gtk_main_iteration() def setup_blender_hack(self, context): self._sync_hack_handles = {} # region : handle self.default_blender_screen = context.screen.name self.evil_C = Blender.Context( context ) for area in context.screen.areas: if area.type == 'VIEW_3D': for reg in area.regions: if reg.type == 'WINDOW': handle = reg.callback_add( self.update_gtk, (reg,), 'POST_PIXEL' ) self._sync_hack_handles[ reg ] = handle return self._sync_hack_handles def mainloop(self): self.active = True while self.active: screen = bpy.data.screens[ self.default_blender_screen ] ## force a redraw on the 3d view for area in screen.areas: if area.type == 'VIEW_3D': for reg in area.regions: if reg.type == 'WINDOW': reg.tag_redraw() break ## iterate blender's mainloop from ctypes Blender.iterate( self.evil_C ) time.sleep(0.01) hack = BlenderHack() hack.setup_blender_hack( bpy.context ) hack.mainloop() print('exit to normal blender mainloop')