From c6ea8f2be80a5233c9ae72e3e6c2a0b70bce2923 Mon Sep 17 00:00:00 2001 From: Tony Garnock-Jones Date: Mon, 27 Feb 2017 04:10:43 -0500 Subject: [PATCH] New example --- examples/mixin/Makefile | 7 +++ examples/mixin/index.expanded.js | 81 ++++++++++++++++++++++++++++++++ examples/mixin/index.html | 38 +++++++++++++++ examples/mixin/index.js | 80 +++++++++++++++++++++++++++++++ 4 files changed, 206 insertions(+) create mode 100644 examples/mixin/Makefile create mode 100644 examples/mixin/index.expanded.js create mode 100644 examples/mixin/index.html create mode 100644 examples/mixin/index.js diff --git a/examples/mixin/Makefile b/examples/mixin/Makefile new file mode 100644 index 0000000..6b0a114 --- /dev/null +++ b/examples/mixin/Makefile @@ -0,0 +1,7 @@ +all: index.expanded.js + +%.expanded.js: %.js + ../../bin/syndicatec $< > $@ || (rm -f $@; false) + +clean: + rm -f *.expanded.js diff --git a/examples/mixin/index.expanded.js b/examples/mixin/index.expanded.js new file mode 100644 index 0000000..8f86590 --- /dev/null +++ b/examples/mixin/index.expanded.js @@ -0,0 +1,81 @@ +"use strict"; +var G = new Syndicate.Ground(function () { + var shiftClicked = Syndicate.Struct.makeConstructor("shiftClicked", ["fragmentId"]); + + Syndicate.UI.spawnUIDriver(); + + Syndicate.Actor.spawnActor(function() { Syndicate.Actor.Facet.build(function () { { + var uiRoot = new Syndicate.UI.Anchor(); + + Syndicate.Actor.Facet.current.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(uiRoot.html('#place', ''), 0); })); + + Syndicate.Actor.spawnActor(function() { Syndicate.Actor.Facet.build(function () { { + var ui = new Syndicate.UI.Anchor(); + Syndicate.Actor.Facet.current.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(ui.html('#svgroot', + '', + -1), 0); })); + Syndicate.Actor.Facet.current.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(ui.event('.', 'click', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: ui.event('.', 'click', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) { + var svg = document.getElementById('svgroot'); + var pt = svg.createSVGPoint(); + pt.x = e.clientX; + pt.y = e.clientY; + pt = pt.matrixTransform(svg.getScreenCTM().inverse()); + spawnRectangle(pt.x, pt.y); + })); + } }); }); + + Syndicate.Actor.spawnActor(function() { Syndicate.Actor.Facet.build(function () { { + Syndicate.Actor.declareField(this, "x", 50); + Syndicate.Actor.declareField(this, "y", 50); + var ui = new Syndicate.UI.Anchor(); + Syndicate.Actor.Facet.current.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(ui.html('#svgroot', + '', + 0), 0); })); + draggableMixin(this, ui); + } }); }); + + /////////////////////////////////////////////////////////////////////////// + + function spawnRectangle(x0, y0) { + var length = 90; + Syndicate.Actor.spawnActor(function() { Syndicate.Actor.Facet.build(function () { { + Syndicate.Actor.declareField(this, "x", x0 - length / 2); + Syndicate.Actor.declareField(this, "y", y0 - length / 2); + var ui = new Syndicate.UI.Anchor(); + Syndicate.Actor.Facet.current.addAssertion((function() { var _ = Syndicate.__; return Syndicate.Patch.assert(ui.html('#svgroot', + '', + 0), 0); })); + draggableMixin(this, ui); + Syndicate.Actor.Facet.current.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(ui.event('.', 'mousedown', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: ui.event('.', 'mousedown', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) { + if (e.shiftKey) { Syndicate.Dataspace.send(shiftClicked(ui.fragmentId)); } + })); + Syndicate.Actor.Facet.current.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(shiftClicked(ui.fragmentId), 0); }), (function() { var _ = Syndicate.__; return { assertion: shiftClicked(ui.fragmentId), metalevel: 0 }; }), (function() {})); + } }); }); + } + + function draggableMixin(obj, ui) { + idle(); + + function idle() { + (function () { Syndicate.Actor.Facet.build(function () { { + Syndicate.Actor.Facet.current.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(ui.event('.', 'mousedown', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: ui.event('.', 'mousedown', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) { + dragging(e.clientX - obj.x, e.clientY - obj.y); + })); + } }); }).call(this); + } + + function dragging(dx, dy) { + (function () { Syndicate.Actor.Facet.build(function () { { + Syndicate.Actor.Facet.current.onEvent(Syndicate.Actor.PRIORITY_NORMAL, false, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(uiRoot.event('.', 'mousemove', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: uiRoot.event('.', 'mousemove', (Syndicate._$("e"))), metalevel: 0 }; }), (function(e) { + obj.x = e.clientX - dx; + obj.y = e.clientY - dy; + })); + Syndicate.Actor.Facet.current.onEvent(Syndicate.Actor.PRIORITY_NORMAL, true, "message", (function() { var _ = Syndicate.__; return Syndicate.Patch.sub(uiRoot.event('.', 'mouseup', _), 0); }), (function() { var _ = Syndicate.__; return { assertion: uiRoot.event('.', 'mouseup', _), metalevel: 0 }; }), (function() { + idle(); + })); + } }); }).call(this); + } + } + } }); }); +}).startStepping(); diff --git a/examples/mixin/index.html b/examples/mixin/index.html new file mode 100644 index 0000000..c7c8b0a --- /dev/null +++ b/examples/mixin/index.html @@ -0,0 +1,38 @@ + + + + Syndicate: Mixin + + + + + + +
+

