diff --git a/stitchcode/blocks.js b/stitchcode/blocks.js index 9e180339..7a19b8a3 100644 --- a/stitchcode/blocks.js +++ b/stitchcode/blocks.js @@ -1,10 +1,13 @@ SymbolMorph.prototype.names.push('largeStage'); +SymbolMorph.prototype.names.push('zoomToFit'); SymbolMorph.prototype.originalSymbolCanvasColored = SymbolMorph.prototype.symbolCanvasColored; SymbolMorph.prototype.symbolCanvasColored = function (aColor) { if (this.name == 'largeStage') { return this.drawSymbolLargeStage(newCanvas(new Point(this.symbolWidth(), this.size)), aColor); - } else { + } else if (this.name == 'zoomToFit') { + return this.drawSymbolZoomToFit(newCanvas(new Point(this.symbolWidth(), this.size)), aColor); + } else { return this.originalSymbolCanvasColored(aColor) } } @@ -44,6 +47,51 @@ SymbolMorph.prototype.drawSymbolFullScreen = function (canvas, color) { return canvas; }; +SymbolMorph.prototype.drawSymbolZoomToFit = function (canvas, color) { + // answer a canvas showing two arrows pointing diagonally outwards + var ctx = canvas.getContext('2d'), + h = canvas.height, + c = canvas.width / 2, + off = canvas.width / 10, + w = canvas.width / 4; + + ctx.strokeStyle = color.toString(); + ctx.lineWidth = 1.5; + + + ctx.moveTo(0, 0); + ctx.lineTo(w, 0); + ctx.stroke(); + ctx.moveTo(0, 0); + ctx.lineTo(0, w); + ctx.stroke(); + + ctx.moveTo(0, h); + ctx.lineTo(0, h - w); + ctx.stroke(); + ctx.moveTo(0, h); + ctx.lineTo(w, h); + ctx.stroke(); + + ctx.moveTo(h, 0); + ctx.lineTo(h - w, 0); + ctx.stroke(); + ctx.moveTo(h, 0); + ctx.lineTo(h, w); + ctx.stroke(); + + ctx.moveTo(h, h); + ctx.lineTo(h - w, h); + ctx.stroke(); + ctx.moveTo(h, h); + ctx.lineTo(h, h - w); + ctx.stroke(); + + return canvas; +}; + + + SymbolMorph.prototype.drawSymbolFile= function (canvas, color) { // answer a canvas showing a page symbol var ctx = canvas.getContext('2d'), diff --git a/stitchcode/gui.js b/stitchcode/gui.js index 7a443e10..0f6502a2 100644 --- a/stitchcode/gui.js +++ b/stitchcode/gui.js @@ -208,6 +208,7 @@ IDE_Morph.prototype.createControlBar = function () { settingsButton, steppingButton, stageSizeButton, + zoomToFitButton, //largeStageSizeButton, appModeButton, cloudButton, @@ -278,7 +279,7 @@ IDE_Morph.prototype.createControlBar = function () { return myself.isAppMode; } ); - + button.corner = 12; button.color = colors[0]; button.highlightColor = colors[1]; @@ -297,6 +298,39 @@ IDE_Morph.prototype.createControlBar = function () { this.controlBar.add(appModeButton); this.controlBar.appModeButton = appModeButton; // for refreshing + + + // zoomToFitButton + //appModeButton + + button = new ToggleButtonMorph( + null, //colors, + this, // the IDE is the target + 'zoomToFit', new SymbolMorph('zoomToFit', 14), + function () { // query + return false; + } + ); + + 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 = 'start green\nflag scripts'; + button.fixLayout(); + button.refresh(); + zoomToFitButton = button; + this.controlBar.add(zoomToFitButton); + this.controlBar.zoomToFitButton = zoomToFitButton; // for refreshing + + //steppingButton button = new ToggleButtonMorph( null, //colors, @@ -501,7 +535,7 @@ IDE_Morph.prototype.createControlBar = function () { myself.right() - StageMorph.prototype.dimensions.x * (myself.isSmallStage ? myself.stageRatio : 1) ); - [stageSizeButton, appModeButton].forEach( + [stageSizeButton, appModeButton, zoomToFitButton].forEach( function (button) { x += padding; button.setCenter(myself.controlBar.center()); @@ -586,9 +620,6 @@ IDE_Morph.prototype.createControlBar = function () { }; }; - - - IDE_Morph.prototype.toggleAppMode = function (appMode) { var world = this.world(), elements = [ @@ -646,6 +677,11 @@ IDE_Morph.prototype.toggleAppMode = function (appMode) { this.setExtent(this.world().extent()); // resume trackChanges }; +IDE_Morph.prototype.zoomToFit = function (appMode) { + this.stage.camera.fitScene(); +} + + IDE_Morph.prototype.aboutTurtleStitch = function () { var dlg, aboutTxt, pic, world = this.world(); diff --git a/stitchcode/objects.js b/stitchcode/objects.js index fb20073c..9ebbe471 100644 --- a/stitchcode/objects.js +++ b/stitchcode/objects.js @@ -1124,23 +1124,26 @@ StageMorph.prototype.initCamera = function () { }; myself.camera.fitScene = function () { + var boundingBox = new THREE.Box3().setFromObject(myself.myStitchLines), boundingSphere = boundingBox.getBoundingSphere(), center = boundingSphere.center, distance = boundingSphere.radius; - var width = Math.max(myself.width(), 480), + if(distance > 0) { + var width = Math.max(myself.width(), 480), height = Math.max(myself.height(), 360); - - this.zoomFactor = Math.max(width / distance, height / distance); - this.applyZoom(); - - this.position.set(center.x, center.y, 10); - myself.controls.center.set(center.x, center.y, 10); - - myself.controls.update(); - myself.reRender(); + + this.zoomFactor = Math.max(width / distance, height / distance) * 0.95; + this.applyZoom(); + + this.position.set(center.x, center.y, 10); + myself.controls.center.set(center.x, center.y, 10); + + myself.controls.update(); + myself.reRender(); + } }; }; @@ -1415,6 +1418,8 @@ SpriteMorph.prototype.initBlocks = function () { var myself = this; this.originalInitBlocks(); + // sprite movements + this.blocks.resetAll = { only: SpriteMorph, @@ -1473,6 +1478,7 @@ SpriteMorph.prototype.initBlocks = function () { }; // pen blocks + this.blocks.isPenDown = { only: SpriteMorph, @@ -1480,8 +1486,7 @@ SpriteMorph.prototype.initBlocks = function () { category: 'pen', spec: 'pen down?', }; - - // pen blocks + this.blocks.getPenSize = { only: SpriteMorph, @@ -1489,7 +1494,9 @@ SpriteMorph.prototype.initBlocks = function () { category: 'pen', spec: 'pen size', }; - + + // pen color blocks + this.blocks.setColorRGB = { only: SpriteMorph, @@ -1599,6 +1606,15 @@ SpriteMorph.prototype.initBlocks = function () { category: 'pen' }; + // more blocks + + this.blocks.zoomToFit = + { + type: 'command', + spec: 'zoom to fit', + category: 'sensing' + }; + }; SpriteMorph.prototype.initBlocks(); @@ -1934,6 +1950,8 @@ SpriteMorph.prototype.blockTemplates = function (category) { blocks.push(block('doSetFastTracking')); blocks.push('-'); blocks.push(block('reportDate')); + blocks.push('-'); + blocks.push(block('zoomToFit')); // for debugging: /////////////// diff --git a/stitchcode/threads.js b/stitchcode/threads.js index 13781585..a67b12ed 100644 --- a/stitchcode/threads.js +++ b/stitchcode/threads.js @@ -27,3 +27,10 @@ Process.prototype.reportMouseY = function () { } return 0; }; + +Process.prototype.zoomToFit = function() { + stage = this.homeContext.receiver.parentThatIsA(StageMorph); + if (stage) { + stage.camera.fitScene(); + } +}