/addons/Canvas.py
Python | 141 lines | 122 code | 9 blank | 10 comment | 0 complexity | 981f4cf8e7156c6cbc5910d55e66ddc2 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0
1# Canvas wrapper component for Pyjamas 2# Ported by Willie Gollino from Canvas component for GWT - Originally by Alexei Sokolov http://gwt.components.googlepages.com/ 3# 4# Canvas API reference: 5# http://developer.apple.com/documentation/AppleApplications/Reference/SafariJSRef/Classes/Canvas.html#//apple_ref/js/Canvas.clearRect 6# 7# Usage Notes: 8# - IE support requires ExplorerCanvas from excanvas.sourceforge.net 9# - place excanvas.js in your apps public folder 10# - add this to your MainModule.html: <!--[if IE]><script src="excanvas.js" type="text/javascript"></script><![endif]--> 11 12import DOM 13from ui import Image, Widget 14 15class Canvas(Widget): 16 def __init__(self, width, height): 17 self.context = None 18 19 self.setElement(DOM.createDiv()) 20 canvas = DOM.createElement("canvas") 21 self.setWidth(width) 22 self.setHeight(height) 23 24 canvas.width=width 25 canvas.height=height 26 27 DOM.appendChild(self.getElement(), canvas) 28 self.setStyleName("gwt-Canvas") 29 30 self.init() 31 32 self.context.fillStyle = "black" 33 self.context.strokeStyle = "black" 34 35 def getContext(self): 36 return self.context 37 38 def isEmulation(self): 39 JS(""" 40 return (typeof $wnd.G_vmlCanvasManager != "undefined"); 41 """) 42 43 def init(self): 44 JS(""" 45 var el = this.getElement().firstChild; 46 if (typeof $wnd.G_vmlCanvasManager != "undefined") { 47 var parent = el.parent; 48 49 el = $wnd.G_vmlCanvasManager.fixElement_(el); 50 el.getContext = function () { 51 if (this.context_) { 52 return this.context_; 53 } 54 return this.context_ = new $wnd.CanvasRenderingContext2D(el); 55 }; 56 57 el.attachEvent("onpropertychange", function (e) { 58 // we need to watch changes to width and height 59 switch (e.propertyName) { 60 case "width": 61 case "height": 62 // coord size changed? 63 break; 64 } 65 }); 66 67 // if style.height is set 68 69 var attrs = el.attributes; 70 if (attrs.width && attrs.width.specified) { 71 // TODO: use runtimeStyle and coordsize 72 // el.getContext().setWidth_(attrs.width.nodeValue); 73 el.style.width = attrs.width.nodeValue + "px"; 74 } 75 if (attrs.height && attrs.height.specified) { 76 // TODO: use runtimeStyle and coordsize 77 // el.getContext().setHeight_(attrs.height.nodeValue); 78 el.style.height = attrs.height.nodeValue + "px"; 79 } 80 } 81 var ctx = el.getContext("2d"); 82 83 ctx._createPattern = ctx.createPattern; 84 ctx.createPattern = function(img, rep) { 85 if (!(img instanceof Image)) img = img.getElement(); 86 return this._createPattern(img, rep); 87 } 88 89 ctx._drawImage = ctx.drawImage; 90 ctx.drawImage = function() { 91 var a=arguments; 92 if (!(a[0] instanceof Image)) a[0] = a[0].getElement(); 93 if (a.length==9) return this._drawImage(a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8]); 94 else if (a.length==5) return this._drawImage(a[0], a[1], a[2], a[3], a[4]); 95 return this._drawImage(a[0], a[1], a[2]); 96 } 97 98 this.context = ctx; 99 """) 100 101class CanvasImage(Image): 102 def __init__(self, url="", load_listener = None): 103 Image.__init__(self, url) 104 if load_listener: 105 self.addLoadListener(load_listener) 106 self.onAttach() 107 108 def isLoaded(self): 109 return self.getElement().complete 110 111 112class ImageLoadListener: 113 def __init__(self, listener = None): 114 self.wait_list = [] 115 self.loadListeners = [] 116 117 if listener: 118 self.addLoadListener(listener) 119 120 def add(self, sender): 121 self.wait_list.append(sender) 122 sender.addLoadListener(self) 123 124 def addLoadListener(self, listener): 125 self.loadListeners.append(listener) 126 127 def isLoaded(self): 128 if len(self.wait_list): 129 return False 130 return True 131 132 def onError(self, sender): 133 for listener in self.loadListeners: 134 listener.onError(sender) 135 136 def onLoad(self, sender): 137 self.wait_list.remove(sender) 138 139 if self.isLoaded(): 140 for listener in self.loadListeners: 141 listener.onLoad(self)