Mixin example

+

Source code: index.js

+

Drag shapes. Click for rectangles. Shift-click to delete a rectangle.

+
+
+ + + diff --git a/examples/mixin/index.js b/examples/mixin/index.js new file mode 100644 index 0000000..38133c7 --- /dev/null +++ b/examples/mixin/index.js @@ -0,0 +1,80 @@ +ground dataspace G { + message type shiftClicked(fragmentId); + + Syndicate.UI.spawnUIDriver(); + + spawn { + var uiRoot = new Syndicate.UI.Anchor(); + + assert uiRoot.html('#place', ''); + + spawn { + var ui = new Syndicate.UI.Anchor(); + assert ui.html('#svgroot', + '', + -1); + on message ui.event('.', 'click', $e) { + var svg = document.getElementById('svgroot'); + var pt = svg.createSVGPoint(); + pt.x = e.clientX; + pt.y = e.clientY; + pt = pt.matrixTransform(svg.getScreenCTM().inverse()); + spawnRectangle(pt.x, pt.y); + } + } + + spawn { + field this.x = 50; + field this.y = 50; + var ui = new Syndicate.UI.Anchor(); + assert ui.html('#svgroot', + '', + 0); + draggableMixin(this, ui); + } + + /////////////////////////////////////////////////////////////////////////// + + function spawnRectangle(x0, y0) { + var length = 90; + spawn { + field this.x = x0 - length / 2; + field this.y = y0 - length / 2; + var ui = new Syndicate.UI.Anchor(); + assert ui.html('#svgroot', + '', + 0); + draggableMixin(this, ui); + on message ui.event('.', 'mousedown', $e) { + if (e.shiftKey) { :: shiftClicked(ui.fragmentId); } + } + stop on message shiftClicked(ui.fragmentId); + } + } + + function draggableMixin(obj, ui) { + idle(); + + function idle() { + react { + stop on message ui.event('.', 'mousedown', $e) { + dragging(e.clientX - obj.x, e.clientY - obj.y); + } + } + } + + function dragging(dx, dy) { + react { + on message uiRoot.event('.', 'mousemove', $e) { + obj.x = e.clientX - dx; + obj.y = e.clientY - dy; + } + stop on message uiRoot.event('.', 'mouseup', _) { + idle(); + } + } + } + } + } +}