-
-
Notifications
You must be signed in to change notification settings - Fork 235
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a Blockly block to define key/value dictionaries (#1209)
Signed-off-by: Yannick Schaus <github@schaus.net>
- Loading branch information
Showing
3 changed files
with
178 additions
and
0 deletions.
There are no files selected for viewing
174 changes: 174 additions & 0 deletions
174
bundles/org.openhab.ui/web/src/assets/definitions/blockly/blocks-dicts.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
import Blockly from 'blockly' | ||
|
||
export default function (f7) { | ||
Blockly.Blocks['dicts_create_with'] = { | ||
/** | ||
* Block for creating a list with any number of elements of any type. | ||
* @this {Blockly.Block} | ||
*/ | ||
init: function () { | ||
this.setStyle('list_blocks') | ||
this.itemCount_ = 3 | ||
this.updateShape_() | ||
this.setOutput(true, 'Dictionary') | ||
this.setMutator(new Blockly.Mutator(['dicts_create_with_item'])) | ||
this.setTooltip('Create a key/value dictionary') | ||
}, | ||
/** | ||
* Create XML to represent list inputs. | ||
* @return {!Element} XML storage element. | ||
* @this {Blockly.Block} | ||
*/ | ||
mutationToDom: function () { | ||
let container = Blockly.utils.xml.createElement('mutation') | ||
container.setAttribute('items', this.itemCount_) | ||
return container | ||
}, | ||
/** | ||
* Parse XML to restore the list inputs. | ||
* @param {!Element} xmlElement XML storage element. | ||
* @this {Blockly.Block} | ||
*/ | ||
domToMutation: function (xmlElement) { | ||
this.itemCount_ = parseInt(xmlElement.getAttribute('items'), 10) | ||
this.updateShape_() | ||
}, | ||
/** | ||
* Populate the mutator's dialog with this block's components. | ||
* @param {!Blockly.Workspace} workspace Mutator's workspace. | ||
* @return {!Blockly.Block} Root block in mutator. | ||
* @this {Blockly.Block} | ||
*/ | ||
decompose: function (workspace) { | ||
let containerBlock = workspace.newBlock('dicts_create_with_container') | ||
containerBlock.initSvg() | ||
let connection = containerBlock.getInput('STACK').connection | ||
for (let i = 0; i < this.itemCount_; i++) { | ||
let itemBlock = workspace.newBlock('dicts_create_with_item') | ||
itemBlock.initSvg() | ||
connection.connect(itemBlock.previousConnection) | ||
connection = itemBlock.nextConnection | ||
} | ||
return containerBlock | ||
}, | ||
/** | ||
* Reconfigure this block based on the mutator dialog's components. | ||
* @param {!Blockly.Block} containerBlock Root block in mutator. | ||
* @this {Blockly.Block} | ||
*/ | ||
compose: function (containerBlock) { | ||
let itemBlock = containerBlock.getInputTargetBlock('STACK') | ||
// Count number of inputs. | ||
let connections = [] | ||
while (itemBlock && !itemBlock.isInsertionMarker()) { | ||
connections.push(itemBlock.valueConnection_) | ||
itemBlock = itemBlock.nextConnection && | ||
itemBlock.nextConnection.targetBlock() | ||
} | ||
// Disconnect any children that don't belong. | ||
for (let i = 0; i < this.itemCount_; i++) { | ||
let input = this.getInput('ADD' + i) | ||
if (!input) continue | ||
let connection = input.connection.targetConnection | ||
if (connection && connections.indexOf(connection) === -1) { | ||
connection.disconnect() | ||
} | ||
} | ||
this.itemCount_ = connections.length | ||
this.updateShape_() | ||
// Reconnect any child blocks. | ||
for (let i = 0; i < this.itemCount_; i++) { | ||
Blockly.Mutator.reconnect(connections[i], this, 'ADD' + i) | ||
} | ||
}, | ||
/** | ||
* Store pointers to any connected child blocks. | ||
* @param {!Blockly.Block} containerBlock Root block in mutator. | ||
* @this {Blockly.Block} | ||
*/ | ||
saveConnections: function (containerBlock) { | ||
let itemBlock = containerBlock.getInputTargetBlock('STACK') | ||
let i = 0 | ||
while (itemBlock) { | ||
let input = this.getInput('ADD' + i) | ||
itemBlock.valueConnection_ = input && input.connection.targetConnection | ||
i++ | ||
itemBlock = itemBlock.nextConnection && | ||
itemBlock.nextConnection.targetBlock() | ||
} | ||
}, | ||
/** | ||
* Modify this block to have the correct number of inputs. | ||
* @private | ||
* @this {Blockly.Block} | ||
*/ | ||
updateShape_: function () { | ||
if (this.itemCount_ && this.getInput('EMPTY')) { | ||
this.removeInput('EMPTY') | ||
} else if (!this.itemCount_ && !this.getInput('EMPTY')) { | ||
this.appendDummyInput('EMPTY') | ||
.appendField('create empty dictionary') | ||
} | ||
// Add new inputs. | ||
let i | ||
for (i = 0; i < this.itemCount_; i++) { | ||
if (!this.getInput('ADD' + i)) { | ||
let input = this.appendValueInput('ADD' + i) | ||
.setAlign(Blockly.ALIGN_RIGHT) | ||
if (i === 0) { | ||
input.appendField('dictionary of') | ||
} | ||
input.appendField(new Blockly.FieldTextInput('key' + i), 'KEY' + i) | ||
} | ||
} | ||
// Remove deleted inputs. | ||
while (this.getInput('ADD' + i)) { | ||
this.removeInput('ADD' + i) | ||
i++ | ||
} | ||
} | ||
} | ||
|
||
Blockly.Blocks['dicts_create_with_container'] = { | ||
/** | ||
* Mutator block for list container. | ||
* @this {Blockly.Block} | ||
*/ | ||
init: function () { | ||
this.setStyle('list_blocks') | ||
this.appendDummyInput() | ||
.appendField('key/values') | ||
this.appendStatementInput('STACK') | ||
this.setTooltip('Initialize a Dictionary') | ||
this.contextMenu = false | ||
} | ||
} | ||
|
||
Blockly.Blocks['dicts_create_with_item'] = { | ||
/** | ||
* Mutator block for adding items. | ||
* @this {Blockly.Block} | ||
*/ | ||
init: function () { | ||
this.setStyle('list_blocks') | ||
this.appendDummyInput() | ||
.appendField('key') | ||
this.setPreviousStatement(true) | ||
this.setNextStatement(true) | ||
this.setTooltip('add a key/value to the dictionary') | ||
this.contextMenu = false | ||
} | ||
} | ||
|
||
Blockly.JavaScript['dicts_create_with'] = function (block) { | ||
// Create an object with any number of elements of any type. | ||
let elements = new Array(block.itemCount_) | ||
for (let i = 0; i < block.itemCount_; i++) { | ||
elements[i] = '\'' + block.getFieldValue('KEY' + i) + '\': ' | ||
elements[i] += Blockly.JavaScript.valueToCode(block, 'ADD' + i, | ||
Blockly.JavaScript.ORDER_NONE) || 'null' | ||
} | ||
let code = '{' + elements.join(', ') + '}' | ||
return [code, Blockly.JavaScript.ORDER_ATOMIC] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters