Scalable blocks and scripts

Shift-clicking on the settings menu lets you specify a fraction, by
which blocks and scripts are scaled, allowing you to e.g. export
poster-sized hi-res script pics, or to present Snap! live on hi-res
screens and projectors
pull/3/merge
jmoenig 2013-03-18 12:32:24 +01:00
rodzic 0b510366d2
commit 78ab4de381
5 zmienionych plików z 123 dodań i 51 usunięć

Wyświetl plik

@ -153,7 +153,7 @@ DialogBoxMorph, BlockInputFragmentMorph, PrototypeHatBlockMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.blocks = '2013-February-26';
modules.blocks = '2013-March-18';
var SyntaxElementMorph;
var BlockMorph;
@ -296,37 +296,46 @@ SyntaxElementMorph.uber = Morph.prototype;
rfColor - <Color> for reified outlines and slot backgrounds
*/
SyntaxElementMorph.prototype.corner = 3;
SyntaxElementMorph.prototype.rounding = 9;
SyntaxElementMorph.prototype.edge = 1.000001; // shadow bug in Chrome
SyntaxElementMorph.prototype.inset = 6;
SyntaxElementMorph.prototype.hatHeight = 12;
SyntaxElementMorph.prototype.hatWidth = 70;
SyntaxElementMorph.prototype.rfBorder = 3;
SyntaxElementMorph.prototype.minWidth = 0;
SyntaxElementMorph.prototype.dent = 8;
SyntaxElementMorph.prototype.bottomPadding = 3;
SyntaxElementMorph.prototype.cSlotPadding = 4;
SyntaxElementMorph.prototype.typeInPadding = 1;
SyntaxElementMorph.prototype.labelPadding = 4;
SyntaxElementMorph.prototype.labelFontName = 'Verdana';
SyntaxElementMorph.prototype.labelFontStyle = 'sans-serif';
SyntaxElementMorph.prototype.fontSize = 10;
SyntaxElementMorph.prototype.embossing = new Point(-1, -1);
SyntaxElementMorph.prototype.labelWidth = 450;
SyntaxElementMorph.prototype.labelWordWrap = true;
SyntaxElementMorph.prototype.dynamicInputLabels = true;
SyntaxElementMorph.prototype.feedbackColor = new Color(255, 255, 255);
SyntaxElementMorph.prototype.feedbackMinHeight = 5;
SyntaxElementMorph.prototype.minSnapDistance = 20;
SyntaxElementMorph.prototype.reporterDropFeedbackPadding = 10;
SyntaxElementMorph.prototype.contrast = 65;
SyntaxElementMorph.prototype.labelContrast = 25;
SyntaxElementMorph.prototype.activeHighlight = new Color(153, 255, 213);
SyntaxElementMorph.prototype.errorHighlight = new Color(173, 15, 0);
SyntaxElementMorph.prototype.activeBlur = 20;
SyntaxElementMorph.prototype.activeBorder = 4;
SyntaxElementMorph.prototype.rfColor = new Color(120, 120, 120);
SyntaxElementMorph.prototype.setScale = function (num) {
var scale = Math.max(num, 1);
SyntaxElementMorph.prototype.scale = scale;
SyntaxElementMorph.prototype.corner = 3 * scale;
SyntaxElementMorph.prototype.rounding = 9 * scale;
SyntaxElementMorph.prototype.edge = 1.000001 * scale;
SyntaxElementMorph.prototype.inset = 6 * scale;
SyntaxElementMorph.prototype.hatHeight = 12 * scale;
SyntaxElementMorph.prototype.hatWidth = 70 * scale;
SyntaxElementMorph.prototype.rfBorder = 3 * scale;
SyntaxElementMorph.prototype.minWidth = 0;
SyntaxElementMorph.prototype.dent = 8 * scale;
SyntaxElementMorph.prototype.bottomPadding = 3 * scale;
SyntaxElementMorph.prototype.cSlotPadding = 4 * scale;
SyntaxElementMorph.prototype.typeInPadding = scale;
SyntaxElementMorph.prototype.labelPadding = 4 * scale;
SyntaxElementMorph.prototype.labelFontName = 'Verdana';
SyntaxElementMorph.prototype.labelFontStyle = 'sans-serif';
SyntaxElementMorph.prototype.fontSize = 10 * scale;
SyntaxElementMorph.prototype.embossing = new Point(
-1 * Math.max(scale / 2, 1),
-1 * Math.max(scale / 2, 1)
);
SyntaxElementMorph.prototype.labelWidth = 450 * scale;
SyntaxElementMorph.prototype.labelWordWrap = true;
SyntaxElementMorph.prototype.dynamicInputLabels = true;
SyntaxElementMorph.prototype.feedbackColor = new Color(255, 255, 255);
SyntaxElementMorph.prototype.feedbackMinHeight = 5;
SyntaxElementMorph.prototype.minSnapDistance = 20;
SyntaxElementMorph.prototype.reporterDropFeedbackPadding = 10 * scale;
SyntaxElementMorph.prototype.contrast = 65;
SyntaxElementMorph.prototype.labelContrast = 25;
SyntaxElementMorph.prototype.activeHighlight = new Color(153, 255, 213);
SyntaxElementMorph.prototype.errorHighlight = new Color(173, 15, 0);
SyntaxElementMorph.prototype.activeBlur = 20;
SyntaxElementMorph.prototype.activeBorder = 4;
SyntaxElementMorph.prototype.rfColor = new Color(120, 120, 120);
};
SyntaxElementMorph.prototype.setScale(1);
// SyntaxElementMorph instance creation:
@ -2033,6 +2042,7 @@ BlockMorph.prototype.showHelp = function () {
BlockMorph.prototype.eraseHoles = function (context) {
var myself = this,
isReporter = this instanceof ReporterBlockMorph,
shift = this.edge * 0.5,
gradient,
rightX,
@ -2071,9 +2081,9 @@ BlockMorph.prototype.eraseHoles = function (context) {
var w = hole.width(),
h = Math.floor(hole.height()) - 2; // Opera needs this
context.clearRect(
Math.floor(hole.bounds.origin.x - myself.bounds.origin.x),
Math.floor(hole.bounds.origin.x - myself.bounds.origin.x) + 1,
Math.floor(hole.bounds.origin.y - myself.bounds.origin.y) + 1,
w,
isReporter ? w - 1 : w + 1,
h
);
});
@ -2760,9 +2770,9 @@ CommandBlockMorph.prototype.drawNew = function () {
CommandBlockMorph.prototype.drawBody = function (context) {
context.fillRect(
0,
this.corner,
Math.floor(this.corner),
this.width(),
this.height() - (this.corner * 3)
this.height() - Math.floor(this.corner * 3) + 1
);
};
@ -3173,9 +3183,9 @@ HatBlockMorph.prototype.drawTop = function (context) {
HatBlockMorph.prototype.drawBody = function (context) {
context.fillRect(
0,
this.hatHeight + this.corner,
this.hatHeight + Math.floor(this.corner) - 1,
this.width(),
this.height() - (this.corner * 3) - (this.hatHeight)
this.height() - Math.floor(this.corner * 3) - this.hatHeight + 2
);
};

18
byob.js
Wyświetl plik

@ -105,7 +105,7 @@ CommentMorph, localize, CSlotMorph*/
// Global stuff ////////////////////////////////////////////////////////
modules.byob = '2013-February-18';
modules.byob = '2013-March-18';
// Declarations
@ -2002,7 +2002,7 @@ BlockLabelPlaceHolderMorph.prototype.drawNew = function () {
context.beginPath();
context.arc(
cx,
cy,
cy * 1.2,
Math.min(cx, cy),
radians(0),
radians(360),
@ -2127,7 +2127,8 @@ InputSlotDialogMorph.prototype.init = function (
environment,
category
) {
var fh = fontHeight(10) / 1.2; // "raw height"
var scale = SyntaxElementMorph.prototype.scale,
fh = fontHeight(10) / 1.2 * scale; // "raw height"
// additional properties:
this.fragment = fragment || new BlockLabelFragment();
@ -2152,7 +2153,7 @@ InputSlotDialogMorph.prototype.init = function (
this.slots = new BoxMorph();
this.slots.color = new Color(55, 55, 55); // same as palette
this.slots.borderColor = this.slots.color.lighter(50);
this.slots.setExtent(new Point((fh + 10) * 24, (fh + 10) * 10.4));
this.slots.setExtent(new Point((fh + 10) * 24, (fh + 10 * scale) * 10.4));
this.add(this.slots);
this.createSlotTypeButtons();
this.fixSlotsLayout();
@ -2548,10 +2549,11 @@ InputSlotDialogMorph.prototype.addSlotArityButton = function (
InputSlotDialogMorph.prototype.fixSlotsLayout = function () {
var slots = this.slots,
xPadding = 10,
ypadding = 14,
bh = fontHeight(10) / 1.2 + 15, // slot type button height
ah = fontHeight(10) / 1.2 + 10, // arity button height
scale = SyntaxElementMorph.prototype.scale,
xPadding = 10 * scale,
ypadding = 14 * scale,
bh = (fontHeight(10) / 1.2 + 15) * scale, // slot type button height
ah = (fontHeight(10) / 1.2 + 10) * scale, // arity button height
size = 12, // number slot type radio buttons
cols = [
slots.left() + xPadding,

56
gui.js
Wyświetl plik

@ -68,7 +68,7 @@ sb*/
// Global stuff ////////////////////////////////////////////////////////
modules.gui = '2013-March-15';
modules.gui = '2013-March-18';
// Declarations
@ -1687,6 +1687,14 @@ IDE_Morph.prototype.settingsMenu = function () {
menu = new MenuMorph(this);
menu.addItem('Language...', 'languageMenu');
if (shiftClicked) {
menu.addItem(
'Scale blocks...',
'userSetBlocksScale',
null,
new Color(100, 0, 0)
);
}
menu.addLine();
addPreference(
'Blurred shadows',
@ -2760,6 +2768,52 @@ IDE_Morph.prototype.reflectLanguage = function (lang) {
this.openProjectString(projectData);
};
// IDE_Morph blocks scaling
IDE_Morph.prototype.userSetBlocksScale = function () {
var myself = this;
new DialogBoxMorph(
null,
function (num) {
myself.setBlocksScale(num);
}
).prompt(
'Scale Blocks',
SyntaxElementMorph.prototype.scale.toString(),
this.world(),
null,
{
'normal (1)' : 1,
'demo (1.2)' : 1.2,
'big (2)' : 2,
'huge (4)' : 4,
'giant (8)' : 8
},
false, // read only?
true // numeric
);
};
IDE_Morph.prototype.setBlocksScale = function (num) {
var projectData;
if (Process.prototype.isCatchingErrors) {
try {
projectData = this.serializer.serialize(this.stage);
} catch (err) {
this.showMessage('Serialization failed: ' + err);
}
} else {
projectData = this.serializer.serialize(this.stage);
}
SyntaxElementMorph.prototype.setScale(num);
SpriteMorph.prototype.initBlocks();
this.spriteBar.tabBar.tabTo('scripts');
this.createCategories();
this.createCorralBar();
this.fixLayout();
this.openProjectString(projectData);
};
// IDE_Morph cloud interface
IDE_Morph.prototype.initializeCloud = function () {

Wyświetl plik

@ -1522,4 +1522,9 @@ ______
130314
------
* GUI: When logged into the Cloud, "cloud" becomes default in the project dialog
* Store: local custom blocks can now store their definition receiver directly as value (avoiding turning them into "Obsolete!" blocks when re-opening the project), this is important for reified blocks assigned to variables elsewhere, and such for the part of OOP we can already do now.
* Store: local custom blocks can now store their definition receiver directly as value (avoiding turning them into "Obsolete!" blocks when re-opening the project), this is important for reified blocks assigned to variables elsewhere, and such for the part of OOP we can already do now.
130318
------
* GUI, Blocks, BYOB, Widgets: Scaling Blocks and Scripts (shift-click on settings menu)
* Widets: numerical prompts

Wyświetl plik

@ -73,7 +73,7 @@ newCanvas, StringMorph, Morph, TextMorph, nop, detect, StringFieldMorph,
HTMLCanvasElement, fontHeight, SymbolMorph, localize, SpeechBubbleMorph,
ArrowMorph, MenuMorph, isString*/
modules.widgets = '2013-February-26';
modules.widgets = '2013-March-18';
var PushButtonMorph;
var ToggleButtonMorph;
@ -1531,11 +1531,12 @@ DialogBoxMorph.prototype.prompt = function (
world,
pic,
choices, // optional dictionary for drop-down of choices
isReadOnly // optional when using choices
isReadOnly, // optional when using choices
isNumeric // optional
) {
var txt = new InputFieldMorph(
defaultString,
false, // numeric?
isNumeric || false, // numeric?
choices || null, // drop-down dict, optional
choices ? isReadOnly || false : false
);