From 12a767ebe7cceb8e8659f17ada295c4a17d93a46 Mon Sep 17 00:00:00 2001 From: Pavel Talanov Date: Wed, 8 Feb 2012 19:31:30 +0400 Subject: [PATCH] move html5 examples intended for webDemo to a separate module --- examplesForWebDemo/examplesForWebDemo.iml | 13 + .../src/html5/interactive/interactive.js | 323 ++++++++++++++++++ .../src/html5/interactive/jbLogo.png | Bin 0 -> 9327 bytes .../src/html5/interactive/main.kt | 183 ++++++++++ .../src/html5/interactive/template.html | 15 + .../src/html5/interactive/template_copy.html | 14 + .../src/html5/interactive/tutorial.js | 222 ++++++++++++ examplesForWebDemo/src/html5/moving/moving.js | 145 ++++++++ .../src/html5/moving/template.html | 14 + examplesForWebDemo/src/html5/moving/test.kt | 92 +++++ .../src/html5/test/template.html | 14 + examplesForWebDemo/src/html5/test/test.kt | 77 +++++ examplesForWebDemo/src/html5/test/testhtml.js | 120 +++++++ jslib/src/html5/core.kt | 14 +- .../QualifiedExpressionTranslator.java | 15 +- .../reference/PropertyAccessTranslator.java | 19 ++ translator/testFiles/canvas_helper.js | 4 + translator/translator.iml | 2 - 18 files changed, 1278 insertions(+), 8 deletions(-) create mode 100644 examplesForWebDemo/examplesForWebDemo.iml create mode 100644 examplesForWebDemo/src/html5/interactive/interactive.js create mode 100644 examplesForWebDemo/src/html5/interactive/jbLogo.png create mode 100644 examplesForWebDemo/src/html5/interactive/main.kt create mode 100644 examplesForWebDemo/src/html5/interactive/template.html create mode 100644 examplesForWebDemo/src/html5/interactive/template_copy.html create mode 100644 examplesForWebDemo/src/html5/interactive/tutorial.js create mode 100644 examplesForWebDemo/src/html5/moving/moving.js create mode 100644 examplesForWebDemo/src/html5/moving/template.html create mode 100644 examplesForWebDemo/src/html5/moving/test.kt create mode 100644 examplesForWebDemo/src/html5/test/template.html create mode 100644 examplesForWebDemo/src/html5/test/test.kt create mode 100644 examplesForWebDemo/src/html5/test/testhtml.js diff --git a/examplesForWebDemo/examplesForWebDemo.iml b/examplesForWebDemo/examplesForWebDemo.iml new file mode 100644 index 00000000000..dd784a152e2 --- /dev/null +++ b/examplesForWebDemo/examplesForWebDemo.iml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/examplesForWebDemo/src/html5/interactive/interactive.js b/examplesForWebDemo/src/html5/interactive/interactive.js new file mode 100644 index 00000000000..7903b8b8ecf --- /dev/null +++ b/examplesForWebDemo/src/html5/interactive/interactive.js @@ -0,0 +1,323 @@ +{ + var classes = function () { + var Vector = Kotlin.Class.create({initialize:function (x, y) { + this.$x = x; + this.$y = y; + }, get_x:function () { + return this.$x; + }, set_x:function (tmp$0) { + this.$x = tmp$0; + }, get_y:function () { + return this.$y; + }, set_y:function (tmp$0) { + this.$y = tmp$0; + }, plus:function (v) { + { + return interactive.v_0(this.get_x() + v.get_x(), this.get_y() + v.get_y()); + } + }, minus:function (v) { + { + return interactive.v_0(this.get_x() - v.get_x(), this.get_y() - v.get_y()); + } + }, times:function (coef) { + { + return interactive.v_0(this.get_x() * coef, this.get_y() * coef); + } + }, distanceTo:function (v) { + { + return Math.sqrt(this.minus(v).get_sqr()); + } + }, isInRect:function (topLeft, size) { + { + return this.get_x() >= topLeft.get_x() && this.get_x() <= topLeft.get_x() + size.get_x() && this.get_y() >= topLeft.get_y() && this.get_y() <= topLeft.get_y() + size.get_y(); + } + }, get_sqr:function () { + { + return this.get_x() * this.get_x() + this.get_y() * this.get_y(); + } + } + }); + var CanvasState = Kotlin.Class.create({initialize:function (canvas) { + this.$canvas = canvas; + this.$width = this.get_canvas().width; + this.$height = this.get_canvas().height; + this.$context = getContext(); + this.$valid = false; + this.$shapes = new Kotlin.ArrayList; + this.$selection = null; + this.$dragOff = new interactive.Vector_0(0, 0); + this.$interval = 1000 / 30; + this.$size = 20; + { + var tmp$4; + var tmp$3; + var tmp$2; + var tmp$1; + var tmp$0_0; + $(this.get_canvas()).mousedown((tmp$0_0 = this , function (it) { + { + var tmp$0; + tmp$0_0.set_valid(false); + tmp$0_0.set_selection(null); + var mousePos = tmp$0_0.mousePos_0(it); + { + tmp$0 = tmp$0_0.get_shapes().iterator(); + while (tmp$0.hasNext()) { + var shape = tmp$0.next(); + { + if (shape.contains(mousePos)) { + tmp$0_0.set_dragOff(mousePos.minus(shape.get_pos())); + shape.set_selected(true); + tmp$0_0.set_selection(shape); + break; + } + } + } + } + } + } + )); + $(this.get_canvas()).mousemove((tmp$1 = this , function (it) { + { + if (tmp$1.get_selection() != null) { + Kotlin.sure(tmp$1.get_selection()).set_pos(tmp$1.mousePos_0(it).minus(tmp$1.get_dragOff())); + tmp$1.set_valid(false); + } + } + } + )); + $(this.get_canvas()).mouseup((tmp$2 = this , function (it) { + { + if (tmp$2.get_selection() != null) { + Kotlin.sure(tmp$2.get_selection()).set_selected(false); + } + tmp$2.set_selection(null); + tmp$2.set_valid(false); + } + } + )); + $(this.get_canvas()).dblclick((tmp$3 = this , function (it) { + { + var redTransparentCircle = new interactive.Circle_0(tmp$3.mousePos_0(it), tmp$3.get_size(), 'rgba(200, 100, 100, 0.3)'); + tmp$3.addShape(redTransparentCircle); + tmp$3.set_valid(false); + } + } + )); + interactive.doWithPeriod(this.get_interval(), (tmp$4 = this , function () { + { + tmp$4.draw(); + } + } + )); + } + }, get_canvas:function () { + return this.$canvas; + }, get_width:function () { + return this.$width; + }, get_height:function () { + return this.$height; + }, get_context:function () { + return this.$context; + }, get_valid:function () { + return this.$valid; + }, set_valid:function (tmp$0) { + this.$valid = tmp$0; + }, get_shapes:function () { + return this.$shapes; + }, set_shapes:function (tmp$0) { + this.$shapes = tmp$0; + }, get_selection:function () { + return this.$selection; + }, set_selection:function (tmp$0) { + this.$selection = tmp$0; + }, get_dragOff:function () { + return this.$dragOff; + }, set_dragOff:function (tmp$0) { + this.$dragOff = tmp$0; + }, get_interval:function () { + return this.$interval; + }, get_size:function () { + return this.$size; + }, mousePos_0:function (e) { + { + var offset = new interactive.Vector_0(0, 0); + var element = this.get_canvas(); + while (element != null) { + var el = Kotlin.sure(element); + offset = offset.plus(new interactive.Vector_0(el.offsetLeft, el.offsetTop)); + element = el.offsetParent; + } + return (new interactive.Vector_0(e.pageX, e.pageY)).minus(offset); + } + }, addShape:function (shape) { + { + this.get_shapes().add(shape); + this.set_valid(false); + } + }, clear:function () { + { + this.get_context().fillStyle = '#FFFFFF'; + this.get_context().fillRect(0, 0, this.get_width(), this.get_height()); + this.get_context().strokeStyle = '#000000'; + this.get_context().lineWidth = 4; + this.get_context().strokeRect(0, 0, this.get_width(), this.get_height()); + } + }, draw:function () { + { + var tmp$0; + if (this.get_valid()) + return; + this.clear(); + { + tmp$0 = this.get_shapes().iterator(); + while (tmp$0.hasNext()) { + var shape = tmp$0.next(); + { + shape.draw(this); + } + } + } + this.set_valid(true); + } + } + }); + var Shape = Kotlin.Class.create({initialize:function () { + this.$selected = false; + }, draw:function (state) { + }, contains:function (mousePos) { + }, get_pos:function () { + return this.$pos; + }, set_pos:function (tmp$0) { + this.$pos = tmp$0; + }, get_selected:function () { + return this.$selected; + }, set_selected:function (tmp$0) { + this.$selected = tmp$0; + } + }); + var JB = Kotlin.Class.create(Shape, {initialize:function (pos, relSize) { + this.$pos = pos; + this.$relSize = relSize; + this.super_init(); + this.$imageSize = interactive.v_0(704, 254); + this.$canvasSize = this.get_imageSize().times(this.get_relSize()); + }, get_pos:function () { + return this.$pos; + }, set_pos:function (tmp$0) { + this.$pos = tmp$0; + }, get_relSize:function () { + return this.$relSize; + }, set_relSize:function (tmp$0) { + this.$relSize = tmp$0; + }, get_imageSize:function () { + return this.$imageSize; + }, get_canvasSize:function () { + return this.$canvasSize; + }, draw:function (state) { + { + var context = state.get_context(); + context.drawImage(getJBLogo(), 0, 0, this.get_imageSize().get_x(), this.get_imageSize().get_y(), this.get_pos().get_x(), this.get_pos().get_y(), this.get_canvasSize().get_x(), this.get_canvasSize().get_y()); + } + }, contains:function (mousePos) { + { + return mousePos.isInRect(this.get_pos(), this.get_canvasSize()); + } + } + }); + var Rectangle = Kotlin.Class.create(Shape, {initialize:function (pos, size) { + this.$pos = pos; + this.$size = size; + this.super_init(); + }, get_pos:function () { + return this.$pos; + }, set_pos:function (tmp$0) { + this.$pos = tmp$0; + }, get_size:function () { + return this.$size; + }, set_size:function (tmp$0) { + this.$size = tmp$0; + }, draw:function (state) { + { + var context = state.get_context(); + context.fillStyle = 'rgba(0,255,0,.6)'; + context.fillRect(this.get_pos().get_x(), this.get_pos().get_y(), this.get_size().get_x(), this.get_size().get_y()); + if (this.get_selected()) { + context.strokeStyle = '#FF0000'; + context.lineWidth = 2; + context.strokeRect(this.get_pos().get_x(), this.get_pos().get_y(), this.get_size().get_x(), this.get_size().get_y()); + } + } + }, contains:function (mousePos) { + { + return mousePos.isInRect(this.get_pos(), this.get_size()); + } + } + }); + var Circle = Kotlin.Class.create(Shape, {initialize:function (pos, radius, fillColor) { + this.$pos = pos; + this.$radius = radius; + this.$fillColor = fillColor; + this.super_init(); + }, get_pos:function () { + return this.$pos; + }, set_pos:function (tmp$0) { + this.$pos = tmp$0; + }, get_radius:function () { + return this.$radius; + }, set_radius:function (tmp$0) { + this.$radius = tmp$0; + }, get_fillColor:function () { + return this.$fillColor; + }, set_fillColor:function (tmp$0) { + this.$fillColor = tmp$0; + }, draw:function (state) { + { + var context = state.get_context(); + context.shadowColor = 'white'; + context.shadowBlur = 10; + context.fillStyle = this.get_fillColor(); + context.beginPath(); + context.arc(this.get_pos().get_x(), this.get_pos().get_y(), this.get_radius(), 0, 2 * Math.PI, false); + context.closePath(); + context.fill(); + } + }, contains:function (mousePos) { + { + return this.get_pos().distanceTo(mousePos) < this.get_radius(); + } + } + }); + return {Shape_0:Shape, JB_0:JB, Rectangle_0:Rectangle, Circle_0:Circle, CanvasState_0:CanvasState, Vector_0:Vector}; + } + (); + var interactive = Kotlin.Namespace.create({initialize:function () { + interactive.$state = new interactive.CanvasState_0(getCanvas()); + }, get_state:function () { + return interactive.$state; + }, doWithPeriod:function (period, f) { + { + setInterval(f, period); + } + }, v_0:function (x, y) { + { + return new interactive.Vector_0(x, y); + } + }, main:function () { + { + var state = new interactive.CanvasState_0(getCanvas()); + state.addShape(new interactive.JB_0(interactive.v_0(1, 1), 0.3)); + setTimeout(function () { + { + state.set_valid(false); + } + } + ); + } + } + }, classes); + interactive.initialize(); +} + +var args = []; +interactive.main(args); diff --git a/examplesForWebDemo/src/html5/interactive/jbLogo.png b/examplesForWebDemo/src/html5/interactive/jbLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..759aa8ae05a7237bb1793cfb1706f127556b0041 GIT binary patch literal 9327 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�?7QP2QYFfM|yoVITZ(RHUSx5R%X>vYGFUvpe%aq zJyMA*z8;>W*a`u(RunJVvBE|e%B~t$iY7r`m!|%-yQ?Co?MlcN2sA&K{fYj=a(wof^Ha%hXC+zT8r-a`H^)D6SIRU>sstYL!` zdWt7}`qzGW{b5yF7nxCSc$h0PdP@ndsDD7^Qc~#P^++=QYm7)C-2q`~(JMvmY0A)Q zhqIQufS$|!6CeC{5m%T6n_cOB3;I2&_0#m_K8h4|pPHmr>E(nFr!{x`x5WpyRgGq9 zaZ4O>FH4x$c+70L+N1+YC{f*Mvc>yX$f&Lx-={GQI)tf2h0BN`JzYCfjn6R2niMXx zS@$be`i{vb7y8+fnauTA|?t({p_d%9sl7l04DikFc@U<;+*7^pE@B2;{ zPqfrWQ~9M?yMFS9ZMk~klD5xjrLRdjOt6!8Um7F$AB!Y}mK+7So2zfUj;m52l*`sZ zT1pyd2S$Wi3`VjB_QEZ0x@RZ3I#Iy_de2M~i7fo$ZypANj98wxBPWgH?^);K1>f2UuY=mi3!3~>yj>H7Z7;+b#=4^SzUmStogIwnf z@3Z%3W~F=e4DLn+v?K|^z2GSZHQv3mT~XAy;cL*5;e*ss<$Fz%dg_t66Nxp~U4Nk; zD1U0osh(t;+?_Mw)IrB+zE>|=cG8V6@iT_Eg~JC~>o46bI8&VOOAf@Gh7MEkGI(xC z736;8%X(#XDwJ_^Y>w<|&oVUOt9jc8eaGE1uuoHT-HCl?we4=ep~LB+zmJ|MaK87K zPnfmydTQ)eL*0(FAFbX$3$ws8_v8n!^g^EedX+CY;Y2Y%?m49Uio(v|4zPAaY&nw= zXb4B(kH3~9lY;=Zg+@Zi?(5XBhAwZWwJ*O*blg(C`{HW3@3TUQl*8l4!yMvM3BO1m z@GpV-3`g|;T1-&MKke#c58vs*8k}?29mhQgV8>rC`dYF$AvT6itq`=X7{&bx>+Z~v zC|$aeTl!Tg{9Rc^*vV)v*Z7sALq>u6F&T zwo4J_^;fE@6=C~YlN5JRm<8A4Y$cSijhG~2@qfs}jN3j!Nb;UGGe#WfjCslw00t7s zqY5;%En$zUMI7 zees#ut0HPUB7Z=^^UsfYDz|Da_3w5gJU&be|EOAOzwf)$FTABNh-zlX#{9aHOlVwO zGiYR*zuFQOFrqEB1muA8b^`As5DVZGY1(cIsgvUy$$W3bRU!Ts$rZn%*Fm}i0U8d~ z*q@DGt%kv&utAkx{eUz1|8VmjVojGC#|`;}c*IT&?%!X`RJF>jLXimN*-KIhpre_a V?{5ee#9s~qv^DhAtM4Ks{s*lVCNKa1 literal 0 HcmV?d00001 diff --git a/examplesForWebDemo/src/html5/interactive/main.kt b/examplesForWebDemo/src/html5/interactive/main.kt new file mode 100644 index 00000000000..ae53ad652d1 --- /dev/null +++ b/examplesForWebDemo/src/html5/interactive/main.kt @@ -0,0 +1,183 @@ +package interactive; + +import jquery.*; +import html5.*; +import java.util.ArrayList; +import js.*; +import js.Math; +import js.setInterval +import html5.getCanvas +import html5.getJBLogo +import jquery.jq +import js.setTimeout + +val state = CanvasState(getCanvas()); + +fun doWithPeriod(period : Int, f : ()->Unit) { + setInterval(f, period); +} + +abstract class Shape() { + abstract fun draw(state : CanvasState); + abstract fun contains(mousePos : Vector) : Boolean; + abstract var pos : Vector; + var selected : Boolean = false; +} + +class Circle(override var pos : Vector, + var radius : Double = 1.0, + var fillColor : String = "#AAAAAA") : Shape() { + + override fun draw(state : CanvasState) { + val context = state.context; + context.shadowColor = "white"; + context.shadowBlur = 10.0; + context.fillStyle = fillColor; + context.beginPath(); + context.arc(pos.x, pos.y, radius, 0.0, 2 * Math.PI, false); + context.closePath(); + context.fill(); + } + + override fun contains(mousePos : Vector) = pos.distanceTo(mousePos) < radius; +} + +class Rectangle(override var pos : Vector, + var size : Vector) : Shape() +{ + override fun draw(state : CanvasState) { + val context = state.context; + context.fillStyle = "rgba(0,255,0,.6)"; + context.fillRect(pos.x, pos.y, size.x, size.y); + if (selected) { + context.strokeStyle = "#FF0000" + context.lineWidth = 2.0; + context.strokeRect(pos.x, pos.y, size.x, size.y) + } + } + + override fun contains(mousePos : Vector) = mousePos.isInRect(pos, size); +} + +class JB(override var pos : Vector, + var relSize : Double = 0.3) : Shape() +{ + + val imageSize = v(704.0, 254.0) + val canvasSize = imageSize * relSize + + override fun draw(state : CanvasState) { + val context = state.context; + context.drawImage(getJBLogo(), 0.0, 0.0, imageSize.x, imageSize.y, pos.x, pos.y, canvasSize.x, canvasSize.y) + } + + override fun contains(mousePos: Vector): Boolean = mousePos.isInRect(pos, canvasSize) +} + +class CanvasState(val canvas : Canvas) { + val width = canvas.width; + val height = canvas.height; + val context = getContext(); + var valid = false; + var shapes = ArrayList(); + var selection : Shape? = null; + var dragOff = Vector(); + val interval = 1000 / 30; + val size = 20.0; + + { + jq(canvas).mousedown { + valid = false; + selection = null; + val mousePos = mousePos(it); + for (shape in shapes) { + if (mousePos in shape) { + dragOff = mousePos - shape.pos; + shape.selected = true; + selection = shape; + break; + } + } + } + + jq(canvas).mousemove { + if (selection != null) { + selection.sure().pos = mousePos(it) - dragOff; + valid = false; + } + } + + jq(canvas).mouseup { + if (selection != null) { + selection.sure().selected = false; + } + selection = null; + valid = false; + } + + jq(canvas).dblclick { + val redTransparentCircle = Circle(mousePos(it), size, "rgba(200, 100, 100, 0.3)"); + addShape(redTransparentCircle); + valid = false; + } + + doWithPeriod(interval) { + draw(); + } + } + + fun mousePos(e : MouseEvent) : Vector { + var offset = Vector(); + var element : DomElement? = canvas; + while (element != null) { + val el : DomElement = element.sure(); + offset += Vector(el.offsetLeft, el.offsetTop); + element = el.offsetParent; + } + return Vector(e.pageX, e.pageY) - offset; + } + + fun addShape(shape : Shape) { + shapes.add(shape); + valid = false; + } + + fun clear() { + context.fillStyle = "#FFFFFF" + context.fillRect(0.0, 0.0, width, height) + context.strokeStyle = "#000000" + context.lineWidth = 4.0; + context.strokeRect(0.0, 0.0, width, height) + } + + fun draw() { + if (valid) return + + clear(); + for (shape in shapes) { + shape.draw(this); + } + valid = true; + } +} + +fun v(x : Double, y : Double) = Vector(x, y); + +class Vector(var x : Double = 0.0, var y : Double = 0.0) { + fun plus(v : Vector) = v(x + v.x, y + v.y); + fun minus(v : Vector) = v(x - v.x, y - v.y); + fun times(coef : Double) = v(x * coef, y * coef); + fun distanceTo(v : Vector) = Math.sqrt((this - v).sqr); + fun isInRect(topLeft : Vector, size : Vector) = (x >= topLeft.x) && (x <= topLeft.x + size.x) && + (y >= topLeft.y) && (y <= topLeft.y + size.y) + val sqr : Double + get() = x * x + y * y; +} + +fun main() { + val state = CanvasState(getCanvas()); + state.addShape(JB(v(1.0, 1.0))); + setTimeout({ + state.valid = false + }) +} \ No newline at end of file diff --git a/examplesForWebDemo/src/html5/interactive/template.html b/examplesForWebDemo/src/html5/interactive/template.html new file mode 100644 index 00000000000..c629242e8ee --- /dev/null +++ b/examplesForWebDemo/src/html5/interactive/template.html @@ -0,0 +1,15 @@ + + + + Canvas demo + + + + + + + + + + \ No newline at end of file diff --git a/examplesForWebDemo/src/html5/interactive/template_copy.html b/examplesForWebDemo/src/html5/interactive/template_copy.html new file mode 100644 index 00000000000..7994eac67a3 --- /dev/null +++ b/examplesForWebDemo/src/html5/interactive/template_copy.html @@ -0,0 +1,14 @@ + + + + Canvas demo + + + + + + + + + \ No newline at end of file diff --git a/examplesForWebDemo/src/html5/interactive/tutorial.js b/examplesForWebDemo/src/html5/interactive/tutorial.js new file mode 100644 index 00000000000..9306f52d6bb --- /dev/null +++ b/examplesForWebDemo/src/html5/interactive/tutorial.js @@ -0,0 +1,222 @@ +// By Simon Sarris +// www.simonsarris.com +// sarris@acm.org +// +// Last update December 2011 +// +// Free to use and distribute at will +// So long as you are nice to people, etc + +// Constructor for Shape objects to hold data for all drawn objects. +// For now they will just be defined as rectangles. +function Shape(x, y, w, h, fill) { + // This is a very simple and unsafe constructor. All we're doing is checking if the values exist. + // "x || 0" just means "if there is a value for x, use that. Otherwise use 0." + // But we aren't checking anything else! We could put "Lalala" for the value of x + this.x = x || 0; + this.y = y || 0; + this.w = w || 1; + this.h = h || 1; + this.fill = fill || '#AAAAAA'; +} + +// Draws this shape to a given context +Shape.prototype.draw = function (ctx) { + ctx.fillStyle = this.fill; + ctx.fillRect(this.x, this.y, this.w, this.h); +} + +// Determine if a point is inside the shape's bounds +Shape.prototype.contains = function (mx, my) { + // All we have to do is make sure the Mouse X,Y fall in the area between + // the shape's X and (X + Height) and its Y and (Y + Height) + return (this.x <= mx) && (this.x + this.w >= mx) && + (this.y <= my) && (this.y + this.h >= my); +} + +function CanvasState(canvas) { + // **** First some setup! **** + + this.canvas = canvas; + this.width = canvas.width; + this.height = canvas.height; + this.ctx = canvas.getContext('2d'); + // This complicates things a little but but fixes mouse co-ordinate problems + // when there's a border or padding. See getMouse for more detail +// if (document.defaultView && document.defaultView.getComputedStyle) { +// this.stylePaddingLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingLeft'], 10) || 0; +// this.stylePaddingTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['paddingTop'], 10) || 0; +// this.styleBorderLeft = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderLeftWidth'], 10) || 0; +// this.styleBorderTop = parseInt(document.defaultView.getComputedStyle(canvas, null)['borderTopWidth'], 10) || 0; +// } + // Some pages have fixed-position bars (like the stumbleupon bar) at the top or left of the page + // They will mess up mouse coordinates and this fixes that + var html = document.body.parentNode; + this.htmlTop = html.offsetTop; + this.htmlLeft = html.offsetLeft; + + // **** Keep track of state! **** + + this.valid = false; // when set to false, the canvas will redraw everything + this.shapes = []; // the collection of things to be drawn + this.dragging = false; // Keep track of when we are dragging + // the current selected object. In the future we could turn this into an array for multiple selection + this.selection = null; + this.dragoffx = 0; // See mousedown and mousemove events for explanation + this.dragoffy = 0; + + // **** Then events! **** + + // This is an example of a closure! + // Right here "this" means the CanvasState. But we are making events on the Canvas itself, + // and when the events are fired on the canvas the variable "this" is going to mean the canvas! + // Since we still want to use this particular CanvasState in the events we have to save a reference to it. + // This is our reference! + var myState = this; + + //fixes a problem where double clicking causes text to get selected on the canvas + canvas.addEventListener('selectstart', function (e) { + e.preventDefault(); + return false; + }, false); + // Up, down, and move are for dragging + canvas.addEventListener('mousedown', function (e) { + var mouse = myState.getMouse(e); + var mx = mouse.x; + var my = mouse.y; + var shapes = myState.shapes; + var l = shapes.length; + for (var i = l - 1; i >= 0; i--) { + if (shapes[i].contains(mx, my)) { + var mySel = shapes[i]; + // Keep track of where in the object we clicked + // so we can move it smoothly (see mousemove) + myState.dragoffx = mx - mySel.x; + myState.dragoffy = my - mySel.y; + myState.dragging = true; + myState.selection = mySel; + myState.valid = false; + return; + } + } + // havent returned means we have failed to select anything. + // If there was an object selected, we deselect it + if (myState.selection) { + myState.selection = null; + myState.valid = false; // Need to clear the old selection border + } + }, true); + canvas.addEventListener('mousemove', function (e) { + if (myState.dragging) { + var mouse = myState.getMouse(e); + // We don't want to drag the object by its top-left corner, we want to drag it + // from where we clicked. Thats why we saved the offset and use it here + myState.selection.x = mouse.x - myState.dragoffx; + myState.selection.y = mouse.y - myState.dragoffy; + myState.valid = false; // Something's dragging so we must redraw + } + }, true); + canvas.addEventListener('mouseup', function (e) { + myState.dragging = false; + }, true); + // double click for making new shapes + canvas.addEventListener('dblclick', function (e) { + var mouse = myState.getMouse(e); + myState.addShape(new Shape(mouse.x - 10, mouse.y - 10, 20, 20, 'rgba(0,255,0,.6)')); + }, true); + + // **** Options! **** + + this.selectionColor = '#CC0000'; + this.selectionWidth = 2; + this.interval = 30; + setInterval(function () { + myState.draw(); + }, myState.interval); +} + +CanvasState.prototype.addShape = function (shape) { + this.shapes.push(shape); + this.valid = false; +} + +CanvasState.prototype.clear = function () { + this.ctx.clearRect(0, 0, this.width, this.height); +} + +// While draw is called as often as the INTERVAL variable demands, +// It only ever does something if the canvas gets invalidated by our code +CanvasState.prototype.draw = function () { + // if our state is invalid, redraw and validate! + if (!this.valid) { + var ctx = this.ctx; + var shapes = this.shapes; + this.clear(); + + // ** Add stuff you want drawn in the background all the time here ** + + // draw all shapes + var l = shapes.length; + for (var i = 0; i < l; i++) { + var shape = shapes[i]; + // We can skip the drawing of elements that have moved off the screen: + if (shape.x > this.width || shape.y > this.height || + shape.x + shape.w < 0 || shape.y + shape.h < 0) continue; + shapes[i].draw(ctx); + } + + // draw selection + // right now this is just a stroke along the edge of the selected Shape + if (this.selection != null) { + ctx.strokeStyle = this.selectionColor; + ctx.lineWidth = this.selectionWidth; + var mySel = this.selection; + ctx.strokeRect(mySel.x, mySel.y, mySel.w, mySel.h); + } + + // ** Add stuff you want drawn on top all the time here ** + + this.valid = true; + } +} + + +// Creates an object with x and y defined, set to the mouse position relative to the state's canvas +// If you wanna be super-correct this can be tricky, we have to worry about padding and borders +CanvasState.prototype.getMouse = function (e) { + var element = this.canvas, offsetX = 0, offsetY = 0, mx, my; + + // Compute the total offset + if (element.offsetParent !== undefined) { + do { + offsetX += element.offsetLeft; + offsetY += element.offsetTop; + } while ((element = element.offsetParent)); + } + + // Add padding and border style widths to offset + // Also add the offsets in case there's a position:fixed bar +// offsetX += this.stylePaddingLeft + this.styleBorderLeft + this.htmlLeft; + // offsetY += this.stylePaddingTop + this.styleBorderTop + this.htmlTop; + + mx = e.pageX - offsetX; + my = e.pageY - offsetY; + + // We return a simple javascript object (a hash) with x and y defined + return {x:mx, y:my}; +} + +// If you dont want to use +// You could uncomment this init() reference and place the script reference inside the body tag +init(); + +function init() { + var s = new CanvasState(getCanvas()); + s.addShape(new Shape(40, 40, 50, 50)); // The default is gray + s.addShape(new Shape(60, 140, 40, 60, 'lightskyblue')); + // Lets make some partially transparent + s.addShape(new Shape(80, 150, 60, 30, 'rgba(127, 255, 212, .5)')); + s.addShape(new Shape(125, 80, 30, 80, 'rgba(245, 222, 179, .7)')); +} + +// Now go make something amazing! \ No newline at end of file diff --git a/examplesForWebDemo/src/html5/moving/moving.js b/examplesForWebDemo/src/html5/moving/moving.js new file mode 100644 index 00000000000..75bf92d60bf --- /dev/null +++ b/examplesForWebDemo/src/html5/moving/moving.js @@ -0,0 +1,145 @@ +{ + var classes = function () { + var Moving = Kotlin.Class.create({initialize:function () { + this.$context = getContext(); + this.$height = getCanvas().height; + this.$width = getCanvas().width; + this.$relX = 0.5; + this.$relY = 0.5; + this.$relXVelocity = this.randomVelocity(); + this.$relYVelocity = this.randomVelocity(); + this.$message = 'Hello Kotlin'; + this.$textHeightInPixels = 60; + { + this.get_context().font = 'bold ' + this.get_textHeightInPixels() + 'px Georgia, serif'; + } + this.$textWidthInPixels = this.get_context().measureText(this.get_message()).width; + }, get_context:function () { + return this.$context; + }, get_height:function () { + return this.$height; + }, get_width:function () { + return this.$width; + }, get_relX:function () { + return this.$relX; + }, set_relX:function (tmp$0) { + this.$relX = tmp$0; + }, get_relY:function () { + return this.$relY; + }, set_relY:function (tmp$0) { + this.$relY = tmp$0; + }, get_absX:function () { + { + return this.get_relX() * this.get_width(); + } + }, get_absY:function () { + { + return this.get_relY() * this.get_height(); + } + }, get_relXVelocity:function () { + return this.$relXVelocity; + }, set_relXVelocity:function (tmp$0) { + this.$relXVelocity = tmp$0; + }, get_relYVelocity:function () { + return this.$relYVelocity; + }, set_relYVelocity:function (tmp$0) { + this.$relYVelocity = tmp$0; + }, get_message:function () { + return this.$message; + }, get_textHeightInPixels:function () { + return this.$textHeightInPixels; + }, get_textWidthInPixels:function () { + return this.$textWidthInPixels; + }, renderText:function () { + { + this.get_context().save(); + this.move(); + this.get_context().shadowColor = 'white'; + this.get_context().shadowBlur = 10; + this.get_context().fillStyle = 'rgba(100,200,0,0.7)'; + this.get_context().fillText(this.get_message(), this.get_absX(), this.get_absY()); + this.get_context().restore(); + } + }, move:function () { + { + var relTextWidth = this.get_textWidthInPixels() / this.get_width(); + if (this.get_relX() > 1 - relTextWidth - this.get_abs(this.get_relXVelocity()) || this.get_relX() < this.get_abs(this.get_relXVelocity())) { + this.set_relXVelocity(this.get_relXVelocity() * -1); + } + var relTextHeight = this.get_textHeightInPixels() / this.get_height(); + if (this.get_relY() > 1 - this.get_abs(this.get_relYVelocity()) || this.get_relY() < this.get_abs(this.get_relYVelocity()) + relTextHeight) { + this.set_relYVelocity(this.get_relYVelocity() * -1); + } + this.set_relX(this.get_relX() + this.get_relXVelocity()); + this.set_relY(this.get_relY() + this.get_relYVelocity()); + } + }, changeDirection:function () { + { + this.set_relYVelocity(this.randomVelocity()); + this.set_relXVelocity(this.randomVelocity()); + } + }, renderBackground:function () { + { + this.get_context().save(); + this.get_context().fillStyle = 'rgba(255,255,1,0.2)'; + this.get_context().fillRect(0, 0, this.get_width(), this.get_height()); + this.get_context().restore(); + } + }, randomVelocity:function () { + var tmp$0; + if (Math.random() < 0.5) + tmp$0 = 1; + else + tmp$0 = -1; + { + return 0.01 * Math.random() * tmp$0; + } + }, run:function () { + { + var tmp$1; + var tmp$0; + setInterval((tmp$0 = this , function () { + { + tmp$0.renderBackground(); + tmp$0.renderText(); + } + } + ), 10); + setInterval((tmp$1 = this , function () { + { + tmp$1.changeDirection(); + } + } + ), 3000); + } + }, get_abs:function (receiver) { + var tmp$0; + if (receiver > 0) + tmp$0 = receiver; + else + tmp$0 = -receiver; + { + return tmp$0; + } + } + }); + return {Moving_0:Moving}; + } + (); + var moving = Kotlin.Namespace.create({initialize:function () { + }, main:function () { + { + $(function () { + { + (new moving.Moving_0).run(); + } + } + ); + } + } + }, classes); + moving.initialize(); +} + +var args = []; +moving.main(args); diff --git a/examplesForWebDemo/src/html5/moving/template.html b/examplesForWebDemo/src/html5/moving/template.html new file mode 100644 index 00000000000..5043894d83f --- /dev/null +++ b/examplesForWebDemo/src/html5/moving/template.html @@ -0,0 +1,14 @@ + + + + Canvas demo + + + + + + + + + \ No newline at end of file diff --git a/examplesForWebDemo/src/html5/moving/test.kt b/examplesForWebDemo/src/html5/moving/test.kt new file mode 100644 index 00000000000..db0ae95bb40 --- /dev/null +++ b/examplesForWebDemo/src/html5/moving/test.kt @@ -0,0 +1,92 @@ +package moving; + +import js.*; +import html5.*; +import jquery.*; + +fun main() { + jq { + Moving().run(); + } +} + + +class Moving() { + + val context = getContext(); + val height = getCanvas().height; + val width = getCanvas().width; + + var relX = 0.5; + var relY = 0.5; + + val absX : Double + get() = (relX * width); + val absY : Double + get() = (relY * height); + + var relXVelocity = randomVelocity(); + var relYVelocity = randomVelocity(); + + + val message = "Hello Kotlin"; + val textHeightInPixels = 60; + { + context.font = "bold ${textHeightInPixels}px Georgia, serif" + } + val textWidthInPixels = context.measureText(message).width; + + fun renderText() { + context.save(); + move(); + context.shadowColor = "white"; + context.shadowBlur = 10.0; + context.fillStyle = "rgba(100,200,0,0.7)"; + context.fillText(message, absX, absY); + context.restore(); + } + + fun move() { + val relTextWidth = textWidthInPixels / width; + if (relX > (1.0 - relTextWidth - relXVelocity.abs) || relX < relXVelocity.abs) { + relXVelocity *= -1; + } + val relTextHeight = textHeightInPixels / height; + if (relY > (1.0 - relYVelocity.abs) || relY < relYVelocity.abs + relTextHeight) { + relYVelocity *= -1; + } + relX += relXVelocity; + relY += relYVelocity; + } + + fun changeDirection() { + relYVelocity = randomVelocity(); + relXVelocity = randomVelocity(); + } + + + fun renderBackground() { + context.save(); + context.fillStyle = "rgba(255,255,1,0.2)"; + context.fillRect(0.0, 0.0, width, height); + context.restore(); + } + + fun randomVelocity() = 0.01 * Math.random() * + if (Math.random() < 0.5) 1 else -1; + + fun run() { + setInterval({ + renderBackground(); + renderText(); + }, 10); + setInterval({ + changeDirection(); + }, 3000); + } + + val Double.abs : Double + get() = if (this > 0) this else -this + +} + diff --git a/examplesForWebDemo/src/html5/test/template.html b/examplesForWebDemo/src/html5/test/template.html new file mode 100644 index 00000000000..38521fe3248 --- /dev/null +++ b/examplesForWebDemo/src/html5/test/template.html @@ -0,0 +1,14 @@ + + + + Canvas demo + + + + + + + + + \ No newline at end of file diff --git a/examplesForWebDemo/src/html5/test/test.kt b/examplesForWebDemo/src/html5/test/test.kt new file mode 100644 index 00000000000..e4fdcae638d --- /dev/null +++ b/examplesForWebDemo/src/html5/test/test.kt @@ -0,0 +1,77 @@ +package testhtml; + +import js.*; +import html5.*; +import jquery.*; + +fun main() { + jq { + Test().run(); + HelloKotlin().run(); + } +} + + +class Test() { + val context = getContext(); + val height = getCanvas().height; + val width = getCanvas().width; + var x = width * Math.random(); + var y = height * Math.random(); + var hue = 0; + + fun line() { + context.save(); + context.beginPath(); + context.lineWidth = 20.0 * Math.random(); + context.moveTo(x, y); + + x = width * Math.random(); + y = height * Math.random(); + + context.bezierCurveTo(width * Math.random(), height * Math.random(), + width * Math.random(), height * Math.random(), x, y); + + hue += Math.random() * 10; + context.strokeStyle = "hsl($hue, 50%, 50%)"; + + context.shadowColor = "white"; + context.shadowBlur = 10.0; + + context.stroke(); + context.restore(); + } + + fun blank() { + context.fillStyle = "rgba(255,255,1,0.1)"; + context.fillRect(0.0, 0.0, width, height); + } + + fun run() { + setInterval({line()}, 40); + setInterval({blank()}, 100); + } +} + +class HelloKotlin() { + val context = getContext(); + val height = getCanvas().height; + val width = getCanvas().width; + + fun run() { + setInterval({ + greet(); + }, 2000); + } + + fun greet() { + context.save(); + val message = "Hello Kotlin"; + context.font = "bold 20px Georgia, serif"; + context.scale(5.0, 5.0); + context.strokeStyle = "rgba(0,0,0, 0.8)"; + context.strokeText(message, /*(width / 3) + */ (width / 7) * Math.random(), + /*(height / 3) + */ (height / 7) * Math.random()); + context.restore(); + } +} diff --git a/examplesForWebDemo/src/html5/test/testhtml.js b/examplesForWebDemo/src/html5/test/testhtml.js new file mode 100644 index 00000000000..8312453d084 --- /dev/null +++ b/examplesForWebDemo/src/html5/test/testhtml.js @@ -0,0 +1,120 @@ +{ + var classes = function () { + var HelloKotlin = Kotlin.Class.create({initialize:function () { + this.$context = getContext(); + this.$height = getCanvas().height; + this.$width = getCanvas().width; + }, get_context:function () { + return this.$context; + }, get_height:function () { + return this.$height; + }, get_width:function () { + return this.$width; + }, run:function () { + { + var tmp$0; + setInterval((tmp$0 = this , function () { + { + tmp$0.greet(); + } + } + ), 2000); + } + }, greet:function () { + { + this.get_context().save(); + var message = 'Hello Kotlin'; + this.get_context().font = 'bold 20px Georgia, serif'; + this.get_context().scale(5, 5); + this.get_context().strokeStyle = 'rgba(0,0,0, 0.8)'; + this.get_context().strokeText(message, this.get_width() / 7 * Math.random(), this.get_height() / 7 * Math.random()); + this.get_context().restore(); + } + } + }); + var Test = Kotlin.Class.create({initialize:function () { + this.$context = getContext(); + this.$height = getCanvas().height; + this.$width = getCanvas().width; + this.$x = this.get_width() * Math.random(); + this.$y = this.get_height() * Math.random(); + this.$hue = 0; + }, get_context:function () { + return this.$context; + }, get_height:function () { + return this.$height; + }, get_width:function () { + return this.$width; + }, get_x:function () { + return this.$x; + }, set_x:function (tmp$0) { + this.$x = tmp$0; + }, get_y:function () { + return this.$y; + }, set_y:function (tmp$0) { + this.$y = tmp$0; + }, get_hue:function () { + return this.$hue; + }, set_hue:function (tmp$0) { + this.$hue = tmp$0; + }, line:function () { + { + this.get_context().save(); + this.get_context().beginPath(); + this.get_context().lineWidth = 20 * Math.random(); + this.get_context().moveTo(this.get_x(), this.get_y()); + this.set_x(this.get_width() * Math.random()); + this.set_y(this.get_height() * Math.random()); + this.get_context().bezierCurveTo(this.get_width() * Math.random(), this.get_height() * Math.random(), this.get_width() * Math.random(), this.get_height() * Math.random(), this.get_x(), this.get_y()); + this.set_hue(this.get_hue() + Math.random() * 10); + this.get_context().strokeStyle = 'hsl(' + this.get_hue() + ', 50%, 50%)'; + this.get_context().shadowColor = 'white'; + this.get_context().shadowBlur = 10; + this.get_context().stroke(); + this.get_context().restore(); + } + }, blank:function () { + { + this.get_context().fillStyle = 'rgba(255,255,1,0.1)'; + this.get_context().fillRect(0, 0, this.get_width(), this.get_height()); + } + }, run:function () { + { + var tmp$1; + var tmp$0; + setInterval((tmp$0 = this , function () { + { + tmp$0.line(); + } + } + ), 40); + setInterval((tmp$1 = this , function () { + { + tmp$1.blank(); + } + } + ), 100); + } + } + }); + return {Test_0:Test, HelloKotlin_0:HelloKotlin}; + } + (); + var testhtml = Kotlin.Namespace.create({initialize:function () { + }, main:function () { + { + $(function () { + { + (new testhtml.Test_0).run(); + (new testhtml.HelloKotlin_0).run(); + } + } + ); + } + } + }, classes); + testhtml.initialize(); +} + +var args = []; +testhtml.main(args); diff --git a/jslib/src/html5/core.kt b/jslib/src/html5/core.kt index 6e14f794a4e..ac64a472188 100644 --- a/jslib/src/html5/core.kt +++ b/jslib/src/html5/core.kt @@ -34,7 +34,7 @@ class Context() { fun quadraticCurveTo(cpx : Double, cpy : Double, x : Double, y : Double) {} fun bezierCurveTo(cp1x : Double, cp1y : Double, cp2x : Double, cp2y : Double, x : Double, y : Double) {} fun arcTo(x1 : Double, y1 : Double, x2 : Double, y2 : Double, radius : Double) {} - fun arc(x : Double, y : Double, radius : Double, startAngle : Double, endAngle : Double, anticlockwise : Boolean= false) {} + fun arc(x : Double, y : Double, radius : Double, startAngle : Double, endAngle : Double, anticlockwise : Boolean) {} fun rect(x : Double, y : Double, w : Double, h : Double) {} fun fill() {} @@ -46,8 +46,16 @@ class Context() { fun strokeText(text : String, x : Double, y : Double, maxWidth : Double) {} fun measureText(text : String) : TextMetrics = TextMetrics(); + + fun drawImage(image : HTMLImageElement, dx : Double, dy : Double) {} + fun drawImage(image : HTMLImageElement, dx: Double, dy: Double, dw: Double, dh: Double) {} + fun drawImage(image : HTMLImageElement, sx: Double, sy: Double, + sw: Double, sh: Double, dx: Double, dy: Double, dw: Double, dh: Double) {} } +native +class HTMLImageElement() : DomElement() {} + native class Canvas() : DomElement() { val width = 0.0; @@ -63,4 +71,6 @@ class TextMetrics() { native fun getContext() : Context = Context(); native -fun getCanvas() : Canvas = Canvas(); \ No newline at end of file +fun getCanvas() : Canvas = Canvas(); +native +fun getJBLogo() : HTMLImageElement = HTMLImageElement(); \ No newline at end of file diff --git a/translator/src/org/jetbrains/k2js/translate/expression/QualifiedExpressionTranslator.java b/translator/src/org/jetbrains/k2js/translate/expression/QualifiedExpressionTranslator.java index dc9be6cb630..57a7078560c 100644 --- a/translator/src/org/jetbrains/k2js/translate/expression/QualifiedExpressionTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/expression/QualifiedExpressionTranslator.java @@ -28,11 +28,18 @@ public final class QualifiedExpressionTranslator { @NotNull public static AccessTranslator getAccessTranslator(@NotNull JetQualifiedExpression expression, @NotNull TranslationContext context) { - if (expression instanceof JetDotQualifiedExpression) { - JsExpression receiver = translateReceiver(expression, context); - return PropertyAccessTranslator.newInstance(getNotNullSimpleNameSelector(expression), receiver, context); + + JsExpression receiver = translateReceiver(expression, context); + PropertyAccessTranslator result = + PropertyAccessTranslator.newInstance(getNotNullSimpleNameSelector(expression), receiver, context); + //TODO: util if this code duplicates + if (expression instanceof JetSafeQualifiedExpression) { + result.setCallType(PropertyAccessTranslator.CallType.SAFE); } - throw new UnsupportedOperationException(); + if (expression instanceof JetDotQualifiedExpression) { + result.setCallType(PropertyAccessTranslator.CallType.NORMAL); + } + return result; } @NotNull diff --git a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java index f9940af4f37..5547746f769 100644 --- a/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java +++ b/translator/src/org/jetbrains/k2js/translate/reference/PropertyAccessTranslator.java @@ -105,8 +105,27 @@ public abstract class PropertyAccessTranslator extends AccessTranslator { return canBePropertyGetterCall(expression, context); } + public enum CallType { + SAFE, + //TODO: bang qualifier is not implemented in frontend for now + BANG, + NORMAL + } + + //TODO: we use normal by default but may cause bugs + private /*var*/ CallType callType = CallType.NORMAL; + protected PropertyAccessTranslator(@NotNull TranslationContext context) { super(context); } + public void setCallType(@NotNull CallType callType) { + this.callType = callType; + } + + @NotNull + protected CallType getCallType() { + assert callType != null : "CallType not set"; + return callType; + } } \ No newline at end of file diff --git a/translator/testFiles/canvas_helper.js b/translator/testFiles/canvas_helper.js index 4544e7456ef..0931cd4b484 100644 --- a/translator/testFiles/canvas_helper.js +++ b/translator/testFiles/canvas_helper.js @@ -4,4 +4,8 @@ function getContext() { function getCanvas() { return document.getElementsByTagName('canvas')[0]; +} + +function getJBLogo() { + return document.getElementsByTagName('img')[0]; } \ No newline at end of file diff --git a/translator/translator.iml b/translator/translator.iml index 700837a9777..e22aa76dd49 100644 --- a/translator/translator.iml +++ b/translator/translator.iml @@ -4,8 +4,6 @@ - -