I recommend that “Template” and “Tutorial” be moved/added to the Stage script area, like this:
That way, it fills the gap that the “draggable” button left there.
I rewrote the function that adds the draggable button:
IDE_Morph.prototype.createSpriteBar = function () {
// assumes that the categories pane has already been created
var rotationStyleButtons = [],
thumbSize = new Point(45, 45),
nameField,
padlock,
thumbnail,
tabCorner = 15,
tabColors = this.tabColors,
tabBar = new AlignmentMorph('row', -tabCorner * 2),
tab,
symbols = [
new SymbolMorph('arrowRightThin', 10),
new SymbolMorph('turnAround', 10),
new SymbolMorph('arrowLeftRightThin', 10),
],
labels = ["don't rotate", 'can rotate', 'only face left/right'],
myself = this;
if (this.spriteBar) {
this.spriteBar.destroy();
}
this.spriteBar = new Morph();
this.spriteBar.color = this.frameColor;
this.add(this.spriteBar);
function addRotationStyleButton(rotationStyle) {
var colors = myself.rotationStyleColors,
button;
button = new ToggleButtonMorph(
colors,
myself, // the IDE is the target
() => {
if (myself.currentSprite instanceof SpriteMorph) {
myself.currentSprite.rotationStyle = rotationStyle;
myself.currentSprite.changed();
myself.currentSprite.fixLayout();
myself.currentSprite.rerender();
myself.currentSprite.recordUserEdit(
'sprite',
'rotation',
rotationStyle
);
}
rotationStyleButtons.forEach(each =>
each.refresh()
);
},
symbols[rotationStyle], // label
() => myself.currentSprite instanceof SpriteMorph // query
&& myself.currentSprite.rotationStyle === rotationStyle,
null, // environment
localize(labels[rotationStyle])
);
button.corner = 8;
button.labelMinExtent = new Point(11, 11);
button.padding = 0;
button.labelShadowOffset = new Point(-1, -1);
button.labelShadowColor = colors[1];
button.labelColor = myself.buttonLabelColor;
button.fixLayout();
button.refresh();
rotationStyleButtons.push(button);
button.setPosition(myself.spriteBar.position().add(new Point(2, 4)));
button.setTop(button.top()
+ ((rotationStyleButtons.length - 1) * (button.height() + 2))
);
myself.spriteBar.add(button);
if (myself.currentSprite instanceof StageMorph) {
button.hide();
}
return button;
}
addRotationStyleButton(1);
addRotationStyleButton(2);
addRotationStyleButton(0);
this.rotationStyleButtons = rotationStyleButtons;
thumbnail = new Morph();
thumbnail.isCachingImage = true;
thumbnail.bounds.setExtent(thumbSize);
thumbnail.cachedImage = this.currentSprite.thumbnail(thumbSize);
thumbnail.setPosition(
rotationStyleButtons[0].topRight().add(new Point(5, 3))
);
this.spriteBar.add(thumbnail);
thumbnail.fps = 3;
thumbnail.step = function () {
if (thumbnail.version !== myself.currentSprite.version) {
thumbnail.cachedImage = myself.currentSprite.thumbnail(
thumbSize,
thumbnail.cachedImage
);
thumbnail.changed();
thumbnail.version = myself.currentSprite.version;
}
};
nameField = new InputFieldMorph(this.currentSprite.name);
nameField.setWidth(100); // fixed dimensions
nameField.contrast = 90;
nameField.setPosition(thumbnail.topRight().add(new Point(10, 3)));
this.spriteBar.add(nameField);
this.spriteBar.nameField = nameField;
nameField.fixLayout();
nameField.accept = function () {
var newName = nameField.getValue();
myself.currentSprite.setName(
myself.newSpriteName(newName, myself.currentSprite)
);
nameField.setContents(myself.currentSprite.name);
};
this.spriteBar.reactToEdit = nameField.accept;
createControlToggle = (label, callback, getter) => {
let controlToggle = new ToggleMorph(
'checkbox',
null,
callback,
label,
getter
);
controlToggle.label.isBold = false;
controlToggle.label.setColor(this.buttonLabelColor);
controlToggle.color = tabColors[2];
controlToggle.highlightColor = tabColors[0];
controlToggle.pressColor = tabColors[1];
controlToggle.tick.shadowOffset = MorphicPreferences.isFlat ?
ZERO : new Point(-1, -1);
controlToggle.tick.shadowColor = BLACK;
controlToggle.tick.color = this.buttonLabelColor;
controlToggle.tick.isBold = false;
controlToggle.tick.fixLayout();
controlToggle.setPosition(nameField.bottomLeft().add(2));
controlToggle.fixLayout();
return controlToggle;
}
// padlock
padlock = createControlToggle(
localize('draggable'),
() => {
this.currentSprite.isDraggable = !this.currentSprite.isDraggable;
this.currentSprite.recordUserEdit(
'sprite',
'draggable',
this.currentSprite.isDraggable
);
},
() => this.currentSprite.isDraggable),
this.spriteBar.add(padlock);
sceneControls = new AlignmentMorph('row');
template = createControlToggle(
localize('template'),
() => {
this.scene.role = this.scene.role === 'template' ?
null : 'template'
},
() => this.scene.role === 'template'
);
tutorial = createControlToggle(
localize('tutorial'),
() => {
this.scene.role = this.scene.role === 'tutorial' ?
null : 'tutorial'
},
() => this.scene.role === 'tutorial'
);
sceneControls.add(template);
sceneControls.add(tutorial);
sceneControls.fixLayout();
this.spriteBar.add(sceneControls);
if (this.currentSprite instanceof StageMorph) {
padlock.hide();
} else {
sceneControls.hide();
}
// tab bar
tabBar.tabTo = function (tabString) {
var active;
if (myself.currentTab === tabString) {return; }
myself.world().hand.destroyTemporaries();
myself.currentTab = tabString;
this.children.forEach(each => {
each.refresh();
if (each.state) {active = each; }
});
active.refresh(); // needed when programmatically tabbing
myself.createSpriteEditor();
myself.fixLayout('tabEditor');
};
tab = new TabMorph(
tabColors,
null, // target
() => tabBar.tabTo('scripts'),
[ // label
new SymbolMorph('blocks', 10),
localize('Scripts')
],
() => this.currentTab === 'scripts' // query
);
tab.padding = 3;
tab.corner = tabCorner;
tab.edge = 1;
tab.labelShadowOffset = new Point(-1, -1);
tab.labelShadowColor = tabColors[1];
tab.labelColor = this.buttonLabelColor;
tab.getPressRenderColor = function () {
if (MorphicPreferences.isFlat ||
SyntaxElementMorph.prototype.alpha > 0.85) {
return this.pressColor;
}
return this.pressColor.mixed(
Math.max(SyntaxElementMorph.prototype.alpha - 0.15, 0),
SpriteMorph.prototype.paletteColor
);
};
tab.fixLayout();
tabBar.add(tab);
tab = new TabMorph(
tabColors,
null, // target
() => tabBar.tabTo('costumes'),
[ // label
new SymbolMorph('brush', 10),
localize(this.currentSprite instanceof SpriteMorph ? 'Costumes'
: 'Backgrounds')
],
() => this.currentTab === 'costumes' // query
);
tab.padding = 3;
tab.corner = tabCorner;
tab.edge = 1;
tab.labelShadowOffset = new Point(-1, -1);
tab.labelShadowColor = tabColors[1];
tab.labelColor = this.buttonLabelColor;
tab.fixLayout();
tabBar.add(tab);
tab = new TabMorph(
tabColors,
null, // target
() => tabBar.tabTo('sounds'),
[ // label
new SymbolMorph('speaker', 10),
localize('Sounds')
],
() => this.currentTab === 'sounds' // query
);
tab.padding = 3;
tab.corner = tabCorner;
tab.edge = 1;
tab.labelShadowOffset = new Point(-1, -1);
tab.labelShadowColor = tabColors[1];
tab.labelColor = this.buttonLabelColor;
tab.fixLayout();
tabBar.add(tab);
tabBar.fixLayout();
tabBar.children.forEach(each =>
each.refresh()
);
this.spriteBar.tabBar = tabBar;
this.spriteBar.add(this.spriteBar.tabBar);
this.spriteBar.fixLayout = function () {
this.tabBar.setLeft(this.left());
this.tabBar.setBottom(this.bottom() + myself.padding);
};
};
So glad the sprite bar is already prepared for AlignmentMorphs. 