mirror of
https://github.com/google/blockly.git
synced 2026-03-14 01:00:09 +01:00
Create fromJson for events. Add master-slave demo.
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
120
core/events.js
120
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('<xml>' + json['xml'] + '</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'];
|
||||
};
|
||||
|
||||
@@ -160,6 +160,18 @@
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="mirror/index.html">
|
||||
<img src="mirror/icon.png" height=80 width=100>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<div><a href="mirror/index.html">Mirrored Blockly</a></div>
|
||||
<div>Two Blockly instances connected as master-slave.</div>
|
||||
</td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="code/index.html">
|
||||
|
||||
BIN
demos/mirror/icon.png
Normal file
BIN
demos/mirror/icon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
76
demos/mirror/index.html
Normal file
76
demos/mirror/index.html
Normal file
@@ -0,0 +1,76 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Blockly Demo: Mirrored Blockly</title>
|
||||
<script src="../../blockly_compressed.js"></script>
|
||||
<script src="../../blocks_compressed.js"></script>
|
||||
<script src="../../msg/js/en.js"></script>
|
||||
<style>
|
||||
body {
|
||||
background-color: #fff;
|
||||
font-family: sans-serif;
|
||||
}
|
||||
h1 {
|
||||
font-weight: normal;
|
||||
font-size: 140%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1><a href="https://developers.google.com/blockly/">Blockly</a> >
|
||||
<a href="../index.html">Demos</a> > Mirrored Blockly</h1>
|
||||
|
||||
<p>This is a simple demo of a master Blockly that controls a slave Blockly.
|
||||
Open the JavaScript console to see the event passing.</p>
|
||||
|
||||
<p>→ More info on <a href="https://developers.google.com/blockly/hacking/events">events</a>…</p>
|
||||
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<div id="masterDiv" style="height: 480px; width: 600px;"></div>
|
||||
</td>
|
||||
<td>
|
||||
<div id="slaveDiv" style="height: 480px; width: 430px;"></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<xml id="toolbox" style="display: none">
|
||||
<block type="controls_if"></block>
|
||||
<block type="logic_compare"></block>
|
||||
<block type="controls_repeat_ext"></block>
|
||||
<block type="math_number"></block>
|
||||
<block type="math_arithmetic"></block>
|
||||
<block type="text"></block>
|
||||
<block type="text_print"></block>
|
||||
</xml>
|
||||
|
||||
<script>
|
||||
// Inject master workspace.
|
||||
var masterWorkspace = Blockly.inject('masterDiv',
|
||||
{media: '../../media/',
|
||||
toolbox: document.getElementById('toolbox')});
|
||||
// Inject slave workspace.
|
||||
var slaveWorkspace = Blockly.inject('slaveDiv',
|
||||
{media: '../../media/',
|
||||
readOnly: true});
|
||||
// Listen to events on master workspace.
|
||||
masterWorkspace.addChangeListener(mirrorEvent);
|
||||
|
||||
function mirrorEvent(masterEvent) {
|
||||
if (masterEvent.type == Blockly.Events.UI) {
|
||||
return; // Don't mirror UI events.
|
||||
}
|
||||
// Convert event to JSON. This could then be transmitted across the net.
|
||||
var json = masterEvent.toJson();
|
||||
console.log(json);
|
||||
// Convert JSON back into an event, then execute it.
|
||||
var slaveEvent = Blockly.Events.fromJson(json, slaveWorkspace);
|
||||
slaveEvent.run(true);
|
||||
}
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user