/addons/Canvas.py

http://pyjamas.googlecode.com/ · Python · 141 lines · 110 code · 21 blank · 10 comment · 6 complexity · 981f4cf8e7156c6cbc5910d55e66ddc2 MD5 · raw file

  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. import DOM
  12. from ui import Image, Widget
  13. class Canvas(Widget):
  14. def __init__(self, width, height):
  15. self.context = None
  16. self.setElement(DOM.createDiv())
  17. canvas = DOM.createElement("canvas")
  18. self.setWidth(width)
  19. self.setHeight(height)
  20. canvas.width=width
  21. canvas.height=height
  22. DOM.appendChild(self.getElement(), canvas)
  23. self.setStyleName("gwt-Canvas")
  24. self.init()
  25. self.context.fillStyle = "black"
  26. self.context.strokeStyle = "black"
  27. def getContext(self):
  28. return self.context
  29. def isEmulation(self):
  30. JS("""
  31. return (typeof $wnd.G_vmlCanvasManager != "undefined");
  32. """)
  33. def init(self):
  34. JS("""
  35. var el = this.getElement().firstChild;
  36. if (typeof $wnd.G_vmlCanvasManager != "undefined") {
  37. var parent = el.parent;
  38. el = $wnd.G_vmlCanvasManager.fixElement_(el);
  39. el.getContext = function () {
  40. if (this.context_) {
  41. return this.context_;
  42. }
  43. return this.context_ = new $wnd.CanvasRenderingContext2D(el);
  44. };
  45. el.attachEvent("onpropertychange", function (e) {
  46. // we need to watch changes to width and height
  47. switch (e.propertyName) {
  48. case "width":
  49. case "height":
  50. // coord size changed?
  51. break;
  52. }
  53. });
  54. // if style.height is set
  55. var attrs = el.attributes;
  56. if (attrs.width && attrs.width.specified) {
  57. // TODO: use runtimeStyle and coordsize
  58. // el.getContext().setWidth_(attrs.width.nodeValue);
  59. el.style.width = attrs.width.nodeValue + "px";
  60. }
  61. if (attrs.height && attrs.height.specified) {
  62. // TODO: use runtimeStyle and coordsize
  63. // el.getContext().setHeight_(attrs.height.nodeValue);
  64. el.style.height = attrs.height.nodeValue + "px";
  65. }
  66. }
  67. var ctx = el.getContext("2d");
  68. ctx._createPattern = ctx.createPattern;
  69. ctx.createPattern = function(img, rep) {
  70. if (!(img instanceof Image)) img = img.getElement();
  71. return this._createPattern(img, rep);
  72. }
  73. ctx._drawImage = ctx.drawImage;
  74. ctx.drawImage = function() {
  75. var a=arguments;
  76. if (!(a[0] instanceof Image)) a[0] = a[0].getElement();
  77. 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]);
  78. else if (a.length==5) return this._drawImage(a[0], a[1], a[2], a[3], a[4]);
  79. return this._drawImage(a[0], a[1], a[2]);
  80. }
  81. this.context = ctx;
  82. """)
  83. class CanvasImage(Image):
  84. def __init__(self, url="", load_listener = None):
  85. Image.__init__(self, url)
  86. if load_listener:
  87. self.addLoadListener(load_listener)
  88. self.onAttach()
  89. def isLoaded(self):
  90. return self.getElement().complete
  91. class ImageLoadListener:
  92. def __init__(self, listener = None):
  93. self.wait_list = []
  94. self.loadListeners = []
  95. if listener:
  96. self.addLoadListener(listener)
  97. def add(self, sender):
  98. self.wait_list.append(sender)
  99. sender.addLoadListener(self)
  100. def addLoadListener(self, listener):
  101. self.loadListeners.append(listener)
  102. def isLoaded(self):
  103. if len(self.wait_list):
  104. return False
  105. return True
  106. def onError(self, sender):
  107. for listener in self.loadListeners:
  108. listener.onError(sender)
  109. def onLoad(self, sender):
  110. self.wait_list.remove(sender)
  111. if self.isLoaded():
  112. for listener in self.loadListeners:
  113. listener.onLoad(self)