-
Notifications
You must be signed in to change notification settings - Fork 39
/
menuly_override.js
144 lines (104 loc) · 4.85 KB
/
menuly_override.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
'use strict';
// Disable blocks lying around the workspace unconnected to our main start block.
// (original idea stolen from OpenRoberta and optimized)
var original_onMouseUp_ = Blockly.Block.prototype.onMouseUp_;
Blockly.Block.prototype.onMouseUp_ = function(e) {
original_onMouseUp_.call(this, e);
if (Blockly.selected) {
var rootBlock = Blockly.selected.getRootBlock();
var isDisabled = (rootBlock.type != 'start');
var descendants = Blockly.selected.getDescendants();
for(var i in descendants) {
descendants[i].setDisabled(isDisabled);
}
}
};
Blockly.FieldDropdown.prototype.setValue = function(newValue) { // Allow the label on the closed menu to differ from values of the open menu
this.value_ = newValue;
// Look up and display the human-readable text.
var options = this.getOptions_();
for(var x = 0; x < options.length; x++) {
// Options are tuples of human-readable text and language-neutral values.
if (options[x][1] == newValue) {
var shortValue = options[x][2] || options[x][0];
this.setText(shortValue);
return;
}
}
};
Blockly.Input.prototype.appendSelector = function(allowedBlocks, presenceLabel, absenceLabel) {
var presenceLabel = presenceLabel || this.name;
var absenceLabel = absenceLabel || 'no '+this.name;
var ddl_name = 'ddl_'+this.name;
var dd_list = [
[ absenceLabel, ':REMOVE', absenceLabel]
];
if(allowedBlocks.length == 1) {
dd_list.push( [presenceLabel+': ', allowedBlocks[0], presenceLabel ] );
} else {
for(var i = 0; i < allowedBlocks.length; i++) {
dd_list.push( [allowedBlocks[i], allowedBlocks[i], presenceLabel ] );
}
}
var this_input = this;
this//.setCheck(allowedBlocks) // FIXME: we'll need to re-establish the connection rules somehow!
.setAlign( this.type == Blockly.INPUT_VALUE ? Blockly.ALIGN_RIGHT : Blockly.ALIGN_LEFT)
.appendField(new Blockly.FieldDropdown( dd_list, function(targetType) {
return this.sourceBlock_.toggleTargetBlock(this_input, targetType);
}
), ddl_name);
return this;
};
Blockly.Block.prototype.toggleTargetBlock = function(input, targetType) { // universal version: can create any type of targetBlocks
var targetBlock = input ? this.getInputTargetBlock(input.name) : this.getNextBlock(); // named input or next
if( targetType==':REMOVE' ) {
if(targetBlock) {
targetBlock.dispose(true, true); // or targetBlock.unplug(...)
}
} else {
if(targetBlock) { // Don't remove it, but return the "override" value to make sure the DDL is up to date:
return targetBlock.type;
} else { // add a new kind of block:
targetBlock = Blockly.Block.obtain(Blockly.getMainWorkspace(), targetType);
targetBlock.initSvg();
targetBlock.render();
var parentConnection = input ? this.getInput(input.name).connection : this.nextConnection; // named input or next
var childConnection = targetBlock.outputConnection || targetBlock.previousConnection; // vertical or horizontal
parentConnection.connect(childConnection);
}
}
};
// A very useful mapping from connection back to input
Blockly.Connection.prototype.getInput = function() {
var inputList = this.sourceBlock_.inputList;
for(var i in inputList) {
var connection = inputList[i].connection;
if(connection == this) {
return inputList[i];
}
}
};
// If there is a ddl linked with the input, update its label to the type of the block plugged in:
Blockly.Input.prototype.updateLinkedDDL = function() {
var ddl_name = 'ddl_'+this.name;
var ddl_field = this.sourceBlock_.getField_(ddl_name);
if(ddl_field) {
var targetBlock = this.connection.targetBlock();
var type = targetBlock ? targetBlock.type : ':REMOVE';
ddl_field.setValue(type);
}
}
// Update the DDL on connect() :
var original_connect = Blockly.Connection.prototype.connect;
Blockly.Connection.prototype.connect = function(otherConnection) {
original_connect.call(this, otherConnection);
var parentConnection = this.isSuperior() ? this : otherConnection; // since connect() is symmetrical we never know which way it is called
parentConnection.getInput().updateLinkedDDL();
};
// Update the DDL on disconnect() :
var original_disconnect = Blockly.Connection.prototype.disconnect;
Blockly.Connection.prototype.disconnect = function() {
var parentConnection = this.isSuperior() ? this : this.targetConnection; // since disconnect() is symmetrical we never know which way it is called
original_disconnect.call(this);
parentConnection.getInput().updateLinkedDDL();
};