kopia lustrzana https://github.com/backface/turtlestitch
Paint editor fixes
rodzic
f5e101dc57
commit
3f92313ae4
443
paint.js
443
paint.js
|
@ -1,46 +1,75 @@
|
|||
/*
|
||||
paint.js
|
||||
Paint editor for Snap!
|
||||
Inspired by the Scratch paint editor.
|
||||
|
||||
written by Kartik Chandra
|
||||
|
||||
Latest revision: May 10 (Kartik)
|
||||
|
||||
This file is part of Snap!.
|
||||
|
||||
--current changes
|
||||
Shrinkwrap
|
||||
Draw crosshairs immediately
|
||||
TRANSPARENT PAINT
|
||||
Line width viewer
|
||||
|
||||
--To-Do list (in rough order of priority):
|
||||
Eraser tool
|
||||
paint.js
|
||||
|
||||
After release:
|
||||
--
|
||||
rgba sliders
|
||||
Import image
|
||||
Zoom/pan/Selection tools
|
||||
Pick color from canvas
|
||||
a paint editor for Snap!
|
||||
inspired by the Scratch paint editor.
|
||||
|
||||
written by Kartik Chandra
|
||||
Copyright (C) 2013 by Kartik Chandra
|
||||
|
||||
This file is part of Snap!.
|
||||
|
||||
Snap! is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as
|
||||
published by the Free Software Foundation, either version 3 of
|
||||
the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
toc
|
||||
---
|
||||
the following list shows the order in which all constructors are
|
||||
defined. Use this list to locate code in this document:
|
||||
|
||||
PaintEditorMorph
|
||||
PaintColorPickerMorph
|
||||
PaintCanvasMorph
|
||||
|
||||
|
||||
credits
|
||||
-------
|
||||
Nathan Dinsmore contributed a fully working prototype,
|
||||
Nathan's brilliant flood-fill tool has been more or less
|
||||
directly imported into this paint implementation.
|
||||
|
||||
Jens Mönig has contributed icons and bugfixes and says he has probably
|
||||
introduced many other bugs in that process. :-)
|
||||
|
||||
|
||||
revision history
|
||||
----------------
|
||||
May 10 - first full release (Kartik)
|
||||
May 14 - bugfixes (bugfixes, Snap integration (Jens)
|
||||
|
||||
*/
|
||||
|
||||
/*global Point, Rectangle, DialogBoxMorph, fontHeight, AlignmentMorph,
|
||||
FrameMorph, PushButtonMorph, Color, SymbolMorph, newCanvas, Morph, TextMorph,
|
||||
CostumeIconMorph, IDE_Morph, Costume, SpriteMorph, nop, Image, WardrobeMorph,
|
||||
TurtleIconMorph, localize, MenuMorph, InputFieldMorph, SliderMorph,
|
||||
ToggleMorph, ToggleButtonMorph, BoxMorph
|
||||
ToggleMorph, ToggleButtonMorph, BoxMorph, modules, radians, SVG_Costume
|
||||
*/
|
||||
|
||||
// Global definitions
|
||||
// Global stuff ////////////////////////////////////////////////////////
|
||||
|
||||
modules.paint = '2013-May-14';
|
||||
|
||||
// Declarations
|
||||
|
||||
var PaintEditorMorph;
|
||||
var PaintCanvasMorph;
|
||||
var PaintColorPickerMorph;
|
||||
|
||||
// PaintEditorMorph //////////////////////////
|
||||
|
||||
// A complete paint editor
|
||||
//////////////////////////////////////////////
|
||||
|
||||
PaintEditorMorph.prototype = new DialogBoxMorph();
|
||||
PaintEditorMorph.prototype.constructor = PaintEditorMorph;
|
||||
|
@ -54,7 +83,8 @@ function PaintEditorMorph() {
|
|||
|
||||
PaintEditorMorph.prototype.init = function() {
|
||||
// additional properties:
|
||||
this.paper = null; // paint canvas
|
||||
this.paper = null; // paint canvas
|
||||
this.oncancel = null;
|
||||
|
||||
// initialize inherited properties:
|
||||
PaintEditorMorph.uber.init.call(this);
|
||||
|
@ -70,7 +100,8 @@ PaintEditorMorph.prototype.init = function() {
|
|||
PaintEditorMorph.prototype.buildContents = function () {
|
||||
var myself = this;
|
||||
|
||||
this.paper = new PaintCanvasMorph(function() {return myself.shift; });
|
||||
this.paper = new PaintCanvasMorph(function() {return myself.shift; });
|
||||
this.paper.setExtent(new Point(480, 360));
|
||||
|
||||
this.addBody(new AlignmentMorph('row', this.padding));
|
||||
this.controls = new AlignmentMorph('column', this.padding);
|
||||
|
@ -113,22 +144,22 @@ PaintEditorMorph.prototype.buildContents = function () {
|
|||
PaintEditorMorph.prototype.buildToolbox = function() {
|
||||
var tools = {
|
||||
brush:
|
||||
"Paintbrush tool (free draw)",
|
||||
"Paintbrush tool\n(free draw)",
|
||||
rectangle:
|
||||
"Stroked Rectangle (shift: square)",
|
||||
"Stroked Rectangle\n(shift: square)",
|
||||
circle:
|
||||
"Stroked Ellipse (shift: circle)",
|
||||
"Stroked Ellipse\n(shift: circle)",
|
||||
eraser:
|
||||
"Eraser tool",
|
||||
crosshairs:
|
||||
"Set the rotation center",
|
||||
|
||||
line:
|
||||
"Line tool (shift: vertical/horizontal)",
|
||||
"Line tool\n(shift: vertical/horizontal)",
|
||||
rectangleSolid:
|
||||
"Filled Rectangle (shift: square)",
|
||||
"Filled Rectangle\n(shift: square)",
|
||||
circleSolid:
|
||||
"Filled Ellipse (shift: circle)",
|
||||
"Filled Ellipse\n(shift: circle)",
|
||||
paintbucket:
|
||||
"Fill a region"
|
||||
},
|
||||
|
@ -165,21 +196,18 @@ PaintEditorMorph.prototype.buildEdits = function() {
|
|||
|
||||
this.edits.add(this.pushButton(
|
||||
"undo",
|
||||
function () {paper.undo(); },
|
||||
"Undo last action"
|
||||
function () {paper.undo(); }
|
||||
));
|
||||
|
||||
this.edits.add(this.pushButton(
|
||||
"clear",
|
||||
function () {paper.clearCanvas(); },
|
||||
"Clear the paper"
|
||||
function () {paper.clearCanvas(); }
|
||||
));
|
||||
this.edits.fixLayout();
|
||||
};
|
||||
|
||||
|
||||
// Open the editor in a world with an optional image to edit
|
||||
PaintEditorMorph.prototype.openIn = function(world, oldim, oldrc, callback) {
|
||||
// Open the editor in a world with an optional image to edit
|
||||
this.setCenter(world.center());
|
||||
this.oldim = oldim;
|
||||
this.oldrc = oldrc.copy();
|
||||
|
@ -194,29 +222,40 @@ PaintEditorMorph.prototype.openIn = function(world, oldim, oldrc, callback) {
|
|||
this.shift = this.world().currentKey === 16;
|
||||
this.propertiesControls.constrain.refresh();
|
||||
};
|
||||
this.fixLayout(); // merge oldim - factor out into separate function
|
||||
this.changed();
|
||||
|
||||
//merge oldim:
|
||||
if (this.oldim) {
|
||||
this.paper.centermerge(this.oldim, this.paper.paper);
|
||||
this.paper.rotationCenter =
|
||||
this.oldrc.add(
|
||||
new Point(
|
||||
(this.paper.paper.width - this.oldim.width) / 2,
|
||||
(this.paper.paper.height - this.oldim.height) / 2
|
||||
)
|
||||
);
|
||||
this.paper.drawNew();
|
||||
}
|
||||
|
||||
this.fullChanged();
|
||||
};
|
||||
|
||||
PaintEditorMorph.prototype.fixLayout = function() {
|
||||
if (this.paper) {
|
||||
this.paper.setExtent(new Point(480, 360));
|
||||
this.paper.fixLayout();
|
||||
if (this.oldim) {
|
||||
this.paper.centermerge(this.oldim, this.paper.paper);
|
||||
this.paper.rotationCenter =
|
||||
this.oldrc.add(
|
||||
new Point(
|
||||
(this.paper.paper.width - this.oldim.width) / 2,
|
||||
(this.paper.paper.height - this.oldim.height) / 2
|
||||
)
|
||||
);
|
||||
}
|
||||
PaintEditorMorph.prototype.fixLayout = function() {
|
||||
var oldFlag = Morph.prototype.trackChanges;
|
||||
|
||||
this.changed();
|
||||
oldFlag = Morph.prototype.trackChanges;
|
||||
Morph.prototype.trackChanges = false;
|
||||
|
||||
if (this.paper) {
|
||||
this.paper.buildContents();
|
||||
this.paper.drawNew();
|
||||
}
|
||||
if (this.controls) {this.controls.fixLayout(); }
|
||||
if (this.body) {this.body.fixLayout(); }
|
||||
PaintEditorMorph.uber.fixLayout.call(this);
|
||||
|
||||
Morph.prototype.trackChanges = oldFlag;
|
||||
this.changed();
|
||||
};
|
||||
|
||||
PaintEditorMorph.prototype.refreshToolButtons = function() {
|
||||
|
@ -232,6 +271,11 @@ PaintEditorMorph.prototype.ok = function() {
|
|||
);
|
||||
this.destroy();
|
||||
};
|
||||
|
||||
PaintEditorMorph.prototype.cancel = function () {
|
||||
if (this.oncancel) {this.oncancel(); }
|
||||
this.destroy();
|
||||
};
|
||||
|
||||
PaintEditorMorph.prototype.populatePropertiesMenu = function() {
|
||||
var c = this.controls,
|
||||
|
@ -317,7 +361,7 @@ PaintEditorMorph.prototype.populatePropertiesMenu = function() {
|
|||
c.add(pc.colorpicker);
|
||||
//c.add(pc.primaryColorButton);
|
||||
c.add(pc.primaryColorViewer);
|
||||
c.add(new TextMorph("Pen size"));
|
||||
c.add(new TextMorph("Brush size"));
|
||||
c.add(alpen);
|
||||
c.add(pc.constrain);
|
||||
};
|
||||
|
@ -354,8 +398,8 @@ PaintEditorMorph.prototype.pushButton = function(title, action, hint) {
|
|||
};
|
||||
|
||||
// AdvancedColorPickerMorph //////////////////
|
||||
|
||||
// A large hsl color picker
|
||||
//////////////////////////////////////////////
|
||||
|
||||
PaintColorPickerMorph.prototype = new Morph();
|
||||
PaintColorPickerMorph.prototype.constructor = PaintColorPickerMorph;
|
||||
|
@ -425,11 +469,13 @@ PaintColorPickerMorph.prototype.mouseDownLeft = function(pos) {
|
|||
};
|
||||
|
||||
PaintColorPickerMorph.prototype.mouseMove =
|
||||
PaintColorPickerMorph.prototype.mouseDownLeft;
|
||||
// PaintCanvasMorph ///////////////////////////
|
||||
// A canvas which reacts to drag events to
|
||||
// modify its image, based on a 'tool' property.
|
||||
///////////////////////////////////////////////
|
||||
PaintColorPickerMorph.prototype.mouseDownLeft;
|
||||
|
||||
// PaintCanvasMorph ///////////////////////////
|
||||
/*
|
||||
A canvas which reacts to drag events to
|
||||
modify its image, based on a 'tool' property.
|
||||
*/
|
||||
|
||||
PaintCanvasMorph.prototype = new Morph();
|
||||
PaintCanvasMorph.prototype.constructor = PaintCanvasMorph;
|
||||
|
@ -440,14 +486,13 @@ function PaintCanvasMorph(shift) {
|
|||
}
|
||||
|
||||
PaintCanvasMorph.prototype.init = function(shift) {
|
||||
this.fixLayout();
|
||||
this.rotationCenter = new Point(240, 180);
|
||||
this.dragRect = null;
|
||||
this.previousDragPoint = null;
|
||||
this.currentTool = "brush";
|
||||
this.dragRect = new Rectangle();
|
||||
// rectangle with origin being the starting drag position and
|
||||
// corner being the current drag position
|
||||
// corner being the current drag position
|
||||
this.mask = newCanvas(this.extent()); // Temporary canvas
|
||||
this.paper = newCanvas(this.extent()); // Actual canvas
|
||||
this.erasermask = newCanvas(this.extent()); // eraser memory
|
||||
|
@ -462,7 +507,8 @@ PaintCanvasMorph.prototype.init = function(shift) {
|
|||
this.isShiftPressed = shift || function() {
|
||||
var key = this.world().currentKey;
|
||||
return (key === 16);
|
||||
};
|
||||
};
|
||||
this.buildContents();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.cacheUndo = function() {
|
||||
|
@ -483,7 +529,8 @@ PaintCanvasMorph.prototype.undo = function() {
|
|||
|
||||
PaintCanvasMorph.prototype.merge = function(a, b) {
|
||||
b.getContext("2d").drawImage(a, 0, 0);
|
||||
};
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.centermerge = function(a, b) {
|
||||
b.getContext("2d").drawImage(
|
||||
a,
|
||||
|
@ -507,33 +554,60 @@ PaintCanvasMorph.prototype.toolChanged = function(tool) {
|
|||
this.changed();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.drawcrosshair = function() {
|
||||
var mctx = this.mask.getContext("2d"),
|
||||
pos = this.rotationCenter;
|
||||
|
||||
mctx.strokeStyle = "rgba(0,0,0,0.6)";
|
||||
mctx.lineWidth = 5;
|
||||
mctx.beginPath();
|
||||
mctx.moveTo(pos.x, 0);
|
||||
mctx.lineTo(pos.x, this.extent().y);
|
||||
mctx.moveTo(0, pos.y);
|
||||
mctx.lineTo(this.extent().x, pos.y);
|
||||
mctx.stroke();
|
||||
|
||||
mctx.strokeStyle = "rgba(255,255,255,0.6)";
|
||||
mctx.lineWidth = 1;
|
||||
mctx.beginPath();
|
||||
mctx.moveTo(pos.x, 0);
|
||||
mctx.lineTo(pos.x, this.extent().y);
|
||||
mctx.moveTo(0, pos.y);
|
||||
mctx.lineTo(this.extent().x, pos.y);
|
||||
mctx.stroke();
|
||||
PaintCanvasMorph.prototype.drawcrosshair = function(context) {
|
||||
var ctx = context || this.mask.getContext("2d"),
|
||||
rp = this.rotationCenter;
|
||||
|
||||
ctx.lineWidth = 1;
|
||||
ctx.strokeStyle = 'black';
|
||||
ctx.clearRect(0, 0, this.mask.width, this.mask.height);
|
||||
|
||||
// draw crosshairs:
|
||||
ctx.globalAlpha = 0.5;
|
||||
|
||||
// circle around center:
|
||||
ctx.fillStyle = 'white';
|
||||
ctx.beginPath();
|
||||
ctx.arc(
|
||||
rp.x,
|
||||
rp.y,
|
||||
20,
|
||||
radians(0),
|
||||
radians(360),
|
||||
false
|
||||
);
|
||||
ctx.closePath();
|
||||
ctx.fill();
|
||||
ctx.stroke();
|
||||
|
||||
ctx.beginPath();
|
||||
ctx.arc(
|
||||
rp.x,
|
||||
rp.y,
|
||||
10,
|
||||
radians(0),
|
||||
radians(360),
|
||||
false
|
||||
);
|
||||
ctx.stroke();
|
||||
|
||||
// horizontal line:
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(0, rp.y);
|
||||
ctx.lineTo(this.mask.width, rp.y);
|
||||
ctx.stroke();
|
||||
|
||||
// vertical line:
|
||||
ctx.beginPath();
|
||||
ctx.moveTo(rp.x, 0);
|
||||
ctx.lineTo(rp.x, this.mask.height);
|
||||
ctx.stroke();
|
||||
|
||||
this.drawNew();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.floodfill = function(sourcepoint) {
|
||||
PaintCanvasMorph.prototype.floodfill = function(sourcepoint) {
|
||||
var width = this.paper.width,
|
||||
height = this.paper.height,
|
||||
ctx = this.paper.getContext("2d"),
|
||||
|
@ -555,7 +629,7 @@ PaintCanvasMorph.prototype.floodfill = function(sourcepoint) {
|
|||
p[2] === sourcecolor[2] &&
|
||||
p[3] === sourcecolor[3];
|
||||
};
|
||||
while (stack.length > 0) {
|
||||
while (stack.length > 0) {
|
||||
currentpoint = stack.pop();
|
||||
if (checkpoint(read(currentpoint))) {
|
||||
if (currentpoint % 480 > 1) {
|
||||
|
@ -576,7 +650,9 @@ PaintCanvasMorph.prototype.floodfill = function(sourcepoint) {
|
|||
data[currentpoint * 4 + 3] = this.settings.primarycolor.a;
|
||||
}
|
||||
}
|
||||
ctx.putImageData(img, 0, 0);
|
||||
ctx.putImageData(img, 0, 0);
|
||||
this.drawNew();
|
||||
this.changed();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.mouseDownLeft = function(pos) {
|
||||
|
@ -584,8 +660,13 @@ PaintCanvasMorph.prototype.mouseDownLeft = function(pos) {
|
|||
this.dragRect.origin = pos.subtract(this.bounds.origin);
|
||||
this.dragRect.corner = pos.subtract(this.bounds.origin);
|
||||
this.previousDragPoint = this.dragRect.corner.copy();
|
||||
if (this.currentTool === 'crosshairs') {
|
||||
this.rotationCenter = pos.subtract(this.bounds.origin);
|
||||
this.drawcrosshair();
|
||||
return;
|
||||
}
|
||||
if (this.currentTool === "paintbucket") {
|
||||
this.floodfill(pos.subtract(this.bounds.origin));
|
||||
return this.floodfill(pos.subtract(this.bounds.origin));
|
||||
}
|
||||
if (this.settings.primarycolor === "transparent" &&
|
||||
this.currentTool !== "crosshairs") {
|
||||
|
@ -594,7 +675,11 @@ PaintCanvasMorph.prototype.mouseDownLeft = function(pos) {
|
|||
}
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.mouseMove = function(pos) {
|
||||
PaintCanvasMorph.prototype.mouseMove = function(pos) {
|
||||
if (this.currentTool === "paintbucket") {
|
||||
return;
|
||||
}
|
||||
|
||||
var relpos = pos.subtract(this.bounds.origin),
|
||||
mctx = this.mask.getContext("2d"),
|
||||
pctx = this.paper.getContext("2d"),
|
||||
|
@ -707,27 +792,9 @@ PaintCanvasMorph.prototype.mouseMove = function(pos) {
|
|||
}
|
||||
}
|
||||
break;
|
||||
case "crosshairs":
|
||||
mctx.save();
|
||||
mctx.globalCompositeOperation = "source-over";
|
||||
mctx.strokeStyle = "rgba(0,0,0,0.6)";
|
||||
mctx.lineWidth = 5;
|
||||
mctx.beginPath();
|
||||
mctx.moveTo(p, 0);
|
||||
mctx.lineTo(p, this.extent().y);
|
||||
mctx.moveTo(0, q);
|
||||
mctx.lineTo(this.extent().x, q);
|
||||
mctx.stroke();
|
||||
mctx.strokeStyle = "rgba(255,255,255,0.6)";
|
||||
mctx.lineWidth = 1;
|
||||
mctx.beginPath();
|
||||
mctx.moveTo(p, 0);
|
||||
mctx.lineTo(p, this.extent().y);
|
||||
mctx.moveTo(0, q);
|
||||
mctx.lineTo(this.extent().x, q);
|
||||
mctx.stroke();
|
||||
this.rotationCenter = relpos.copy();
|
||||
mctx.restore();
|
||||
case "crosshairs":
|
||||
this.rotationCenter = relpos.copy();
|
||||
this.drawcrosshair(mctx);
|
||||
break;
|
||||
case "eraser":
|
||||
this.merge(this.paper, this.mask);
|
||||
|
@ -752,30 +819,30 @@ PaintCanvasMorph.prototype.mouseMove = function(pos) {
|
|||
mctx.restore();
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.mouseClickLeft = function() {
|
||||
PaintCanvasMorph.prototype.mouseClickLeft = function() {
|
||||
if (this.currentTool !== "crosshairs") {
|
||||
this.merge(this.mask, this.paper);
|
||||
}
|
||||
this.brushBuffer = [];
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.fixLayout = function() {
|
||||
this.background = newCanvas(this.extent());
|
||||
this.paper = newCanvas(this.extent());
|
||||
this.mask = newCanvas(this.extent());
|
||||
this.erasermask = newCanvas(this.extent());
|
||||
var i, j, bkctx = this.background.getContext("2d");
|
||||
for (i = 0; i < this.background.width; i += 5) {
|
||||
for (j = 0; j < this.background.height; j += 5) {
|
||||
if ((i + j) / 5 % 2 === 1) {
|
||||
bkctx.fillStyle = "rgba(255, 255, 255, 1)";
|
||||
} else {
|
||||
bkctx.fillStyle = "rgba(255, 255, 255, 0.3)";
|
||||
}
|
||||
bkctx.fillRect(i, j, 5, 5);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.buildContents = function() {
|
||||
this.background = newCanvas(this.extent());
|
||||
this.paper = newCanvas(this.extent());
|
||||
this.mask = newCanvas(this.extent());
|
||||
this.erasermask = newCanvas(this.extent());
|
||||
var i, j, bkctx = this.background.getContext("2d");
|
||||
for (i = 0; i < this.background.width; i += 5) {
|
||||
for (j = 0; j < this.background.height; j += 5) {
|
||||
if ((i + j) / 5 % 2 === 1) {
|
||||
bkctx.fillStyle = "rgba(255, 255, 255, 1)";
|
||||
} else {
|
||||
bkctx.fillStyle = "rgba(255, 255, 255, 0.3)";
|
||||
}
|
||||
bkctx.fillRect(i, j, 5, 5);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
PaintCanvasMorph.prototype.drawNew = function() {
|
||||
var can = newCanvas(this.extent());
|
||||
|
@ -825,9 +892,16 @@ PaintCanvasMorph.prototype.contrast
|
|||
// These will be incorporated into the respective files later
|
||||
// They add costume editing functionality to Snap!.
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
CostumeIconMorph.prototype.editCostume = function () {
|
||||
var ide = this.parentThatIsA(IDE_Morph);
|
||||
this.object.edit(this.world(), ide);
|
||||
|
||||
CostumeIconMorph.prototype.editCostume = function () {
|
||||
if (this.object instanceof SVG_Costume) {
|
||||
this.object.editRotationPointOnly(this.world());
|
||||
} else {
|
||||
this.object.edit(
|
||||
this.world(),
|
||||
this.parentThatIsA(IDE_Morph)
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
Costume.prototype.edit = function (aWorld, anIDE, isnew, oncancel, onsubmit) {
|
||||
|
@ -857,9 +931,6 @@ Costume.prototype.edit = function (aWorld, anIDE, isnew, oncancel, onsubmit) {
|
|||
);
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
IDE_Morph.prototype.createCorralBar = function () {
|
||||
// assumes the stage has already been created
|
||||
var padding = 5,
|
||||
|
@ -869,14 +940,17 @@ IDE_Morph.prototype.createCorralBar = function () {
|
|||
this.groupColor,
|
||||
this.frameColor.darker(50),
|
||||
this.frameColor.darker(50)
|
||||
];
|
||||
];
|
||||
|
||||
if (this.corralBar) {
|
||||
this.corralBar.destroy();
|
||||
}
|
||||
|
||||
this.corralBar = new Morph();
|
||||
this.corralBar.color = this.frameColor;
|
||||
this.corralBar.setHeight(this.logo.height()); // height is fixed
|
||||
this.add(this.corralBar);
|
||||
|
||||
// new sprite button
|
||||
newbutton = new PushButtonMorph(
|
||||
this,
|
||||
|
@ -899,6 +973,7 @@ IDE_Morph.prototype.createCorralBar = function () {
|
|||
newbutton.setCenter(this.corralBar.center());
|
||||
newbutton.setLeft(this.corralBar.left() + padding);
|
||||
this.corralBar.add(newbutton);
|
||||
|
||||
paintbutton = new PushButtonMorph(
|
||||
this,
|
||||
"paintNewSprite",
|
||||
|
@ -922,21 +997,31 @@ IDE_Morph.prototype.createCorralBar = function () {
|
|||
this.corralBar.left() + padding + newbutton.width() + padding
|
||||
);
|
||||
this.corralBar.add(paintbutton);
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.paintNewSprite = function() {
|
||||
var sprite = new SpriteMorph(this.globalVariables),
|
||||
cos = new Costume();
|
||||
sprite.name = sprite.name +
|
||||
(this.corral.frame.contents.children.length + 1);
|
||||
sprite.setCenter(this.stage.center());
|
||||
this.stage.add(sprite);
|
||||
this.sprites.add(sprite);
|
||||
this.corral.addSprite(sprite);
|
||||
this.selectSprite(sprite);
|
||||
cos.edit(this.world(), this, true, function() {sprite.remove(); });
|
||||
sprite.addCostume(cos);
|
||||
};
|
||||
};
|
||||
|
||||
IDE_Morph.prototype.paintNewSprite = function() {
|
||||
var sprite = new SpriteMorph(this.globalVariables),
|
||||
cos = new Costume(),
|
||||
myself = this;
|
||||
|
||||
sprite.name = sprite.name +
|
||||
(this.corral.frame.contents.children.length + 1);
|
||||
sprite.setCenter(this.stage.center());
|
||||
this.stage.add(sprite);
|
||||
this.sprites.add(sprite);
|
||||
this.corral.addSprite(sprite);
|
||||
this.selectSprite(sprite);
|
||||
cos.edit(
|
||||
this.world(),
|
||||
this,
|
||||
true,
|
||||
function() {myself.removeSprite(sprite); },
|
||||
function () {
|
||||
sprite.addCostume(cos);
|
||||
sprite.wearCostume(cos);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
WardrobeMorph.prototype.updateList = function () {
|
||||
var myself = this,
|
||||
|
@ -948,15 +1033,12 @@ WardrobeMorph.prototype.updateList = function () {
|
|||
icon,
|
||||
template,
|
||||
txt,
|
||||
paintbutton,
|
||||
colors = [
|
||||
new Color(50, 50, 50, 1),
|
||||
new Color(60, 60, 60, 1),
|
||||
new Color(70, 70, 70, 1)
|
||||
];
|
||||
paintbutton;
|
||||
|
||||
this.changed();
|
||||
oldFlag = Morph.prototype.trackChanges;
|
||||
Morph.prototype.trackChanges = false;
|
||||
|
||||
this.contents.destroy();
|
||||
this.contents = new FrameMorph(this);
|
||||
this.contents.acceptsDrops = false;
|
||||
|
@ -964,6 +1046,7 @@ WardrobeMorph.prototype.updateList = function () {
|
|||
myself.reactToDropOf(icon);
|
||||
};
|
||||
this.addBack(this.contents);
|
||||
|
||||
icon = new TurtleIconMorph(this.sprite);
|
||||
icon.setPosition(new Point(x, y));
|
||||
myself.addContents(icon);
|
||||
|
@ -974,31 +1057,37 @@ WardrobeMorph.prototype.updateList = function () {
|
|||
"paintNew",
|
||||
new SymbolMorph("brush", 15)
|
||||
);
|
||||
paintbutton.padding = 5;
|
||||
paintbutton.padding = 0;
|
||||
paintbutton.corner = 12;
|
||||
paintbutton.color = colors[0];
|
||||
paintbutton.highlightColor = colors[1];
|
||||
paintbutton.pressColor = colors[2];
|
||||
paintbutton.color = IDE_Morph.prototype.groupColor;
|
||||
paintbutton.highlightColor = IDE_Morph.prototype.frameColor.darker(50);
|
||||
paintbutton.pressColor = paintbutton.highlightColor;
|
||||
paintbutton.labelMinExtent = new Point(36, 18);
|
||||
paintbutton.labelShadowOffset = new Point(-1, -1);
|
||||
paintbutton.labelShadowColor = colors[1];
|
||||
paintbutton.labelShadowColor = paintbutton.highlightColor;
|
||||
paintbutton.labelColor = new Color(255, 255, 255);
|
||||
paintbutton.contrast = this.buttonContrast;
|
||||
paintbutton.drawNew();
|
||||
paintbutton.hint = "Paint a new costume";
|
||||
paintbutton.setPosition(new Point(x, y));
|
||||
paintbutton.fixLayout();
|
||||
|
||||
paintbutton.fixLayout();
|
||||
paintbutton.setCenter(icon.center());
|
||||
paintbutton.setLeft(icon.right() + padding * 4);
|
||||
|
||||
|
||||
this.addContents(paintbutton);
|
||||
y = paintbutton.bottom() + padding;
|
||||
|
||||
txt = new TextMorph(localize(
|
||||
"costumes tab help" // look up long string in translator
|
||||
));
|
||||
txt.fontSize = 9;
|
||||
txt.setColor(new Color(230, 230, 230));
|
||||
|
||||
txt.setPosition(new Point(x, y));
|
||||
this.addContents(txt);
|
||||
y = txt.bottom() + padding;
|
||||
y = txt.bottom() + padding;
|
||||
|
||||
|
||||
this.sprite.costumes.asArray().forEach(function (costume) {
|
||||
template = icon = new CostumeIconMorph(costume, template);
|
||||
icon.setPosition(new Point(x, y));
|
||||
|
@ -1006,10 +1095,12 @@ WardrobeMorph.prototype.updateList = function () {
|
|||
y = icon.bottom() + padding;
|
||||
});
|
||||
this.costumesVersion = this.sprite.costumes.lastChanged;
|
||||
|
||||
this.contents.setPosition(oldPos);
|
||||
this.adjustScrollBars();
|
||||
Morph.prototype.trackChanges = oldFlag;
|
||||
this.changed();
|
||||
|
||||
this.updateSelection();
|
||||
};
|
||||
|
||||
|
@ -1029,6 +1120,14 @@ CostumeIconMorph.prototype.userMenu = function () {
|
|||
var menu = new MenuMorph(this);
|
||||
if (!(this.object instanceof Costume)) {return null; }
|
||||
menu.addItem("edit", "editCostume");
|
||||
if (this.world().currentKey === 16) { // shift clicked
|
||||
menu.addItem(
|
||||
'edit rotation point only...',
|
||||
'editRotationPointOnly',
|
||||
null,
|
||||
new Color(100, 0, 0)
|
||||
);
|
||||
}
|
||||
menu.addItem("rename", "renameCostume");
|
||||
menu.addLine();
|
||||
menu.addItem("duplicate", "duplicateCostume");
|
||||
|
@ -1058,7 +1157,6 @@ CostumeIconMorph.prototype.duplicateCostume = function() {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// I had to change this because adding a "paint new" button changed the offset
|
||||
// of the costume (so the 5th child would be the 3rd costume, not the 4th as
|
||||
// it was before with only the text morph child).
|
||||
|
@ -1072,7 +1170,6 @@ CostumeIconMorph.prototype.removeCostume = function () {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
Costume.prototype.shrinkWrap = function () {
|
||||
// adjust my contents' bounds to my visible bounding box
|
||||
var bb = this.boundingBox(),
|
||||
|
|
Ładowanie…
Reference in New Issue