kopia lustrzana https://github.com/backface/turtlestitch
„read-only“ option for editable custom block input slots
also custom block input slots reverting to default now show their default value (useful in combination with the new "read-only" optionpull/3/merge
rodzic
cc0bf15c1a
commit
81654e7299
34
blocks.js
34
blocks.js
|
@ -155,7 +155,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph, Costume*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.blocks = '2013-November-12';
|
||||
modules.blocks = '2013-November-15';
|
||||
|
||||
var SyntaxElementMorph;
|
||||
var BlockMorph;
|
||||
|
@ -518,10 +518,13 @@ SyntaxElementMorph.prototype.revertToDefaultInput = function (arg, noValues) {
|
|||
if (this instanceof BlockMorph) {
|
||||
deflt = this.labelPart(this.parseSpec(this.blockSpec)[idx]);
|
||||
if (deflt instanceof InputSlotMorph && this.definition) {
|
||||
deflt.choices = this.definition.dropDownMenuOfInputIdx(
|
||||
this.inputs().indexOf(arg)
|
||||
deflt.setChoices.apply(
|
||||
deflt,
|
||||
this.definition.inputOptionsOfIdx(inp)
|
||||
);
|
||||
deflt.setContents(
|
||||
this.definition.defaultValueOfInputIdx(inp)
|
||||
);
|
||||
deflt.fixLayout();
|
||||
}
|
||||
} else if (this instanceof MultiArgMorph) {
|
||||
deflt = this.labelPart(this.slotSpec);
|
||||
|
@ -1912,8 +1915,10 @@ BlockMorph.prototype.setSpec = function (spec) {
|
|||
myself.add(myself.placeHolder());
|
||||
}
|
||||
if (part instanceof InputSlotMorph && myself.definition) {
|
||||
part.choices = myself.definition.dropDownMenuOfInputIdx(inputIdx);
|
||||
part.fixLayout(); // needed when de-serializing
|
||||
part.setChoices.apply(
|
||||
part,
|
||||
myself.definition.inputOptionsOfIdx(inputIdx)
|
||||
);
|
||||
}
|
||||
});
|
||||
this.blockSpec = spec;
|
||||
|
@ -6593,6 +6598,23 @@ InputSlotMorph.prototype.getVarNamesDict = function () {
|
|||
return {};
|
||||
};
|
||||
|
||||
InputSlotMorph.prototype.setChoices = function (dict, readonly) {
|
||||
// externally specify choices and read-only status,
|
||||
// used for custom blocks
|
||||
var cnts = this.contents();
|
||||
this.choices = dict;
|
||||
this.isReadOnly = readonly || false;
|
||||
if (this.parent instanceof BlockMorph) {
|
||||
this.parent.fixLabelColor();
|
||||
if (!readonly) {
|
||||
cnts.shadowOffset = new Point();
|
||||
cnts.shadowColor = null;
|
||||
cnts.setColor(new Color(0, 0, 0));
|
||||
}
|
||||
}
|
||||
this.fixLayout();
|
||||
};
|
||||
|
||||
// InputSlotMorph layout:
|
||||
|
||||
InputSlotMorph.prototype.fixLayout = function () {
|
||||
|
|
47
byob.js
47
byob.js
|
@ -106,7 +106,7 @@ SymbolMorph, isNil*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.byob = '2013-November-12';
|
||||
modules.byob = '2013-November-15';
|
||||
|
||||
// Declarations
|
||||
|
||||
|
@ -137,7 +137,8 @@ function CustomBlockDefinition(spec, receiver) {
|
|||
this.isGlobal = false;
|
||||
this.type = 'command';
|
||||
this.spec = spec || '';
|
||||
this.declarations = {}; // {'inputName' : [type, default, options]}
|
||||
// format: {'inputName' : [type, default, options, readonly]}
|
||||
this.declarations = {};
|
||||
this.comment = null;
|
||||
this.codeMapping = null; // experimental, generate text code
|
||||
this.codeHeader = null; // experimental, generate text code
|
||||
|
@ -193,6 +194,7 @@ CustomBlockDefinition.prototype.prototypeInstance = function () {
|
|||
part.fragment.type = slot[0];
|
||||
part.fragment.defaultValue = slot[1];
|
||||
part.fragment.options = slot[2];
|
||||
part.fragment.isReadonly = slot[3] || false;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -271,6 +273,16 @@ CustomBlockDefinition.prototype.dropDownMenuOfInputIdx = function (idx) {
|
|||
return this.dropDownMenuOf(inputName);
|
||||
};
|
||||
|
||||
CustomBlockDefinition.prototype.isReadOnlyInputIdx = function (idx) {
|
||||
var inputName = this.inputNames()[idx];
|
||||
return this.isReadOnlyInput(inputName);
|
||||
};
|
||||
|
||||
CustomBlockDefinition.prototype.inputOptionsOfIdx = function (idx) {
|
||||
var inputName = this.inputNames()[idx];
|
||||
return this.inputOptionsOf(inputName);
|
||||
};
|
||||
|
||||
CustomBlockDefinition.prototype.dropDownMenuOf = function (inputName) {
|
||||
var dict = {};
|
||||
if (this.declarations[inputName] && this.declarations[inputName][2]) {
|
||||
|
@ -283,6 +295,18 @@ CustomBlockDefinition.prototype.dropDownMenuOf = function (inputName) {
|
|||
return null;
|
||||
};
|
||||
|
||||
CustomBlockDefinition.prototype.isReadOnlyInput = function (inputName) {
|
||||
return this.declarations[inputName] &&
|
||||
this.declarations[inputName][3] === true;
|
||||
};
|
||||
|
||||
CustomBlockDefinition.prototype.inputOptionsOf = function (inputName) {
|
||||
return [
|
||||
this.dropDownMenuOf(inputName),
|
||||
this.isReadOnlyInput(inputName)
|
||||
];
|
||||
};
|
||||
|
||||
CustomBlockDefinition.prototype.inputNames = function () {
|
||||
var vNames = [],
|
||||
parts = this.parseSpec(this.spec);
|
||||
|
@ -355,8 +379,7 @@ CustomCommandBlockMorph.prototype.refresh = function () {
|
|||
} else { // update all input slots' drop-downs
|
||||
this.inputs().forEach(function (inp, i) {
|
||||
if (inp instanceof InputSlotMorph) {
|
||||
inp.choices = def.dropDownMenuOfInputIdx(i);
|
||||
inp.fixLayout();
|
||||
inp.setChoices.apply(inp, def.inputOptionsOfIdx(i));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -565,7 +588,8 @@ CustomCommandBlockMorph.prototype.declarationsFromFragments = function () {
|
|||
ans[part.fragment.labelString] = [
|
||||
part.fragment.type,
|
||||
part.fragment.defaultValue,
|
||||
part.fragment.options
|
||||
part.fragment.options,
|
||||
part.fragment.isReadOnly
|
||||
];
|
||||
}
|
||||
});
|
||||
|
@ -1888,6 +1912,7 @@ function BlockLabelFragment(labelString) {
|
|||
this.type = '%s'; // null for label, a spec for an input
|
||||
this.defaultValue = '';
|
||||
this.options = '';
|
||||
this.isReadOnly = false; // for input slots
|
||||
this.isDeleted = false;
|
||||
}
|
||||
|
||||
|
@ -1938,6 +1963,7 @@ BlockLabelFragment.prototype.copy = function () {
|
|||
ans.type = this.type;
|
||||
ans.defaultValue = this.defaultValue;
|
||||
ans.options = this.options;
|
||||
ans.isReadOnly = this.isReadOnly;
|
||||
return ans;
|
||||
};
|
||||
|
||||
|
@ -2832,8 +2858,17 @@ InputSlotDialogMorph.prototype.addSlotsMenu = function () {
|
|||
|
||||
this.slots.userMenu = function () {
|
||||
if (contains(['%s', '%n', '%txt', '%anyUE'], myself.fragment.type)) {
|
||||
var menu = new MenuMorph(myself);
|
||||
var menu = new MenuMorph(myself),
|
||||
on = '\u2611 ',
|
||||
off = '\u2610 ';
|
||||
menu.addItem('options...', 'editSlotOptions');
|
||||
menu.addItem(
|
||||
(myself.fragment.isReadOnly ? on : off) +
|
||||
localize('read-only'),
|
||||
function () {myself.fragment.isReadOnly =
|
||||
!myself.fragment.isReadOnly;
|
||||
}
|
||||
);
|
||||
return menu;
|
||||
}
|
||||
return Morph.prototype.userMenu.call(myself);
|
||||
|
|
|
@ -1993,3 +1993,8 @@ ______
|
|||
* Objects: fixed wrong NaN display for variable watchers
|
||||
* Blocks: left-align multi-line text in value-bubbles
|
||||
* Portuguese translation update, thanks, Manuel!
|
||||
|
||||
131115
|
||||
------
|
||||
* Blocks, BYOB, Store: „read-only“ option for editable custom block input slots
|
||||
* BYOB, Blocks: custom block input slots reverting to default now show their default value
|
||||
|
|
15
store.js
15
store.js
|
@ -61,7 +61,7 @@ SyntaxElementMorph*/
|
|||
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.store = '2013-November-12';
|
||||
modules.store = '2013-November-15';
|
||||
|
||||
|
||||
// XML_Serializer ///////////////////////////////////////////////////////
|
||||
|
@ -749,7 +749,8 @@ SnapSerializer.prototype.loadCustomBlocks = function (
|
|||
definition.declarations[names[i]] = [
|
||||
child.attributes.type,
|
||||
child.contents,
|
||||
options ? options.contents : undefined
|
||||
options ? options.contents : undefined,
|
||||
child.attributes.readonly === 'true'
|
||||
];
|
||||
});
|
||||
}
|
||||
|
@ -1663,13 +1664,15 @@ CustomBlockDefinition.prototype.toXML = function (serializer) {
|
|||
this.codeMapping || '',
|
||||
Object.keys(this.declarations).reduce(function (xml, decl) {
|
||||
return xml + serializer.format(
|
||||
'<input type="@">$%</input>',
|
||||
'<input type="@"$>$%</input>',
|
||||
myself.declarations[decl][0],
|
||||
myself.declarations[decl][3] ?
|
||||
' readonly="true"' : '',
|
||||
myself.declarations[decl][1],
|
||||
myself.declarations[decl][2] ?
|
||||
'<options>' + myself.declarations[decl][2] +
|
||||
'</options>'
|
||||
: ''
|
||||
'<options>' + myself.declarations[decl][2] +
|
||||
'</options>'
|
||||
: ''
|
||||
);
|
||||
}, ''),
|
||||
this.body ? serializer.store(this.body.expression) : '',
|
||||
|
|
Ładowanie…
Reference in New Issue