diff options
| author | jmoenig <jens@moenig.org> | 2013-11-15 11:18:45 +0100 |
|---|---|---|
| committer | jmoenig <jens@moenig.org> | 2013-11-15 11:18:45 +0100 |
| commit | 81654e72997c1577181d6729660c110ed1b9e20f (patch) | |
| tree | 7a03fd5c340f72ca557cd3b6c93a87c0d19435cb | |
| parent | cc0bf15c1a9172c494fd527ad4c15a31014fee75 (diff) | |
| download | snap-byow-81654e72997c1577181d6729660c110ed1b9e20f.tar.gz snap-byow-81654e72997c1577181d6729660c110ed1b9e20f.zip | |
„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" option
| -rw-r--r-- | blocks.js | 34 | ||||
| -rw-r--r-- | byob.js | 47 | ||||
| -rwxr-xr-x | history.txt | 5 | ||||
| -rw-r--r-- | store.js | 15 |
4 files changed, 83 insertions, 18 deletions
@@ -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 () { @@ -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); diff --git a/history.txt b/history.txt index c82f6ff..3f63d3d 100755 --- a/history.txt +++ b/history.txt @@ -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 @@ -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) : '', |
