From effa81f6225a54e933623de24c30df60b4211537 Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Wed, 6 Apr 2016 14:27:15 -0700 Subject: [PATCH] Create fromJson for events. Add master-slave demo. --- core/blockly.js | 3 +- core/events.js | 120 +++++++++++++++++++++++++++++++++++++--- demos/index.html | 12 ++++ demos/mirror/icon.png | Bin 0 -> 2464 bytes demos/mirror/index.html | 76 +++++++++++++++++++++++++ 5 files changed, 203 insertions(+), 8 deletions(-) create mode 100644 demos/mirror/icon.png create mode 100644 demos/mirror/index.html diff --git a/core/blockly.js b/core/blockly.js index 85d311e6d..365255099 100644 --- a/core/blockly.js +++ b/core/blockly.js @@ -222,7 +222,8 @@ Blockly.onMouseMove_ = function(e) { * @private */ Blockly.onKeyDown_ = function(e) { - if (Blockly.isTargetInput_(e)) { + if (Blockly.mainWorkspace.options.readOnly || Blockly.isTargetInput_(e)) { + // No key actions on readonly workspaces. // When focused on an HTML text input widget, don't trap any keys. return; } diff --git a/core/events.js b/core/events.js index 8aafdfdb1..f890d85cb 100644 --- a/core/events.js +++ b/core/events.js @@ -239,6 +239,37 @@ Blockly.Events.getDescendantIds_ = function(block) { return ids; }; +/** + * Decode the JSON into an event. + * @param {!Object} json JSON representation. + * @param {!Blockly.Workspace} workspace Target workspace for event. + */ +Blockly.Events.fromJson = function(json, workspace) { + var event; + switch (json.type) { + case Blockly.Events.CREATE: + event = new Blockly.Events.Create(null); + break; + case Blockly.Events.DELETE: + event = new Blockly.Events.Delete(null); + break; + case Blockly.Events.CHANGE: + event = new Blockly.Events.Change(null); + break; + case Blockly.Events.MOVE: + event = new Blockly.Events.Move(null); + break; + case Blockly.Events.UI: + event = new Blockly.Events.Ui(null); + break; + default: + throw 'Unknown event type.' + } + event.fromJson(json); + event.workspaceId = workspace.id; + return event; +}; + /** * Abstract class for an event. * @param {Blockly.Block} block The block. @@ -260,8 +291,7 @@ Blockly.Events.Abstract = function(block) { Blockly.Events.Abstract.prototype.toJson = function() { var json = { 'type': this.type, - 'blockId': this.blockId, - 'workspaceId': this.workspaceId + 'blockId': this.blockId }; if (this.group) { json['group'] = this.group; @@ -269,6 +299,15 @@ Blockly.Events.Abstract.prototype.toJson = function() { return json; }; +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.Abstract.prototype.fromJson = function(json) { + this.blockId = json['blockId']; + this.group = json['group']; +}; + /** * Does this event record any change of state? * @return {boolean} True if null, false if something changed. @@ -287,11 +326,14 @@ Blockly.Events.Abstract.prototype.run = function(forward) { /** * Class for a block creation event. - * @param {!Blockly.Block} block The created block. + * @param {Blockly.Block} block The created block. Null for a blank event. * @extends {Blockly.Events.Abstract} * @constructor */ Blockly.Events.Create = function(block) { + if (!block) { + return; // Blank event to be populated by fromJson. + } Blockly.Events.Create.superClass_.constructor.call(this, block); this.xml = Blockly.Xml.blockToDomWithXY(block); this.ids = Blockly.Events.getDescendantIds_(block); @@ -315,13 +357,23 @@ Blockly.Events.Create.prototype.toJson = function() { return json; }; +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.Create.prototype.fromJson = function(json) { + Blockly.Events.Create.superClass_.fromJson.call(this, json); + this.xml = Blockly.Xml.textToDom('' + json['xml'] + '').firstChild; + this.ids = json['ids']; +}; + /** * Run a creation event. * @param {boolean} forward True if run forward, false if run backward (undo). */ Blockly.Events.Create.prototype.run = function(forward) { + var workspace = Blockly.Workspace.getById(this.workspaceId); if (forward) { - var workspace = Blockly.Workspace.getById(this.workspaceId); var xml = goog.dom.createDom('xml'); xml.appendChild(this.xml); Blockly.Xml.domToWorkspace(xml, workspace); @@ -340,11 +392,14 @@ Blockly.Events.Create.prototype.run = function(forward) { /** * Class for a block deletion event. - * @param {!Blockly.Block} block The deleted block. + * @param {Blockly.Block} block The deleted block. Null for a blank event. * @extends {Blockly.Events.Abstract} * @constructor */ Blockly.Events.Delete = function(block) { + if (!block) { + return; // Blank event to be populated by fromJson. + } if (block.getParent()) { throw 'Connected blocks cannot be deleted.'; } @@ -370,6 +425,15 @@ Blockly.Events.Delete.prototype.toJson = function() { return json; }; +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.Delete.prototype.fromJson = function(json) { + Blockly.Events.Delete.superClass_.fromJson.call(this, json); + this.ids = json['ids']; +}; + /** * Run a deletion event. * @param {boolean} forward True if run forward, false if run backward (undo). @@ -395,7 +459,7 @@ Blockly.Events.Delete.prototype.run = function(forward) { /** * Class for a block change event. - * @param {!Blockly.Block} block The changed block. + * @param {Blockly.Block} block The changed block. Null for a blank event. * @param {string} element One of 'field', 'comment', 'disabled', etc. * @param {?string} name Name of input or field affected, or null. * @param {string} oldValue Previous value of element. @@ -404,6 +468,9 @@ Blockly.Events.Delete.prototype.run = function(forward) { * @constructor */ Blockly.Events.Change = function(block, element, name, oldValue, newValue) { + if (!block) { + return; // Blank event to be populated by fromJson. + } Blockly.Events.Change.superClass_.constructor.call(this, block); this.element = element; this.name = name; @@ -432,6 +499,17 @@ Blockly.Events.Change.prototype.toJson = function() { return json; }; +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.Change.prototype.fromJson = function(json) { + Blockly.Events.Change.superClass_.fromJson.call(this, json); + this.element = json['element']; + this.name = json['name']; + this.newValue = json['newValue']; +}; + /** * Does this event record any change of state? * @return {boolean} True if something changed. @@ -498,11 +576,14 @@ Blockly.Events.Change.prototype.run = function(forward) { /** * Class for a block move event. Created before the move. - * @param {!Blockly.Block} block The moved block. + * @param {Blockly.Block} block The moved block. Null for a blank event. * @extends {Blockly.Events.Abstract} * @constructor */ Blockly.Events.Move = function(block) { + if (!block) { + return; // Blank event to be populated by fromJson. + } Blockly.Events.Move.superClass_.constructor.call(this, block); var location = this.currentLocation_(); this.oldParentId = location.parentId; @@ -536,6 +617,21 @@ Blockly.Events.Move.prototype.toJson = function() { return json; }; +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.Move.prototype.fromJson = function(json) { + Blockly.Events.Move.superClass_.fromJson.call(this, json); + this.newParentId = json['newParentId']; + this.newInputName = json['newInputName']; + if (json['newCoordinate']) { + var xy = json['newCoordinate'].split(','); + this.newCoordinate = + new goog.math.Coordinate(parseFloat(xy[0]), parseFloat(xy[1])); + } +}; + /** * Record the block's new location. Called after the move. */ @@ -662,3 +758,13 @@ Blockly.Events.Ui.prototype.toJson = function() { } return json; }; + +/** + * Decode the JSON event. + * @param {!Object} json JSON representation. + */ +Blockly.Events.Ui.prototype.fromJson = function(json) { + Blockly.Events.Ui.superClass_.fromJson.call(this, json); + this.element = json['element']; + this.newValue = json['newValue']; +}; diff --git a/demos/index.html b/demos/index.html index 3fe46a780..f9f9833e7 100644 --- a/demos/index.html +++ b/demos/index.html @@ -160,6 +160,18 @@ + + + + + + + +
Mirrored Blockly
+
Two Blockly instances connected as master-slave.
+ + + diff --git a/demos/mirror/icon.png b/demos/mirror/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..45e2a9a290cd7378b3c933f5e5e9e1dbf0df4a16 GIT binary patch literal 2464 zcmV;R319Y!P)SWDViciOhs!Nf*@2;7Uj*#qV5X2ymq<$<1Wi87#Ef} zYdD{o{eye%o_qFu&-tC-?|uP+Kp+qZ1OkCTAP@)y0)apv5C{YUfj}Ub>`1_rU>V5g zvi;36S?J{-8EFTP)n zv$r2-Z@(X1sZf4)A6AwK%QFv2cP@#h<4hGAl}vo})WCO$af4F znMa;KHe7kmS<0U_&LrGuBpaEY(W=vwWH!!=B7{NOYRlPYR*%>X-&!4mPCbaVrJg;N z$|4%@G&_Cj+q9Hekeru&Js~9)z2v0Ye95QJDAG(CZ1onJ{rFwZ?hDLGnMLUp*M|gZ zZSRn0#6?R13!+jftEk^K_=UvX!P-7$;#_X*NQ7R|zHRnmcV;*9n?GI=PUTrV`FIv4E%aMX@k0C1_4#bMCxhuY`QWJ{c6-Eo z_(#jhGD?`s_VDz6r(eHi(ZV@bZJP)&zK|>{G$Mwr_uZj<9>`>&uEHC6Sj~H#{I;GtO;l^3qm8tAtTy6&B85DTLa9A3+ zzwo%vLrzfJ4xl4F->7ILFJ!J!0&E=F?+C6eYr=cfMlvrca>V5jZPe$zL2d}M*CNU|2^tDC|fTQIkKYODFfLe7P1xpRYCq*ecPaVMz9={!f795s( z9xALD@tj>X7s!d5N@7wnaGs=9aZ10IbCe)`$px`BvGw<-F{Ee!h&P$YUmAxYX)aq= z)Kly$QkaqiwECPGa=QZu5Dw_oN;tK5p7XXh7ME~Ou@a&R76NE6Xg#kl8k$BAn`I5O zAS4S-YWw-60-(|Gos`$LOsGZ*_6I?hT%hh z@!i>MS)0wK9Q}|S{Oow%L;3T?=7yglVdcHzUpp%YCOrwfjI75 zI!!rODvxsf%x%~*O&F3Ev2Bxq<2_M)JxvSrapI7j`E!+i5|Mei@Fa_#o`=Dh#FHz| zQgr3Usx)I>9gRt=?8=izYXScYMqR|!Ym5_T&&l(XV^l!Esj515S|puzCt6Jic1JI6 z*8rA=6FBWwW+bMdGba06%X)eYCEj>>C~(-Uy!-Y?>_f$3pL-jNODK+A&C28m(wAhA zK6Fmhl(YS4C~%BjC3=3CH=TIXY~nrNZLB%LtClGgc(N=f5|UKIE5~NCB{LFJ)-5Df z`-}-dYUSwJ9!&GXptpm6j^6QJyOT3dp>hpZ9M=7 z$1BE$jzaAb}fjAbVlw>xf>IuP3 zV`UX(mMJ3&!*66q5F)v0Dl?BrpZ#U!ch|5fHI&B6gZ$zj*0JX+mNP8-TK2)%so~37 ztd~%GYB-nM&Hs)cCx2xQ%^lt279>o*q~v_|u5Nkl_qGC%zv6Zt*qDz#GD3o33-?Ag zs1nj|Wm9Gp2}ydwv9a^1eUt@|?xxI~N~BJU%k9Q`(TUa8MMq0L>sROSaaG&61Q{~8 z)PQ&L0ZMoOfkz+wa=oRUZi;1Il9C%YmRAKN20&}aCG-&kSZ!Sl`kWer&htT7hXf&? z{k@DGHF~h0p~4b)Hrd_i@Z%rs%`9es>J&mWys(PU6A8_PSL=ufDNwBwt5n$soDALW4WVdZtWeV zGvcCi13p89!8Kt9S8hxPmTZO?HDTU_pez6=apVFu45V z8U|PC{N$L4$+BXnDF?7t6XLB%Tg_E8)*Qy!d3G#&&9g*8i8n@iKjCV{;Cj7q4|}}_ zsE@&Qwj0opz9fV1ER7)?AA_so7`sZWIDmN5Y*wX35$a=b4W-k=2AA@}(3EuxiN0e3 zufe6f=NP}ib=j^vP+j_~7e6Z9d!&vJ{#{cF1fC+aS?#65;PNwHv7Di3=g)I%>f1|; z4xb)ja6S9zw + + + + Blockly Demo: Mirrored Blockly + + + + + + +

Blockly > + Demos > Mirrored Blockly

+ +

This is a simple demo of a master Blockly that controls a slave Blockly. + Open the JavaScript console to see the event passing.

+ +

→ More info on events

+ + + + + + +
+
+
+
+
+ + + + + + +