kopia lustrzana https://github.com/backface/turtlestitch
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 projectorspull/3/merge
rodzic
0b510366d2
commit
78ab4de381
86
blocks.js
86
blocks.js
|
@ -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
18
byob.js
|
@ -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
56
gui.js
|
@ -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 () {
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
);
|
||||
|
|
Ładowanie…
Reference in New Issue