diff --git a/index.html b/index.html index 939ad7cc..50f3d495 100644 --- a/index.html +++ b/index.html @@ -57,7 +57,6 @@ position:absolute;right:0;bottom:0;width:480px;height:360px; border:1px solid #c0c0c0"> -
diff --git a/stitchcode/gui.js b/stitchcode/gui.js index 93867048..0052daa6 100644 --- a/stitchcode/gui.js +++ b/stitchcode/gui.js @@ -68,6 +68,11 @@ IDE_Morph.prototype.buildPanes = function () { this.createPaletteHandle(); }; +IDE_Morph.prototype.origSetStageExtent = IDE_Morph.prototype.setStageExtent; +IDE_Morph.prototype.setStageExtent = function (aPoint) { + this.origSetStageExtent(aPoint); + turtleShepherd.setStageDimensions(aPoint.x, aPoint.y); +}; // Create contol bar - (and add custom buttons) IDE_Morph.prototype.createControlBar = function () { @@ -1310,9 +1315,9 @@ IDE_Morph.prototype.createCategories = function () { buttonHeight = myself.categories.children[0].height(), border = 3, rows = Math.ceil((myself.categories.children.length) / 2), - xPadding = (myself.categories.width() - - border - - buttonWidth * 2) / 3, + xPadding = (myself.categories.width() - + border - + buttonWidth * 2) / 3, yPadding = 2, l = myself.categories.left(), t = myself.categories.top(), @@ -1423,12 +1428,12 @@ IDE_Morph.prototype.projectMenu = function () { menu.addLine(); menu.addItem( 'Download as SVG', - function() { myself.downloadSVG() }, + function() { myself.downloadSVG(); }, 'download current drawing as SVG file' ); menu.addItem( 'Download as EXP', - function() { myself.downloadEXP() }, + function() { myself.downloadEXP(); }, 'download current drawing as EXP file' ); @@ -1483,27 +1488,6 @@ IDE_Morph.prototype.projectMenu = function () { ), 'Select categories of additional blocks to add to this project.' ); - - - graphicsName = 'Backgrounds'; - menu.addItem( - 'Backgrounds...', - createMediaMenu( - 'Backgrounds', - function loadLib(file, name) { - var url = myself.resourceURL('Backgrounds', file); - img = new Image(); - img.onload = function () { - var canvas = newCanvas(new Point(img.width, img.height)); - canvas.getContext('2d').drawImage(img, 0, 0); - myself.droppedImageStage(canvas, name); - }; - img.src = url; - } - ), - 'Select categories of additional blocks to add to this project.' - ); - menu.popup(world, pos); }; diff --git a/stitchcode/objects.js b/stitchcode/objects.js index 8dd82f68..39d71e3d 100644 --- a/stitchcode/objects.js +++ b/stitchcode/objects.js @@ -1,6 +1,13 @@ /* Sprite */ // modified SpriteMorph turtlestitch functions + +SpriteMorph.prototype.origInit = SpriteMorph.prototype.init; +SpriteMorph.prototype.init = function(globals) { + this.origInit(globals); + this.hide(); +}; + SpriteMorph.prototype.origForward = SpriteMorph.prototype.forward; SpriteMorph.prototype.forward = function (steps) { oldx = this.xPosition(); @@ -16,10 +23,10 @@ SpriteMorph.prototype.origGotoXY = SpriteMorph.prototype.gotoXY; SpriteMorph.prototype.gotoXY = function (x, y, justMe) { oldx = this.xPosition(); oldy = this.yPosition(); - console.log("jump in place - don't add."); this.origGotoXY(x, y, justMe); if ( Math.abs(this.xPosition()-oldx)<=1 && Math.abs(this.yPosition()-oldy)<=1 ) { - console.log("jump in place - don't add."); + // jump in place - don't add. + if (DEBUG) turtleShepherd.debug_msg("jump in place - don't add"); } else { if (!turtleShepherd.hasSteps()) turtleShepherd.initPosition(oldx, oldy); @@ -32,14 +39,18 @@ SpriteMorph.prototype.origClear = SpriteMorph.prototype.clear; SpriteMorph.prototype.clear = function () { this.origClear(); turtleShepherd.clear(); + //this.changed(); this.reRender(); }; SpriteMorph.prototype.reRender = function () { - this.parent.clearPenTrails(); + //this.changed(); turtleShepherd.reRender(this.parent.penTrails()); + this.hide(); + this.changed(); }; + /* Stage */ // modified StageMorph turtlestitch functions @@ -51,6 +62,140 @@ StageMorph.prototype.mouseScroll = function (y, x) { turtleShepherd.zoomIn(); } - this.clearPenTrails(); - reDraw(this.penTrails()); + this.reRender(); + this.changed(); }; + + +StageMorph.prototype.reRender = function () { + //this.changed(); + turtleShepherd.reRender(this.penTrails()); + //this.changed(); +}; + +StageMorph.prototype.originalSetScale = StageMorph.prototype.setScale; +StageMorph.prototype.setScale = function (number) { + this.scaleChanged = true; + this.originalSetScale(number); + if (DEBUG) turtleShepherd.debug_msg("scale stage to "+ number ); + if (DEBUG) turtleShepherd.debug_msg("stage dimensions " + + this.extent().x + " " + + this.extent().y); + if (DEBUG) turtleShepherd.debug_msg("stage position " + + this.position().x + " " + + this.position().y); + turtleShepherd.setStageDimensions(this.extent().x, this.extent().y); + turtleShepherd.setStagePosition(this.position().x, this.position().y); + //this.resizePenTrails(); + this.changed(); + this.reRender(); +}; + +StageMorph.prototype.resizePenTrails = function () { + this.trailsCanvas = newCanvas(new Point(this.extent().x,this.extent().y)); + this.changed(); +}; + +StageMorph.prototype.originalDrawOn = StageMorph.prototype.drawOn; + +/* +StageMorph.prototype.drawOn = function (aCanvas, aRect) { + if (DEBUG) turtleShepherd.debug_msg("draw on stage"); + //turtleShepherd.reRender(this.penTrails()); + + c = this.penTrails().getContext('2d'); + c.drawSvg(turtleShepherd.toSVG(), 0, 0, aCanvas.width, aCanvas.height); + return this.originalDrawOn(aCanvas, aRect); +};* + + +/* from beetleblocks */ +/* +// StageMorph drawing +StageMorph.prototype.originalDrawOn = StageMorph.prototype.drawOn; +StageMorph.prototype.drawOn = function (aCanvas, aRect) { + // If the scale is lower than 1, we reuse the original method, + // otherwise we need to modify the renderer dimensions + // we do not need to render the original canvas anymore because + // we have removed sprites and backgrounds + + var rectangle, area, delta, src, context, w, h, sl, st; + if (!this.isVisible) { + return null; + } + if (this.scale < 1) { + return this.originalDrawOn(aCanvas, aRect); + } + + rectangle = aRect || this.bounds; + area = rectangle.intersect(this.bounds).round(); + if (area.extent().gt(new Point(0, 0))) { + delta = this.position().neg(); + src = area.copy().translateBy(delta).round(); + context = aCanvas.getContext('2d'); + context.globalAlpha = this.alpha; + + sl = src.left(); + st = src.top(); + w = Math.min(src.width(), this.image.width - sl); + h = Math.min(src.height(), this.image.height - st); + + if (w < 1 || h < 1) { + return null; + } + + context.save(); + if (this.scaleChanged) { + w = this.width(); + h = this.height(); + this.scaleChanged = false; + this.reRender(); + } + + context.drawImage( + this.penTrails(), + src.left() / this.scale, + src.top() / this.scale, + w, + h, + area.left() / this.scale, + area.top() / this.scale, + w, + h + ); + context.restore(); + } +}; + +*/ + +/* + +StageMorph.prototype.originalSetScale = StageMorph.prototype.setScale; +StageMorph.prototype.setScale = function (number) { + this.scaleChanged = true; + this.originalSetScale(number); +}; + +// Contextual menu +StageMorph.prototype.userMenu = function () { + var ide = this.parentThatIsA(IDE_Morph), + menu = new MenuMorph(this), + shiftClicked = this.world().currentKey === 16, + myself = this; + + if (ide && ide.isAppMode) { + menu.hide(); + return menu; + } + menu.addItem( + 'pic...', + function () { + window.open(myself.fullImageClassic().toDataURL()); + }, + 'open a new window\nwith a picture of the scene' + ); + return menu; +}; + +*/ diff --git a/stitchcode/stitchcodeChangeSet.js b/stitchcode/stitchcodeChangeSet.js deleted file mode 100644 index 2a46443f..00000000 --- a/stitchcode/stitchcodeChangeSet.js +++ /dev/null @@ -1,402 +0,0 @@ -// Stitchode's main changes and addtions to snap! go in here -// sorry it lacks proper documentation - - -var tStitch = {}; - -tStitch.debug = true; -tStitch.draw_jumps = true; -tStitch.draw_stitches = true; -tStitch.draw_stitch_len = 2; - -tStitch.debug_msg = function (st,clear) { - o = new String(); - if (!clear) { - o = document.getElementById("bug").innerHTML; - } else { - o = ""; - } - o += st; - document.getElementById("bug").innerHTML = o; -} - -tStitch.getBaseURL = function () { - var url = location.href; // entire url including querystring - also: window.location.href; - if (url.lastIndexOf('#') > 0) { - url = url.substring(0, url.lastIndexOf('#')); - } - url = url.substring(0, url.lastIndexOf('/')); - return url + "/"; -} - - -tStitch.stitches = {}; -tStitch.stitches.x = new Array(); -tStitch.stitches.y = new Array(); -tStitch.stitches.jump = new Array(); - -tStitch.isFirst = function() { - if (tStitch.stitches.x.length > 0) - return false; - else - return true; -} - -tStitch.clearPoints = function() { - tStitch.stitches.x = new Array(); - tStitch.stitches.y = new Array(); - tStitch.stitches.jump = new Array(); -} -tStitch.addPoint = function (x,y,jump) { - if (tStitch.debug) { - s = new String(); - s = s + "adding Point (" + x + "," + y; - if (jump) s = s + ",jump"; - s+= ")"; - console.log(s); - } - - if (tStitch.stitches.x[tStitch.stitches.x.length-1] == x && - tStitch.stitches.y[tStitch.stitches.y.length-1] == y - ) { - //alert("pint exist"); - } else { - tStitch.stitches.x.push(x); - tStitch.stitches.y.push(y); - tStitch.stitches.jump.push(jump); - } -} - -tStitch.toogleShowStitches = function() { - tStitch.draw_stitches = !tStitch.draw_stitches; -} - -tStitch.getShowStitches = function() { - return tStitch.draw_stitches; -} - -tStitch.toogleShowJumpStitches = function() { - tStitch.draw_jumps = !tStitch.draw_jumps; -} - -tStitch.getShowJumpStitches = function() { - return tStitch.draw_jumps; -} - -tStitch.signup = function() { - window.open('http://' + window.location.hostname + '/signup'); -} - - -tStitch.upload = function(name) { - - tStitch.debug_msg("uploading points... sending SAVE with num points= " + tStitch.stitches.x.length, true); - params = { "x[]": tStitch.stitches.x, "y[]":tStitch.stitches.y, "j[]":tStitch.stitches.jump, "name":name }; - - if (tStitch.stitches.x.length <= 1 || tStitch.stitches.y <= 1) { - new DialogBoxMorph().inform( - 'Upload Error', - 'No stitches to upload, please (re)generate a drawing first!', - world); - - } else { - $.post( - "/upload", - data = params, - successCallback = function (data) { - if (data!="ERROR") { - /*new DialogBoxMorph().inform( - 'Upload Success', - 'Your embroidery file is ready and will be available at this url:\n' + - window.location.hostname + '/view/'+data,'\n', - world);*/ - window.open('http://' + window.location.hostname + '/view/'+data, 'TurtleStitch file preview'); - } else { - new DialogBoxMorph().inform( - 'Upload Error', - 'Sorry! Upload failed for an unknown reason', - world); - } - }); - } - - /* - $.fileDownload(tStitch.getBaseURL() +"stitchcode/backend/save.py", { - successCallback: function (html, url) { - alert("DSD"); - }, - failCallback: function (html, url) { - alert( - 'Your file download just failed for this URL:' + url + - '\r\n' + 'Here was the resulting error HTML: \r\n' - + html - ); - }, - - httpMethod: "POST", - data: params - }); */ -} - - - - -/* Sprite */ -// modified SpriteMorph turtle functions - -// SpriteMorph motion primitives - - -SpriteMorph.prototype.forward = function (steps) { - var dest, - dist = steps * this.parent.scale || 0; - - oldpos = this.position(); - - if (dist >= 0) { - dest = this.position().distanceAngle(dist, this.heading); - } else { - dest = this.position().distanceAngle( - Math.abs(dist), - (this.heading - 180) - ); - } - - this.setPosition(dest); - this.positionTalkBubble(); - //this.drawLineX(dest); - - tx = dest.x - this.parent.topLeft().x - ty = dest.y - this.parent.topLeft().y - tjump = !this.isDown; - - if (tStitch.isFirst()) { - origx = oldpos.x - this.parent.topLeft().x; - origy = oldpos.y - this.parent.topLeft().y; - tStitch.addPoint(origx , origy ,true); - //alert("first"); - //alert("orig: " + origx + "," + origy+ " tx/ty: " + tx + ", "+ ty + " - "+ this.position()); - } - - tStitch.addPoint(tx,ty,tjump); - //alert("move to: " + tx + "x" + ty + " - isJump = " + tjump); - -}; - -SpriteMorph.prototype.gotoXY = function (x, y, justMe) { - var stage = this.parentThatIsA(StageMorph), - newX, - newY, - dest; - - newX = stage.center().x + (+x || 0) * stage.scale; - newY = stage.center().y - (+y || 0) * stage.scale; - - oldX = this.position().x / stage.scale - stage.center().x + this.extent().x/2; - oldY = -(this.position().y / stage.scale - stage.center().y + this.extent().y/2); - - if (this.costume) { - dest = new Point(newX, newY).subtract(this.rotationOffset); - } else { - dest = new Point(newX, newY).subtract(this.extent().divideBy(2)); - } - - this.setPosition(dest, justMe); - this.positionTalkBubble(); - - tx = dest.x - this.parent.topLeft().x - ty = dest.y - this.parent.topLeft().y - tjump = !this.isDown; - - if ( Math.abs(x-oldX)<=1.1 && Math.abs(y-oldY)<=1.1 ) { - if (tStitch.debug) - console.log("jump in place - don't add."); - } else { - if (tStitch.debug) - console.log("gotoXY "+ x + "," + y + " from: + " + oldX + "," + oldY); - tStitch.addPoint(tx,ty,tjump); - } -}; -// SpriteMorph drawing: - -SpriteMorph.prototype.drawLine = function (start, dest) { - var stagePos = this.parent.bounds.origin, - stageScale = this.parent.scale, - context = this.parent.penTrails().getContext('2d'), - from = start.subtract(stagePos).divideBy(stageScale), - to = dest.subtract(stagePos).divideBy(stageScale), - damagedFrom = from.multiplyBy(stageScale).add(stagePos), - damagedTo = to.multiplyBy(stageScale).add(stagePos), - damaged = damagedFrom.rectangle(damagedTo).expandBy( - Math.max(this.size * stageScale / 2, 1) - ).intersect(this.parent.visibleBounds()).spread(); - - - - if (this.isDown) { - context.lineWidth = this.size; - context.strokeStyle = this.color.toString(); - if (this.useFlatLineEnds) { - context.lineCap = 'butt'; - context.lineJoin = 'miter'; - } else { - context.lineCap = 'round'; - context.lineJoin = 'round'; - } - context.beginPath(); - context.moveTo(from.x, from.y); - context.lineTo(to.x, to.y); - context.stroke(); - if (this.isWarped === false) { - this.world().broken.push(damaged); - } - } -}; - -SpriteMorph.prototype.drawJumpLine = function (start, dest) { - var stagePos = this.parent.bounds.origin, - stageScale = this.parent.scale, - context = this.parent.penTrails().getContext('2d'), - from = start.subtract(stagePos).divideBy(stageScale), - to = dest.subtract(stagePos).divideBy(stageScale), - damagedFrom = from.multiplyBy(stageScale).add(stagePos), - damagedTo = to.multiplyBy(stageScale).add(stagePos), - damaged = damagedFrom.rectangle(damagedTo).expandBy( - Math.max(this.size * stageScale / 2, 1) - ).intersect(this.parent.visibleBounds()).spread(); - - context.lineWidth = this.size; - context.strokeStyle = new Color(255, 0, 0).toString(); - context.lineCap = 'round'; - context.lineJoin = 'round'; - context.beginPath(); - context.moveTo(from.x, from.y); - context.lineTo(to.x, to.y); - context.stroke(); - if (this.isWarped === false) { - this.world().broken.push(damaged); - } - -}; - -SpriteMorph.prototype.drawStitch = function (dest) { - //dest = dest.subtract(this.topLeft()); - var s = tStitch.draw_stitch_len; - var stagePos = this.parent.bounds.origin, - stageScale = this.parent.scale, - context = this.parent.penTrails().getContext('2d'), - to = dest.subtract(stagePos).divideBy(stageScale), - damagedFrom = new Point(to.x-s,to.y-s).multiplyBy(stageScale).add(stagePos), - damagedTo = new Point(to.x+s,to.y+s).multiplyBy(stageScale).add(stagePos), - damaged = damagedFrom.rectangle(damagedTo).expandBy( - Math.max(this.size * stageScale / 2, 1) - ).intersect(this.parent.visibleBounds()).spread(); - - context.lineWidth = this.size; - context.strokeStyle = new Color(0, 0, 255).toString(); - context.lineCap = 'round'; - context.lineJoin = 'round'; - - context.beginPath(); - context.moveTo(to.x - s, to.y - s ); - context.lineTo(to.x + s, to.y + s); - context.stroke(); - - context.beginPath(); - context.moveTo(to.x - s, to.y + s); - context.lineTo(to.x + s, to.y - s); - context.stroke(); - if (this.isWarped === false) { - this.world().broken.push(damaged); - } -}; - - - -SpriteMorph.prototype.clear = function () { - this.parent.clearPenTrails(); - tStitch.clearPoints(); - if (tStitch.debug) { - tStitch.debug_msg("",true); - } - -}; - - - - -// SpriteMorph motion - adjustments due to nesting - -SpriteMorph.prototype.moveBy = function (delta, justMe) { - // override the inherited default to make sure my parts follow - // unless it's justMe (a correction) - var start = this.isDown && !justMe && this.parent ? - this.rotationCenter() : null; - - // add stitch controls - if (this.parent) { - if (this.parent.penTrails()) { - origin = this.rotationCenter(); - } - } - - SpriteMorph.uber.moveBy.call(this, delta); - - // add stitch controls - if (this.parent) { - if (this.parent.penTrails() && origin.x > 100) { - //alert(origin.x); - if (tStitch.draw_stitches) { - this.drawStitch(this.rotationCenter()); - } - if (tStitch.draw_jumps && !this.isDown) { - this.drawJumpLine(origin,this.rotationCenter()); - } - } - } - - - if (start) { - this.drawLine(start, this.rotationCenter()); - } - if (!justMe) { - this.parts.forEach(function (part) { - part.moveBy(delta); - }); - } -}; - -/* -// Definition of new block categories -SpriteMorph.prototype.categories = - [ - 'motion', - 'control', - 'shapes', - 'colors', - 'sensing', - 'operators', - 'variables', - 'lists', - 'my blocks' - ]; - -SpriteMorph.prototype.blockColor = { - motion : new Color(74, 108, 212), - shapes : new Color(143, 86, 227), - colors : new Color(207, 74, 217), - sound : new Color(207, 74, 217), // we need to keep this color for the zoom blocks dialog - control : new Color(230, 168, 34), - sensing : new Color(4, 148, 220), - operators : new Color(98, 194, 19), - variables : new Color(243, 118, 29), - lists : new Color(217, 77, 17), - other : new Color(150, 150, 150), - 'my blocks': new Color(150, 150, 60), -}; - -// now move also "make a block to 'my blocks' - -*/ - - diff --git a/stitchcode/stitchcodeGUI.js b/stitchcode/stitchcodeGUI.js deleted file mode 100644 index bf836a61..00000000 --- a/stitchcode/stitchcodeGUI.js +++ /dev/null @@ -1,2337 +0,0 @@ -// Force flat design -IDE_Morph.prototype.setDefaultDesign = IDE_Morph.prototype.setFlatDesign; - - -IDE_Morph.prototype.originalInit = IDE_Morph.prototype.init; - -IDE_Morph.prototype.init = function(isAutoFill) { - this.originalInit(); - // Borders are actually just paddings, so we set the bg white to get them to be white - //this.backgroundColor = new Color(255,255,255); - //this.setColor(this.backgroundColor); - this.padding = 1; - //this.frameColor = new Color(220,220,220); -} - - -// change logo -IDE_Morph.prototype.originalCreateLogo = IDE_Morph.prototype.createLogo; -IDE_Morph.prototype.createLogo = function () { - this.originalCreateLogo(); - if (MorphicPreferences.isFlat) { - this.logo.texture = 'stitchcode/stitchcode_logo_small.png'; - } else { - this.logo.texture = 'stitchcode/stitchcode_logo_small_black.png'; - } - - this.logo.color = new Color(230, 230, 230); - this.logo.drawNew(); -} - -IDE_Morph.prototype.buildPanes = function () { - this.createLogo(); - this.createControlBar(); - this.createCategories(); - this.createPalette(); - this.createStage(); - this.createSpriteEditor(); - this.createSpriteBar(); - this.createStatusDisplay(); -}; - -// add buttons - -IDE_Morph.prototype.createControlBar = function () { - // assumes the logo has already been created - var padding = 4, - button, - stopButton, - pauseButton, - startButton, - projectButton, - settingsButton, - stageSizeButton, - //largeStageSizeButton, - appModeButton, - cloudButton, - upstitchButton, - x, - colors = [ - this.groupColor, - this.frameColor.darker(50), - this.frameColor.darker(50) - ], - myself = this; - - if (this.controlBar) { - this.controlBar.destroy(); - } - - this.controlBar = new Morph(); - this.controlBar.color = this.frameColor; - this.controlBar.color = new Color(250, 250, 250); - this.controlBar.setHeight(this.logo.height()); // height is fixed - this.controlBar.mouseClickLeft = function () { - this.world().fillPage(); - }; - this.add(this.controlBar); -/* - button = new ToggleButtonMorph( - null, //colors, - myself, // the IDE is the target - 'setLargeStageSize', - new SymbolMorph('largeStage', 14) - ); - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = this.buttonLabelColor; - button.query = function(){}; - button.contrast = this.buttonContrast; - button.drawNew(); - button.fixLayout(); - button.refresh(); - largeStageSizeButton = button; - this.controlBar.add(largeStageSizeButton); - this.controlBar.largeStageSizeButton = button; // for refreshing -*/ - - - //smallStageButton - button = new ToggleButtonMorph( - null, //colors, - myself, // the IDE is the target - 'toggleStageSize', - [ - new SymbolMorph('smallStage', 14), - new SymbolMorph('normalStage', 14) - ], - function () { // query - return myself.isSmallStage; - } - ); - - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = this.buttonLabelColor; - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'stage size\nsmall & normal'; - button.fixLayout(); - button.refresh(); - stageSizeButton = button; - this.controlBar.add(stageSizeButton); - this.controlBar.stageSizeButton = button; // for refreshing - - //appModeButton - button = new ToggleButtonMorph( - null, //colors, - myself, // the IDE is the target - 'toggleAppMode', - [ - new SymbolMorph('fullScreen', 14), - new SymbolMorph('normalScreen', 14) - ], - function () { // query - return myself.isAppMode; - } - ); - - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = this.buttonLabelColor; - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'app & edit\nmodes'; - button.fixLayout(); - button.refresh(); - appModeButton = button; - this.controlBar.add(appModeButton); - this.controlBar.appModeButton = appModeButton; // for refreshing - - // upload StitchButton - button = new PushButtonMorph( - this, - 'uploadMe', - new SymbolMorph('arrowUp', 14) - ); - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = this.buttonLabelColor; - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'stop\nevery-\nthing'; - button.fixLayout(); - upstitchButton = button; - this.controlBar.add(upstitchButton); - - - // stopButton - button = new PushButtonMorph( - this, - 'stopAllScripts', - new SymbolMorph('octagon', 14) - ); - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = new Color(200, 0, 0); - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'stop\nevery-\nthing'; - button.fixLayout(); - stopButton = button; - this.controlBar.add(stopButton); - - //pauseButton - button = new ToggleButtonMorph( - null, //colors, - myself, // the IDE is the target - 'togglePauseResume', - [ - new SymbolMorph('pause', 12), - new SymbolMorph('pointRight', 14) - ], - function () { // query - return myself.isPaused(); - } - ); - - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = new Color(255, 220, 0); - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'pause/resume\nall scripts'; - button.fixLayout(); - button.refresh(); - pauseButton = button; - this.controlBar.add(pauseButton); - this.controlBar.pauseButton = pauseButton; // for refreshing - - // startButton - button = new PushButtonMorph( - this, - 'pressStart', - new SymbolMorph('flag', 14) - ); - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = new Color(0, 200, 0); - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'start green\nflag scripts'; - button.fixLayout(); - startButton = button; - this.controlBar.add(startButton); - this.controlBar.startButton = startButton; - - // projectButton - button = new PushButtonMorph( - this, - 'projectMenu', - new SymbolMorph('file', 14) - //'\u270E' - ); - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = this.buttonLabelColor; - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'open, save, & annotate project'; - button.fixLayout(); - projectButton = button; - this.controlBar.add(projectButton); - this.controlBar.projectButton = projectButton; // for menu positioning - - // settingsButton - button = new PushButtonMorph( - this, - 'settingsMenu', - new SymbolMorph('gears', 14) - //'\u2699' - ); - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = this.buttonLabelColor; - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'edit settings'; - button.fixLayout(); - settingsButton = button; - this.controlBar.add(settingsButton); - this.controlBar.settingsButton = settingsButton; // for menu positioning - - // cloudButton - button = new PushButtonMorph( - this, - 'cloudMenu', - new SymbolMorph('cloud', 11) - ); - button.corner = 12; - button.color = colors[0]; - button.highlightColor = colors[1]; - button.pressColor = colors[2]; - button.labelMinExtent = new Point(36, 18); - button.padding = 0; - button.labelShadowOffset = new Point(-1, -1); - button.labelShadowColor = colors[1]; - button.labelColor = this.buttonLabelColor; - button.contrast = this.buttonContrast; - button.drawNew(); - // button.hint = 'cloud operations'; - button.fixLayout(); - cloudButton = button; - this.controlBar.add(cloudButton); - this.controlBar.cloudButton = cloudButton; // for menu positioning - - this.controlBar.fixLayout = function () { - x = this.right() - padding; - [stopButton, pauseButton, startButton].forEach( - function (button) { - button.setCenter(myself.controlBar.center()); - button.setRight(x); - x -= button.width(); - x -= padding; - } - ); - - x = Math.min( - startButton.left() - (3 * padding + 2 * stageSizeButton.width()), - myself.right() - StageMorph.prototype.dimensions.x * - (myself.isSmallStage ? myself.stageRatio : 1) - ); - [upstitchButton, stageSizeButton, appModeButton].forEach( - function (button) { - x += padding; - button.setCenter(myself.controlBar.center()); - button.setLeft(x); - x += button.width(); - } - ); - - settingsButton.setCenter(myself.controlBar.center()); - settingsButton.setLeft(this.left()); - - cloudButton.setCenter(myself.controlBar.center()); - cloudButton.setRight(settingsButton.left() - padding); - - projectButton.setCenter(myself.controlBar.center()); - projectButton.setRight(cloudButton.left() - padding); - - this.updateLabel(); - }; - - this.controlBar.updateLabel = function () { - var suffix = myself.world().isDevMode ? - ' - ' + localize('development mode') : ''; - - if (this.label) { - this.label.destroy(); - } - if (myself.isAppMode) { - return; - } - - this.label = new StringMorph( - (myself.projectName || localize('untitled')) + suffix, - 14, - 'sans-serif', - true, - false, - false, - MorphicPreferences.isFlat ? null : new Point(2, 1), - myself.frameColor.darker(myself.buttonContrast) - ); - this.label.color = myself.buttonLabelColor; - this.label.drawNew(); - this.add(this.label); - this.label.setCenter(this.center()); - this.label.setLeft(this.settingsButton.right() + padding); - }; -}; - -IDE_Morph.prototype.setLargeStageSize = function () { - this.setStageSize(1.5); -} -IDE_Morph.prototype.setNormalStageSize = function () { - this.setStageSize(1); -} - -IDE_Morph.prototype.setSmallStageSize = function () { - this.setStageSize(0.5); -} - -IDE_Morph.prototype.setStageSize = function (ratio) { - /* var myself = this, - world = this.world(), - shiftClicked = (world.currentKey === 16);*/ - - this.setStageExtent(new Point(480 * ratio, 360 * ratio)) - - /* - myself.step = function () { - myself.stageRatio = ratio; - myself.setExtent(world.extent()); - myself.controlBar.stageSizeButton.refresh(); - delete myself.step; - } - - // not working yet - if (shiftClicked) { - ratio = SpriteIconMorph.prototype.thumbSize.x * 3 / - this.stage.dimensions.x; - } - */ -}; - -IDE_Morph.prototype.uploadStitches = function () { - tStitch.upload(); -}; - - - -ProjectDialogMorph.prototype.getExamplesProjectList = function () { - var dir, - projects = []; - - //dir = this.ide.getURL('http://snap.berkeley.edu/snapsource/Examples/'); - dir = this.ide.getURL(tStitch.getBaseURL() + '/stitchcode/examples/'); - dir.split('\n').forEach( - function (line) { - var startIdx = line.search(new RegExp('href=".*xml"')), - endIdx, - name, - dta; - if (startIdx > 0) { - endIdx = line.search(new RegExp('.xml')); - name = line.substring(startIdx + 6, endIdx); - dta = { - name: name, - thumb: null, - notes: null - }; - projects.push(dta); - console.log(dta); - } - } - ); - projects.sort(function (x, y) { - return x.name < y.name ? -1 : 1; - }); - return projects; -}; - -ProjectDialogMorph.prototype.setSource = function (source) { - var myself = this, - msg; - - this.source = source; //this.task === 'save' ? 'local' : source; - this.srcBar.children.forEach(function (button) { - button.refresh(); - }); - switch (this.source) { - case 'cloud': - msg = myself.ide.showMessage('Updating\nproject list...'); - this.projectList = []; - SnapCloud.getProjectList( - function (projectList) { - myself.installCloudProjectList(projectList); - msg.destroy(); - }, - function (err, lbl) { - msg.destroy(); - myself.ide.cloudError().call(null, err, lbl); - } - ); - return; - case 'examples': - this.projectList = this.getExamplesProjectList(); - break; - case 'local': - this.projectList = this.getLocalProjectList(); - break; - } - - this.listField.destroy(); - this.listField = new ListMorph( - this.projectList, - this.projectList.length > 0 ? - function (element) { - return element.name; - } : null, - null, - function () {myself.ok(); } - ); - - this.fixListFieldItemColors(); - this.listField.fixLayout = nop; - this.listField.edge = InputFieldMorph.prototype.edge; - this.listField.fontSize = InputFieldMorph.prototype.fontSize; - this.listField.typeInPadding = InputFieldMorph.prototype.typeInPadding; - this.listField.contrast = InputFieldMorph.prototype.contrast; - this.listField.drawNew = InputFieldMorph.prototype.drawNew; - this.listField.drawRectBorder = InputFieldMorph.prototype.drawRectBorder; - - if (this.source === 'local') { - this.listField.action = function (item) { - var src, xml; - - if (item === undefined) {return; } - if (myself.nameField) { - myself.nameField.setContents(item.name || ''); - } - if (myself.task === 'open') { - - src = localStorage['-snap-project-' + item.name]; - xml = myself.ide.serializer.parse(src); - - myself.notesText.text = xml.childNamed('notes').contents - || ''; - myself.notesText.drawNew(); - myself.notesField.contents.adjustBounds(); - myself.preview.texture = xml.childNamed('thumbnail').contents - || null; - myself.preview.cachedTexture = null; - myself.preview.drawNew(); - } - myself.edit(); - }; - } else { // 'examples', 'cloud' is initialized elsewhere - this.listField.action = function (item) { - var src, xml; - if (item === undefined) {return; } - if (myself.nameField) { - myself.nameField.setContents(item.name || ''); - } - src = myself.ide.getURL( - // 'http://snap.berkeley.edu/snapsource/Examples/' + - tStitch.getBaseURL() + 'stitchcode/examples/' + - item.name + '.xml' - ); - - xml = myself.ide.serializer.parse(src); - myself.notesText.text = xml.childNamed('notes').contents - || ''; - myself.notesText.drawNew(); - myself.notesField.contents.adjustBounds(); - myself.preview.texture = xml.childNamed('thumbnail').contents - || null; - myself.preview.cachedTexture = null; - myself.preview.drawNew(); - myself.edit(); - }; - } - this.body.add(this.listField); - this.shareButton.hide(); - this.unshareButton.hide(); - if (this.source === 'local') { - this.deleteButton.show(); - } else { // examples - this.deleteButton.hide(); - } - this.buttons.fixLayout(); - this.fixLayout(); - if (this.task === 'open') { - this.clearDetails(); - } -}; - -ProjectDialogMorph.prototype.openProject = function () { - var proj = this.listField.selected, src; - if (!proj) {return; } - this.ide.source = this.source; - if (this.source === 'cloud') { - this.openCloudProject(proj); - } else if (this.source === 'examples') { - src = this.ide.getURL(tStitch.getBaseURL() + 'stitchcode/examples/' + proj.name + '.xml'); - this.ide.openProjectString(src); - this.destroy(); - } else { // 'local' - this.ide.openProject(proj.name); - this.destroy(); - } -}; - -IDE_Morph.prototype.toggleAppMode = function (appMode) { - var world = this.world(), - elements = [ - this.logo, - this.controlBar.projectButton, - this.controlBar.cloudButton, - this.controlBar.settingsButton, - this.controlBar.stageSizeButton, - this.controlBar.stageSizeButton, - //this.controlBar.largeStageSizeButton, - this.spriteEditor, - this.palette, - this.categories ]; - - this.isAppMode = isNil(appMode) ? !this.isAppMode : appMode; - - Morph.prototype.trackChanges = false; - if (this.isAppMode) { - this.setColor(this.appModeColor); - this.controlBar.setColor(this.color); - this.controlBar.appModeButton.refresh(); - elements.forEach(function (e) { - e.hide(); - }); - world.children.forEach(function (morph) { - if (morph instanceof DialogBoxMorph) { - morph.hide(); - } - }); - } else { - this.setColor(this.backgroundColor); - this.controlBar.setColor(this.frameColor); - elements.forEach(function (e) { - e.show(); - }); - this.stage.setScale(1); - // show all hidden dialogs - world.children.forEach(function (morph) { - if (morph instanceof DialogBoxMorph) { - morph.show(); - } - }); - // prevent scrollbars from showing when morph appears - world.allChildren().filter(function (c) { - return c instanceof ScrollFrameMorph; - }).forEach(function (s) { - s.adjustScrollBars(); - }); - } - this.setExtent(this.world().extent()); // resume trackChanges -}; - - - -IDE_Morph.prototype.createStatusDisplay = function () { - var frame, - padding = 1, - myself = this, - elements = [], - beetle = this.currentSprite.beetle, - stage = this.stage; - - if (this.statusDisplay) { - this.statusDisplay.destroy(); - } - - this.statusDisplay = new Morph(); - this.statusDisplay.color = this.groupColor; - this.add(this.statusDisplay); - - frame = new ScrollFrameMorph(null, null, this.sliderColor); - frame.acceptsDrops = false; - frame.contents.acceptsDrops = false; - - frame.alpha = 0; - - this.statusDisplay.frame = frame; - this.statusDisplay.add(frame); - - this.statusDisplay.fixLayout = function () { - this.setLeft(myself.stage.left()); - this.setTop(myself.stage.bottom() + padding); - this.setWidth(myself.stage.width()); - this.setHeight(myself.height() - myself.stage.height() - myself.controlBar.height() - padding); - this.frame.setExtent(this.extent()); - this.arrangeContents() - this.refresh(); - }; - - this.statusDisplay.arrangeContents = function () { - var x = this.left() + padding, - y = this.top() + padding, - max = this.right() - padding, - start = x, - middle = (max - start) / 2 + start; - - this.frame.contents.children.forEach(function (element) { - element.setPosition(new Point(x, y)); - x += element.width(); - - if (element instanceof ToggleMorph) { x+= element.label.width() + 2 }; - - if (element.newLines) { - y += 14 * element.newLines; - x = start; - }; - - if (element.newColumn) { - if (element.columns) { - x = ((max - start) / element.columns) * element.newColumn + start; - } else { - x = middle; - } - }; - }); - - this.frame.contents.adjustBounds(); - }; - - this.statusDisplay.addElement = function (element) { - - if (typeof element == 'string') { - element = new StringMorph(localize(element), 12, null, true); - }; - - this.frame.contents.add(element); - this.fixLayout(); - }; - - this.statusDisplay.refresh = function () { - this.frame.contents.children.forEach(function (element) { - if (element.hasOwnProperty('update')) { - element.update(); - element.changed(); - element.drawNew(); - element.changed(); - }; - }); - }; - - this.statusDisplay.acceptsDrops = function () { - return false; - }; - - this.statusDisplay.watchers = function (leftPos) { - /* answer an array of all currently visible watchers. - If leftPos is specified, filter the list for all - shown or hidden watchers whose left side equals - the given border (for automatic positioning) */ - - return this.children.filter(function (morph) { - if (morph instanceof WatcherMorph) { - if (leftPos) { - return morph.left() === leftPos; - } - return morph.isVisible; - } - return false; - }); - }; - - this.statusDisplay.step = function() { - // update watchers - current = Date.now(); - elapsed = current - this.lastWatcherUpdate; - leftover = (1000 / this.watcherUpdateFrequency) - elapsed; - if (leftover < 1) { - this.watchers().forEach(function (w) { - w.update(); - }); - this.lastWatcherUpdate = Date.now(); - } - } - - this.statusDisplay.lastWatcherUpdate = Date.now(); - this.statusDisplay.watcherUpdateFrequency = 250; - - // Buttons and toggles - - - var toogleShowStitchButton = new ToggleMorph( - 'checkbox', - null, - function () { - tStitch.toogleShowStitches(); - }, - 'Show Stitches', - function () { - return tStitch.getShowStitches(); - }); - toogleShowStitchButton.columns = 2 - toogleShowStitchButton.newLines = 1; - - elements.push(toogleShowStitchButton); - - var toogleShowJumpsButton = new ToggleMorph( - 'checkbox', - null, - function () { - tStitch.toogleShowJumpStitches(); - }, - 'Show Jump Stitches', - function () { - return tStitch.getShowJumpStitches(); - }); - toogleShowJumpsButton.columns = 1; - - elements.push(toogleShowJumpsButton); - - - elements.forEach(function(each) { myself.statusDisplay.addElement(each) }); -}; - - -// IDE_Morph layout - -IDE_Morph.prototype.fixLayout = function (situation) { - // situation is a string, i.e. - // 'selectSprite' or 'refreshPalette' or 'tabEditor' - var padding = this.padding; - - Morph.prototype.trackChanges = false; - - if (situation !== 'refreshPalette') { - // controlBar - this.controlBar.setPosition(this.logo.topRight()); - this.controlBar.setWidth(this.right() - this.controlBar.left()); - this.controlBar.fixLayout(); - - // categories - this.categories.padding = this.padding; - this.categories.setLeft(this.logo.left()); - this.categories.setTop(this.logo.bottom()+padding); - - } - - // palette - this.palette.setLeft(this.logo.left()); - this.palette.setTop(this.categories.bottom() + padding); - this.palette.setHeight(this.bottom() - this.palette.top()); - - if (situation !== 'refreshPalette') { - // stage - if (this.isAppMode) { - this.stage.setScale(Math.floor(Math.min( - (this.width() - padding * 2) / this.stage.dimensions.x, - (this.height() - this.controlBar.height() * 2 - padding * 2) - / this.stage.dimensions.y - ) * 10) / 10); - this.stage.setCenter(this.center()); - } else { -// this.stage.setScale(this.isSmallStage ? 0.5 : 1); - this.stage.setScale(this.isSmallStage ? this.stageRatio : 1); - this.stage.setTop(this.logo.bottom() + padding); - this.stage.setRight(this.right()); - } - - // spriteBar - this.spriteBar.setPosition(this.logo.bottomRight().add(padding)); - this.spriteBar.setExtent(new Point( - Math.max(0, this.stage.left() - padding - this.spriteBar.left()), - this.categories.bottom() - this.spriteBar.top() - padding - )); - this.spriteBar.fixLayout(); - - // spriteEditor - - if (this.spriteEditor.isVisible) { - //this.spriteEditor.setPosition(this.spriteBar.bottomLeft()); - this.spriteEditor.setPosition(this.logo.bottomRight().add(padding)); - this.spriteEditor.setExtent(new Point( - //this.spriteBar.width(), - Math.max(0, this.stage.left() - padding - this.spriteEditor.left()), - this.bottom() - this.spriteEditor.top() - )); - } - this.statusDisplay.fixLayout(); - } - - - Morph.prototype.trackChanges = true; - this.changed(); -}; - - -// SVG export -IDE_Morph.prototype.downloadSVG = function() { - - - var minX=999999999, maxX=0, minY=999999999, maxY=0; - for (var i=0; imaxX) maxX = x1; - - if (y1maxY) maxY = y1; - } - - var svgStr = "\n"; - svgStr += "\n"; - svgStr += "\n"; - svgStr += "Embroidery export\n"; - svgStr += "\n"; - } - } else { - if (tStitch.stitches.jump[i-1]&& i>1) { - svgStr +=" \n\n" - - blob = new Blob([svgStr], {type: 'text/plain;charset=utf-8'}); - saveAs(blob, (this.projectName ? this.projectName : 'turtlestitch') + '.svg'); -} - -// EXP export -IDE_Morph.prototype.downloadEXP = function() { - var expArr = new Array(); - - pixels_per_millimeter = 5 - scale = 10 / pixels_per_millimeter; - - function move(x, y) { - y *= -1; - if (x<0) x = x + 256; - expArr.push(x); - if (y<0) y = y + 256; - expArr.push(y); - - } - - for (var i=1; i 0) { - libMenu.addItem( - line, - function () {loadCostume(line); } - ); - } - }); - libMenu.popup(world, pos); - }, - 'Select a costume from the media library' - ); - -/* graphicsName = 'Costumes'; - menu.addItem( - localize(graphicsName) + '...', - function () { - var dir = graphicsName, - names = myself.getCostumesList(dir), - libMenu = new MenuMorph( - myself, - localize('Import') + ' ' + localize(dir) - ); - - function loadCostume(name) { - var url = dir + '/' + name, - img = new Image(); - img.onload = function () { - var canvas = newCanvas(new Point(img.width, img.height)); - canvas.getContext('2d').drawImage(img, 0, 0); - myself.droppedImage(canvas, name); - }; - img.src = url; - } - - names.forEach(function (line) { - if (line.length > 0) { - libMenu.addItem( - line, - function () {loadCostume(line); } - ); - } - }); - libMenu.popup(world, pos); - }, - 'Select a costume from the media library' - ); - */ - menu.addItem( - 'Libraries...', - function () { - // read a list of libraries from an external file, - var libMenu = new MenuMorph(this, 'Import library'), - libUrl = 'http://snap.berkeley.edu/snapsource/libraries/' + - 'LIBRARIES'; - - function loadLib(name) { - var url = 'http://snap.berkeley.edu/snapsource/libraries/' - + name - + '.xml'; - myself.droppedText(myself.getURL(url), name); - } - - myself.getURL(libUrl).split('\n').forEach(function (line) { - if (line.length > 0) { - libMenu.addItem( - line.substring(line.indexOf('\t') + 1), - function () { - loadLib( - line.substring(0, line.indexOf('\t')) - ); - } - ); - } - }); - - libMenu.popup(world, pos); - }, - 'Select categories of additional blocks to add to this project.' - ); - - menu.popup(world, pos); -}; - -IDE_Morph.prototype.snapMenu = function () { - var menu, - world = this.world(); - - menu = new MenuMorph(this); - menu.addItem('About...', 'aboutSnap'); - menu.addLine(); - menu.addItem( - 'Reference manual', - function () { - window.open('help/SnapManual.pdf', 'SnapReferenceManual'); - } - ); - menu.addItem( - 'TurtleStich! website', - function () { - window.open('http://'+window.location.hostname, 'SnapWebsite'); - } - ); - menu.addItem( - 'Snap! website', - function () { - window.open('http://snap.berkeley.edu/', 'SnapWebsite'); - } - ); - menu.addItem( - 'Download source', - function () { - window.open( - 'http://snap.berkeley.edu/snapsource/snap.zip', - 'SnapSource' - ); - } - ); - if (world.isDevMode) { - menu.addLine(); - menu.addItem( - 'Switch back to user mode', - 'switchToUserMode', - 'disable deep-Morphic\ncontext menus' - + '\nand show user-friendly ones', - new Color(0, 100, 0) - ); - } else if (world.currentKey === 16) { // shift-click - menu.addLine(); - menu.addItem( - 'Switch to dev mode', - 'switchToDevMode', - 'enable Morphic\ncontext menus\nand inspectors,' - + '\nnot user-friendly!', - new Color(100, 0, 0) - ); - } - menu.popup(world, this.logo.bottomLeft()); -}; - - -IDE_Morph.prototype.originalCreateSpriteEditor = IDE_Morph.prototype.createSpriteEditor; -IDE_Morph.prototype.createSpriteEditor = function(){ - this.originalCreateSpriteEditor(); - this.spriteEditor.color = new Color(240, 240, 240); - this.currentSprite.scripts.color = new Color(240, 240, 240); -} - - - - -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 = ['\u2192', '\u21BB', '\u2194'], - 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 - function () { - if (myself.currentSprite instanceof SpriteMorph) { - myself.currentSprite.rotationStyle = rotationStyle; - myself.currentSprite.changed(); - myself.currentSprite.drawNew(); - myself.currentSprite.changed(); - } - rotationStyleButtons.forEach(function (each) { - each.refresh(); - }); - }, - symbols[rotationStyle], // label - function () { // query - return myself.currentSprite instanceof SpriteMorph - && 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(2)); - 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.setExtent(thumbSize); - thumbnail.image = 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.image = myself.currentSprite.thumbnail(thumbSize); - 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); - nameField.drawNew(); - 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; - - // padlock - padlock = new ToggleMorph( - 'checkbox', - null, - function () { - myself.currentSprite.isDraggable = - !myself.currentSprite.isDraggable; - }, - localize('draggable'), - function () { - return myself.currentSprite.isDraggable; - } - ); - padlock.label.isBold = false; - padlock.label.setColor(this.buttonLabelColor); - padlock.color = tabColors[2]; - padlock.highlightColor = tabColors[0]; - padlock.pressColor = tabColors[1]; - - padlock.tick.shadowOffset = MorphicPreferences.isFlat ? - new Point() : new Point(-1, -1); - padlock.tick.shadowColor = new Color(); // black - padlock.tick.color = this.buttonLabelColor; - padlock.tick.isBold = false; - padlock.tick.drawNew(); - - padlock.setPosition(nameField.bottomLeft().add(2)); - padlock.drawNew(); - this.spriteBar.add(padlock); - if (this.currentSprite instanceof StageMorph) { - padlock.hide(); - } - - // tab bar - tabBar.tabTo = function (tabString) { - var active; - myself.currentTab = tabString; - this.children.forEach(function (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 - function () {tabBar.tabTo('scripts'); }, - localize('Scripts'), // label - function () { // query - return myself.currentTab === 'scripts'; - } - ); - tab.padding = 3; - tab.corner = tabCorner; - tab.edge = 1; - tab.labelShadowOffset = new Point(-1, -1); - tab.labelShadowColor = tabColors[1]; - tab.labelColor = this.buttonLabelColor; - tab.drawNew(); - tab.fixLayout(); - tabBar.add(tab); - - tab = new TabMorph( - tabColors, - null, // target - function () {tabBar.tabTo('costumes'); }, - localize('Costumes'), // label - function () { // query - return myself.currentTab === 'costumes'; - } - ); - tab.padding = 3; - tab.corner = tabCorner; - tab.edge = 1; - tab.labelShadowOffset = new Point(-1, -1); - tab.labelShadowColor = tabColors[1]; - tab.labelColor = this.buttonLabelColor; - tab.drawNew(); - tab.fixLayout(); - tabBar.add(tab); - - tab = new TabMorph( - tabColors, - null, // target - function () {tabBar.tabTo('sounds'); }, - localize('Sounds'), // label - function () { // query - return myself.currentTab === 'sounds'; - } - ); - tab.padding = 3; - tab.corner = tabCorner; - tab.edge = 1; - tab.labelShadowOffset = new Point(-1, -1); - tab.labelShadowColor = tabColors[1]; - tab.labelColor = this.buttonLabelColor; - tab.drawNew(); - tab.fixLayout(); - tabBar.add(tab); - - tabBar.fixLayout(); - tabBar.children.forEach(function (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()); - }; -}; - -IDE_Morph.prototype.createCorralBar = function () { - // assumes the stage has already been created - var padding = 5, - newbutton, - paintbutton, - colors = [ - 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, - "addNewSprite", - new SymbolMorph("turtle", 14) - ); - newbutton.corner = 12; - newbutton.color = colors[0]; - newbutton.highlightColor = colors[1]; - newbutton.pressColor = colors[2]; - newbutton.labelMinExtent = new Point(36, 18); - newbutton.padding = 0; - newbutton.labelShadowOffset = new Point(-1, -1); - newbutton.labelShadowColor = colors[1]; - newbutton.labelColor = this.buttonLabelColor; - newbutton.contrast = this.buttonContrast; - newbutton.drawNew(); - newbutton.hint = "add a new Turtle sprite"; - newbutton.fixLayout(); - newbutton.setCenter(this.corralBar.center()); - newbutton.setLeft(this.corralBar.left() + padding); - this.corralBar.add(newbutton); - - paintbutton = new PushButtonMorph( - this, - "paintNewSprite", - new SymbolMorph("brush", 15) - ); - paintbutton.corner = 12; - paintbutton.color = colors[0]; - paintbutton.highlightColor = colors[1]; - paintbutton.pressColor = colors[2]; - paintbutton.labelMinExtent = new Point(36, 18); - paintbutton.padding = 0; - paintbutton.labelShadowOffset = new Point(-1, -1); - paintbutton.labelShadowColor = colors[1]; - paintbutton.labelColor = this.buttonLabelColor; - paintbutton.contrast = this.buttonContrast; - paintbutton.drawNew(); - paintbutton.hint = "paint a new sprite"; - paintbutton.fixLayout(); - paintbutton.setCenter(this.corralBar.center()); - paintbutton.setLeft( - this.corralBar.left() + padding + newbutton.width() + padding - ); - this.corralBar.add(paintbutton); - */ -}; - - -IDE_Morph.prototype.createCorral = function () { - // assumes the corral bar has already been created - var frame, template, padding = 5, myself = this; - - if (this.corral) { - this.corral.destroy(); - } - - this.corral = new Morph(); - this.corral.color = this.groupColor; - //this.add(this.corral); - - this.corral.stageIcon = new SpriteIconMorph(this.stage); - this.corral.stageIcon.isDraggable = false; - this.corral.add(this.corral.stageIcon); - - frame = new ScrollFrameMorph(null, null, this.sliderColor); - frame.acceptsDrops = false; - frame.contents.acceptsDrops = false; - - frame.contents.wantsDropOf = function (morph) { - return morph instanceof SpriteIconMorph; - }; - - frame.contents.reactToDropOf = function (spriteIcon) { - myself.corral.reactToDropOf(spriteIcon); - }; - - frame.alpha = 0; - - this.sprites.asArray().forEach(function (morph) { - template = new SpriteIconMorph(morph, template); - frame.contents.add(template); - }); - - this.corral.frame = frame; - this.corral.add(frame); - - this.corral.fixLayout = function () { - this.stageIcon.setCenter(this.center()); - this.stageIcon.setLeft(this.left() + padding); - this.frame.setLeft(this.stageIcon.right() + padding); - this.frame.setExtent(new Point( - this.right() - this.frame.left(), - this.height() - )); - this.arrangeIcons(); - this.refresh(); - }; - - this.corral.arrangeIcons = function () { - var x = this.frame.left(), - y = this.frame.top(), - max = this.frame.right(), - start = this.frame.left(); - - this.frame.contents.children.forEach(function (icon) { - var w = icon.width(); - - if (x + w > max) { - x = start; - y += icon.height(); // they're all the same - } - icon.setPosition(new Point(x, y)); - x += w; - }); - this.frame.contents.adjustBounds(); - }; - - this.corral.addSprite = function (sprite) { - this.frame.contents.add(new SpriteIconMorph(sprite)); - this.fixLayout(); - }; - - this.corral.refresh = function () { - this.stageIcon.refresh(); - this.frame.contents.children.forEach(function (icon) { - icon.refresh(); - }); - }; - - this.corral.wantsDropOf = function (morph) { - return morph instanceof SpriteIconMorph; - }; - - this.corral.reactToDropOf = function (spriteIcon) { - var idx = 1, - pos = spriteIcon.position(); - spriteIcon.destroy(); - this.frame.contents.children.forEach(function (icon) { - if (pos.gt(icon.position()) || pos.y > icon.bottom()) { - idx += 1; - } - }); - myself.sprites.add(spriteIcon.object, idx); - myself.createCorral(); - myself.fixLayout(); - }; - -}; - - -ProjectDialogMorph.prototype.buildContents = function () { - var thumbnail, notification; - - this.addBody(new Morph()); - this.body.color = this.color; - - this.srcBar = new AlignmentMorph('column', this.padding / 2); - - if (this.ide.cloudMsg) { - notification = new TextMorph( - this.ide.cloudMsg, - 10, - null, // style - false, // bold - null, // italic - null, // alignment - null, // width - null, // font name - new Point(1, 1), // shadow offset - new Color(255, 255, 255) // shadowColor - ); - notification.refresh = nop; - this.srcBar.add(notification); - } - - //disable cloud for now - // this.addSourceButton('cloud', localize('Cloud'), 'cloud'); - this.addSourceButton('local', localize('Browser'), 'storage'); - if (this.task === 'open') { - this.addSourceButton('examples', localize('Examples'), 'poster'); - } - this.srcBar.fixLayout(); - this.body.add(this.srcBar); - - if (this.task === 'save') { - this.nameField = new InputFieldMorph(this.ide.projectName); - this.body.add(this.nameField); - } - - this.listField = new ListMorph([]); - this.fixListFieldItemColors(); - this.listField.fixLayout = nop; - this.listField.edge = InputFieldMorph.prototype.edge; - this.listField.fontSize = InputFieldMorph.prototype.fontSize; - this.listField.typeInPadding = InputFieldMorph.prototype.typeInPadding; - this.listField.contrast = InputFieldMorph.prototype.contrast; - this.listField.drawNew = InputFieldMorph.prototype.drawNew; - this.listField.drawRectBorder = InputFieldMorph.prototype.drawRectBorder; - - this.body.add(this.listField); - - this.preview = new Morph(); - this.preview.fixLayout = nop; - this.preview.edge = InputFieldMorph.prototype.edge; - this.preview.fontSize = InputFieldMorph.prototype.fontSize; - this.preview.typeInPadding = InputFieldMorph.prototype.typeInPadding; - this.preview.contrast = InputFieldMorph.prototype.contrast; - this.preview.drawNew = function () { - InputFieldMorph.prototype.drawNew.call(this); - if (this.texture) { - this.drawTexture(this.texture); - } - }; - this.preview.drawCachedTexture = function () { - var context = this.image.getContext('2d'); - context.drawImage(this.cachedTexture, this.edge, this.edge); - this.changed(); - }; - this.preview.drawRectBorder = InputFieldMorph.prototype.drawRectBorder; - this.preview.setExtent( - this.ide.serializer.thumbnailSize.add(this.preview.edge * 2) - ); - - this.body.add(this.preview); - this.preview.drawNew(); - if (this.task === 'save') { - thumbnail = this.ide.stage.thumbnail( - SnapSerializer.prototype.thumbnailSize - ); - this.preview.texture = null; - this.preview.cachedTexture = thumbnail; - this.preview.drawCachedTexture(); - } - - this.notesField = new ScrollFrameMorph(); - this.notesField.fixLayout = nop; - - this.notesField.edge = InputFieldMorph.prototype.edge; - this.notesField.fontSize = InputFieldMorph.prototype.fontSize; - this.notesField.typeInPadding = InputFieldMorph.prototype.typeInPadding; - this.notesField.contrast = InputFieldMorph.prototype.contrast; - this.notesField.drawNew = InputFieldMorph.prototype.drawNew; - this.notesField.drawRectBorder = InputFieldMorph.prototype.drawRectBorder; - - this.notesField.acceptsDrops = false; - this.notesField.contents.acceptsDrops = false; - - if (this.task === 'open') { - this.notesText = new TextMorph(''); - } else { // 'save' - this.notesText = new TextMorph(this.ide.projectNotes); - this.notesText.isEditable = true; - this.notesText.enableSelecting(); - } - - this.notesField.isTextLineWrapping = true; - this.notesField.padding = 3; - this.notesField.setContents(this.notesText); - this.notesField.setWidth(this.preview.width()); - - this.body.add(this.notesField); - - if (this.task === 'open') { - this.addButton('openProject', 'Open'); - this.action = 'openProject'; - } else { // 'save' - this.addButton('saveProject', 'Save'); - this.action = 'saveProject'; - } - this.shareButton = this.addButton('shareProject', 'Share'); - this.unshareButton = this.addButton('unshareProject', 'Unshare'); - this.shareButton.hide(); - this.unshareButton.hide(); - this.deleteButton = this.addButton('deleteProject', 'Delete'); - this.addButton('cancel', 'Cancel'); - - if (notification) { - this.setExtent(new Point(455, 335).add(notification.extent())); - } else { - this.setExtent(new Point(455, 335)); - } - this.fixLayout(); - -}; - -IDE_Morph.prototype.droppedImageStage = function (aCanvas, name) { - var costume = new Costume( - aCanvas, - this.currentSprite.newCostumeName( - name ? name.split('.')[0] : '' // up to period - ) - ); - - if (costume.isTainted()) { - this.inform( - 'Unable to import this image', - 'The picture you wish to import has been\n' + - 'tainted by a restrictive cross-origin policy\n' + - 'making it unusable for costumes in Snap!. \n\n' + - 'Try downloading this picture first to your\n' + - 'computer, and import it from there.' - ); - return; - } - - this.stage.addCostume(costume); - this.stage.wearCostume(costume); - //this.spriteBar.tabBar.tabTo('costumes'); - this.hasChangedMedia = true; -}; diff --git a/stitchcode/tstitch.js b/stitchcode/tstitch.js deleted file mode 100644 index 1e279c9d..00000000 --- a/stitchcode/tstitch.js +++ /dev/null @@ -1,146 +0,0 @@ -// Stitchode's main changes and addtions to snap! go in here -// sorry it lacks proper documentation - - -var tStitch = {}; - -tStitch.debug = true; -tStitch.draw_jumps = true; -tStitch.draw_stitches = true; -tStitch.draw_stitch_len = 2; - -tStitch.debug_msg = function (st,clear) { - o = new String(); - if (!clear) { - o = document.getElementById("bug").innerHTML; - } else { - o = ""; - } - o += st; - document.getElementById("bug").innerHTML = o; -}; - -tStitch.getBaseURL = function () { - var url = location.href; // entire url including querystring - also: window.location.href; - if (url.lastIndexOf('#') > 0) { - url = url.substring(0, url.lastIndexOf('#')); - } - url = url.substring(0, url.lastIndexOf('/')); - return url + "/"; -}; - - -tStitch.stitches = {}; -tStitch.stitches.x = []; -tStitch.stitches.y = []; -tStitch.stitches.jump = []; - -tStitch.isFirst = function() { - if (tStitch.stitches.x.length > 0) - return false; - else - return true; -}; - -tStitch.clearPoints = function() { - tStitch.stitches.x = []; - tStitch.stitches.y = []; - tStitch.stitches.jump = []; -}; - -tStitch.addPoint = function (x,y,jump) { - if (tStitch.debug) { - s = new String(); - s = s + "adding Point (" + x + "," + y; - if (jump) s = s + ",jump"; - s+= ")"; - console.log(s); - } - - if (tStitch.stitches.x[tStitch.stitches.x.length-1] == x && - tStitch.stitches.y[tStitch.stitches.y.length-1] == y - ) { - //alert("pint exist"); - } else { - tStitch.stitches.x.push(x); - tStitch.stitches.y.push(y); - tStitch.stitches.jump.push(jump); - } -}; - -tStitch.toogleShowStitches = function() { - tStitch.draw_stitches = !tStitch.draw_stitches; -}; - -tStitch.getShowStitches = function() { - return tStitch.draw_stitches; -}; - -tStitch.toogleShowJumpStitches = function() { - tStitch.draw_jumps = !tStitch.draw_jumps; -}; - -tStitch.getShowJumpStitches = function() { - return tStitch.draw_jumps; -}; - -tStitch.signup = function() { - window.open('http://' + window.location.hostname + '/signup'); -}; - - -tStitch.upload = function(name) { - - tStitch.debug_msg("uploading points... sending SAVE with num points= " + tStitch.stitches.x.length, true); - params = { "x[]": tStitch.stitches.x, "y[]":tStitch.stitches.y, "j[]":tStitch.stitches.jump, "name":name }; - - if (tStitch.stitches.x.length <= 1 || tStitch.stitches.y <= 1) { - new DialogBoxMorph().inform( - 'Upload Error', - 'No stitches to upload, please (re)generate a drawing first!', - world); - - } else { - $.post( - "/upload", - data = params, - successCallback = function (data) { - if (data!="ERROR") { - /*new DialogBoxMorph().inform( - 'Upload Success', - 'Your embroidery file is ready and will be available at this url:\n' + - window.location.hostname + '/view/'+data,'\n', - world);*/ - window.open('http://' + window.location.hostname + '/view/'+data, 'TurtleStitch file preview'); - } else { - new DialogBoxMorph().inform( - 'Upload Error', - 'Sorry! Upload failed for an unknown reason', - world); - } - }); - } - - /* - $.fileDownload(tStitch.getBaseURL() +"stitchcode/backend/save.py", { - successCallback: function (html, url) { - alert("DSD"); - }, - failCallback: function (html, url) { - alert( - 'Your file download just failed for this URL:' + url + - '\r\n' + 'Here was the resulting error HTML: \r\n' - + html - ); - }, - - httpMethod: "POST", - data: params - }); */ -}; - - - -IDE_Morph.prototype.uploadStitches = function () { - tStitch.upload(); -}; diff --git a/stitchcode/tstools.js b/stitchcode/tstools.js deleted file mode 100644 index 085dda9f..00000000 --- a/stitchcode/tstools.js +++ /dev/null @@ -1,21 +0,0 @@ -var tstools = {}; - -tstools.getBaseURL = function () { - var url = location.href; // entire url including querystring - also: window.location.href; - if (url.lastIndexOf('#') > 0) { - url = url.substring(0, url.lastIndexOf('#')); - } - url = url.substring(0, url.lastIndexOf('/')); - return url + "/"; -}; - -tstools.debug_msg = function (st, clear=false) { - o = new String(); - if (!clear) { - o = document.getElementById("debug").innerHTML; - } else { - o = ""; - } - o = st + "
" + o; - document.getElementById("debug").innerHTML = o; -}; diff --git a/stitchcode/turtleShepherd.js b/stitchcode/turtleShepherd.js index 2de72e2b..686c4cb9 100644 --- a/stitchcode/turtleShepherd.js +++ b/stitchcode/turtleShepherd.js @@ -6,7 +6,10 @@ */ function TurtleShepherd() { + this.w = 480; + this.h = 360; this.clear(); + this.gridSize = 50; } TurtleShepherd.prototype.clear = function() { @@ -18,8 +21,6 @@ TurtleShepherd.prototype.clear = function() { this.steps = 0; this.initX = 0; this.initY = 0; - this.w = 480; - this.h = 360; this.scale = 1; }; @@ -85,16 +86,30 @@ TurtleShepherd.prototype.zoomOut = function() { if (DEBUG) this.debug_msg("zoom to scale "+ this.scale ); }; -TurtleShepherd.prototype.setDimensions = function(x,y) { - this.w = x; - this.h = y; +TurtleShepherd.prototype.setStageDimensions = function(w,h) { + this.w = w; + this.h = h; + /* + document.getElementById("svg2").style.left = x + "px"; + document.getElementById("svg2").style.top = y+ "px"; + */ + document.getElementById("svg2").style.width = w + "px"; + document.getElementById("svg2").style.height = h + "px"; + document.getElementById("svg2").style.right = "0"; + document.getElementById("svg2").style.bottom = "0"; +}; + +TurtleShepherd.prototype.setStagePosition = function(x,y) { + //document.getElementById("svg2").style.top = y + "px"; + //document.getElementById("svg2").style.left = x + "px"; }; -TurtleShepherd.prototype.renderGrid = function(size=50) { - return '\n' + - '\n' + - '\n' + +TurtleShepherd.prototype.renderGrid = function(size) { + size = this.gridSize; + return '' + + '' + + '' + '' + '\n'; }; @@ -103,7 +118,7 @@ TurtleShepherd.prototype.toSVG = function() { //var svgStr = "\n"; //svgStr += "\n"; - svgStr = '